What does this error mean? java.lang.reflect.InaccessibleObjectException: Unable to make field private final int java.time.LocalDate.year
Asked Answered
S

10

30

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?

Stillhunt answered 19/12, 2021 at 15:31 Comment(3)
Do you use the latest version of jackson?Asexual
In Project > Properties: Java Build Path tab Module Dependencies select the java.base module and click Expose Package... button. Enter as Package java.time, as Target module UNNAMED and select opens. Does this fix your issue? But probably the root cause is that you use a too old library that was written for an older Java version. So first check, if your used libraries are up to date.Dishtowel
I got it now, default constructor was missing and I had a mistake in it and yes I had to use JavaTime for it. ThanksStillhunt
P
34

You can fix this issue on your own.

add --add-opens java.base/java.time=ALL-UNNAMED as start-argument and it'll work.

Here is the corresponding JEP

Plagiarism answered 27/1, 2022 at 11:57 Comment(2)
if you are on Windows, use --add-opens=java.base/java.time=ALL-UNNAMED for JAVA_TOOL_OPTIONS environment variable.Marissamarist
Hi @makson. I have tried with the suggestion by both of you. But still getting same error java.lang.reflect.InaccessibleObjectException: Unable to make field private final java.time.LocalDateTime java.time.ZonedDateTime.dateTime accessible: module java.base does not "opens java.time" to unnamed module. I have tried the answer of creating Bean GsonBuilderCustomizer, but still no luck. Do anyone have any suggestion for me?Cologne
S
8

I 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();
Suannesuarez answered 17/9, 2022 at 5:7 Comment(1)
The question is about Jackson, so why Gson answer?Organization
N
6

In STS or eclipse add the folowing statement in default VM arguments

--add-opens java.base/java.time=ALL-UNNAMED

Default VM arguments path: Window -> Preferences -> Installed JREs -> select jre -> edit

Niphablepsia answered 5/1, 2023 at 8:22 Comment(1)
if you're testing or trying to initiate a project on your local machine, this is the best solution to fix this problem. thanks for the answer!Pierrette
K
4

I 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();
    }
}
Keeler answered 28/10, 2022 at 19:13 Comment(4)
Where do you use this adapterEquiponderate
Could you please add code maybe as an exampleEquiponderate
Example of registering the TypeAdapter: static final Gson GSON; static { GSON = new GsonBuilder() // .registerTypeAdapter(LocalDateTime.class, new LocalDateTimeDeserializer()) // .setFieldNamingPolicy(FieldNamingPolicy.IDENTITY) // .setDateFormat("YYYY-MM-dd") // .setPrettyPrinting() // .create(); }Umbel
Thanks, exactly my case, and it helped, but I didn't quite get the reason why it started happening to me. I upgraded to Java 17, and my JUnit test started failing with those error. There is an answer explaining this, it seems https://mcmap.net/q/500403/-failed-making-field-39-property-39-accessible-either-change-its-visibility-or-write-a-custom-typeadapter-for-its-declaring-type-gson-fromjson , also this gson ticket github.com/google/gson/issues/2485 , and the comments seem clear, however my class doesn't have any LocalDateTime fields, so not sure why I had to add this adapter.Promenade
H
3

I 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);
Homogamy answered 26/1, 2023 at 19:18 Comment(3)
Dude, your answer was right on the spot. It fixed the issue.Masked
incompatible types: com.fasterxml.jackson.datatype.jsr310.JavaTimeModul e cannot be converted to org.testcontainers.shaded.com.fasterxml.jackson.databind.ModuleGuadalquivir
This is the correct way to solve the issue. Other suggestions about opening java.base/java.time or writing a custom adapter should be ignored.Minard
D
2

From 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:

  1. Make sure you are using a recent Jackson release1.
  2. 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.

Drogin answered 13/11, 2022 at 23:43 Comment(2)
Thits a gson issue not jackson (?)Movie
This is a Jackson issue. The question is about Jackson and so is my answer.Drogin
K
2

I 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());
        };
    }
}
Kinzer answered 27/6, 2023 at 21:33 Comment(1)
The question is asking about Jackson, though, not Gson. Jackson is the preferred default in Spring Boot. docs.spring.io/spring-boot/docs/current/reference/html/…Organization
S
0

You can always use additional DTO object with already parsed LocalDate to String.

Surreptitious answered 7/7, 2023 at 7:36 Comment(0)
B
0

The problem appeared during the migration of Spring Boot 2 to Spring Boot 3 (3.2.2). I am using Java version 21.

In my case, the proper configuration of mongo objects helped. Try to configure beans in Spring Context as follows:

@Bean
@Primary
public MappingMongoConverter mongoMappingConverter(MongoDatabaseFactory dbFactory, MongoMappingContext mongoMappingContext) {
    // Make sure to register your custom converters here

    MappingMongoConverter mappingMongoConverter = new MappingMongoConverter(new DefaultDbRefResolver(dbFactory), mongoMappingContext);
    mongoMappingContext.setSimpleTypeHolder(mappingMongoConverter.getCustomConversions().getSimpleTypeHolder());
    mongoMappingContext.afterPropertiesSet();
    mappingMongoConverter.afterPropertiesSet();
    return mappingMongoConverter;
}


@Bean
public MongoMappingContext mongoMappingContext() {
    return new MongoMappingContext();
}
Beaubeauchamp answered 31/7 at 6:28 Comment(0)
D
-13

I solved this problem to change jdk16 to jdk11.

Derte answered 8/1, 2022 at 7:59 Comment(1)
You haven't solved it. You have just put off the problem so that it can come back and bite you when you move to Java 17 (or later).Drogin

© 2022 - 2024 — McMap. All rights reserved.