I'm trying to make a method, which uses the Json data with jackson library to have a list of objects. If I run my code, I get the error:
java.lang.reflect.InaccessibleObjectException: Unable to make field private final int java.time.LocalDate.year accessible: module java.base does not "opens java.time" to unnamed module @5c90e579
Why is it giving me an error about LocalDate even though I have JodaModul in my Code?
public static List<Tweet> getTweetsFile() throws Exception{ ObjectMapper mapper = new ObjectMapper(). registerModule(new JodaModule()). configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); File path = new File ("C:/Users/PC/eclipse-workspace/hw4/tw.json"); List<Tweet> myObjects3 = Arrays.asList(mapper.readValue(path, Tweet.class)); return myObjects3; } How it looks in my File:
[{"date":"2001-12-28","tweetNumber":1,"country":"England","comments":11,"message":"I like to watch anime and reading books","retweets":3,"username":"Isabelle","likes":55},{"date":"2003-05-11","tweetNumber":2,"country":"France","comments":25,"message":"I'm Viatnamese, but I live in France","retweets":30,"username":"Vin","likes":110}.. It's not in the right order like my Object has in their constructor, could that be the reaseon?
39 Answers
You can fix this issue on your own.
add --add-opens as start-argument and it'll work.
Here is the corresponding JEP
1I used this way and fixed this Problem. Firstly you have to create LocalDateTime Deserializer with the given Date Format in your Json Data.
class LocalDateTimeDeserializer implements JsonDeserializer < LocalDateTime > { @Override public LocalDateTime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { return LocalDateTime.parse(json.getAsString(), DateTimeFormatter.ofPattern("d::MMM::uuuu HH::mm::ss").withLocale(Locale.ENGLISH)); } }
Then create Object of Type GsonBuilder and adapt it with your LocalDateDeserializer.
gsonBuilder.registerTypeAdapter(LocalDateTime.class, new LocalDateTimeDeserializer()); Gson gson = gsonBuilder.setPrettyPrinting().create(); 1In STS or eclipse add the folowing statement in default VM arguments
--add-opens
Default VM arguments path: Window -> Preferences -> Installed JREs -> select jre -> edit
1I got this exception with JDK 17 and Gson:
Unable to make field private final java.time.LocalDate java.time.LocalDateTime.date accessible: module java.base does not "opens java.time" so I used this custom TypeAdapter with null checks:
public class LocalDateTimeTypeAdapter extends TypeAdapter<LocalDateTime> { @Override public void write(final JsonWriter jsonWriter, final LocalDateTime localDate) throws IOException { if (localDate == null) { jsonWriter.nullValue(); return; } jsonWriter.value(localDate.toString()); } @Override public LocalDateTime read(final JsonReader jsonReader) throws IOException { if (jsonReader.peek() == JsonToken.NULL) { jsonReader.nextNull(); return null; } return ZonedDateTime.parse(jsonReader.nextString()).toLocalDateTime(); } } 4From my reading of this issue, the problems that required you to do the "--add-opens" hack or other work-arounds should be fixed in current Jackson releases.
So, if you are still finding you need to do this:
- Make sure you are using a recent Jackson release1.
- If that doesn't help, raise a Jackson issue which sufficient specificity to allow the Jackson developers to figure out where this instance of the problem is occuring.
The "--add-opens" approach will work, but it is not a good solution. The good solution is to help the developers to fix the problem by reporting it.
1 - I can't give you a specific release because it is not clear from the issue tracker or release notes precisely when the problem(s) were fixed. But 2.14.0 or later seems like a good bet, based on the date of the issue closure.
2I got this error after upgrading the application to Java 17 and Spring Boot 3. Adding VM options will lead to other problems.
1.Fixed by adding the adapter.
public class LocalDateTypeAdapter implements JsonSerializer<LocalDate>, JsonDeserializer<LocalDate> { private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); @Override public JsonElement serialize(final LocalDate date, final Type typeOfSrc, final JsonSerializationContext context) { return new JsonPrimitive(date.format(formatter)); } @Override public LocalDate deserialize(final JsonElement json, final Type typeOfT, final JsonDeserializationContext context) throws JsonParseException { return LocalDate.parse(json.getAsString(), formatter); } } 2.Then register the adapter like this :-
@Configuration public class GsonConfiguration { @Bean public GsonBuilderCustomizer typeAdapterRegistration() { return builder -> { builder.registerTypeAdapter(LocalDate.class, new LocalDateTypeAdapter()); }; } } 1I encountered a similar issue when I was unit testing Twilio SMS.
I solved the issue by registering JavaTimeModule on the ObjectMapper.
String json = "{\"status\": \"sent\"}"; ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new JavaTimeModule()); var message = Message.fromJson(json, mapper); 2You can always use additional DTO object with already parsed LocalDate to String.
I solved this problem to change jdk16 to jdk11.
1