spring-data-mongodb
spring-data-mongodb copied to clipboard
Java 17 InaccessibleObjectException when using java.time.Instant
I used the Instant in my model and got this error:
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make private java.time.Instant(long,int) accessible: module java.base does not "opens java.time" to unnamed module @32cf48b7
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
at java.base/java.lang.reflect.Constructor.checkCanSetAccessible(Constructor.java:188)
at java.base/java.lang.reflect.Constructor.setAccessible(Constructor.java:181)
at org.springframework.util.ReflectionUtils.makeAccessible(ReflectionUtils.java:201)
at org.springframework.data.mapping.PreferredConstructor.<init>(PreferredConstructor.java:53)
at org.springframework.data.mapping.model.PreferredConstructorDiscoverer$Discoverers.buildPreferredConstructor(PreferredConstructorDiscoverer.java:250)
at org.springframework.data.mapping.model.PreferredConstructorDiscoverer$Discoverers$1.discover(PreferredConstructorDiscoverer.java:137)
at org.springframework.data.mapping.model.PreferredConstructorDiscoverer.discover(PreferredConstructorDiscoverer.java:82)
at org.springframework.data.mapping.model.InstanceCreatorMetadataDiscoverer.discover(InstanceCreatorMetadataDiscoverer.java:81)
at org.springframework.data.mapping.model.BasicPersistentEntity.<init>(BasicPersistentEntity.java:113)
at org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity.<init>(BasicMongoPersistentEntity.java:84)
at org.springframework.data.mongodb.core.mapping.MongoMappingContext.createPersistentEntity(MongoMappingContext.java:88)
at org.springframework.data.mongodb.core.mapping.MongoMappingContext.createPersistentEntity(MongoMappingContext.java:41)
at org.springframework.data.mapping.context.AbstractMappingContext.doAddPersistentEntity(AbstractMappingContext.java:403)
at org.springframework.data.mapping.context.AbstractMappingContext.addPersistentEntity(AbstractMappingContext.java:379)
at org.springframework.data.mapping.context.AbstractMappingContext$PersistentPropertyCreator.lambda$createAndRegisterProperty$3(AbstractMappingContext.java:591)
at java.base/java.lang.Iterable.forEach(Iterable.java:75)
at org.springframework.data.mapping.context.AbstractMappingContext$PersistentPropertyCreator.createAndRegisterProperty(AbstractMappingContext.java:588)
at org.springframework.data.mapping.context.AbstractMappingContext$PersistentPropertyCreator.doWith(AbstractMappingContext.java:542)
at org.springframework.util.ReflectionUtils.doWithFields(ReflectionUtils.java:711)
at org.springframework.data.mapping.context.AbstractMappingContext.doAddPersistentEntity(AbstractMappingContext.java:422)
at org.springframework.data.mapping.context.AbstractMappingContext.addPersistentEntity(AbstractMappingContext.java:379)
at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:280)
at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:206)
at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:92)
at org.springframework.data.mapping.context.MappingContext.getRequiredPersistentEntity(MappingContext.java:74)
at org.springframework.data.mongodb.repository.support.MongoRepositoryFactory.getEntityInformation(MongoRepositoryFactory.java:146)
at org.springframework.data.mongodb.repository.support.MongoRepositoryFactory.getEntityInformation(MongoRepositoryFactory.java:140)
at org.springframework.data.mongodb.repository.support.MongoRepositoryFactory.getRepositoryFragments(MongoRepositoryFactory.java:119)
at org.springframework.data.mongodb.repository.support.MongoRepositoryFactory.getRepositoryFragments(MongoRepositoryFactory.java:92)
at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepositoryComposition(RepositoryFactorySupport.java:428)
at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:293)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet$5(RepositoryFactoryBeanSupport.java:279)
at org.springframework.data.util.Lazy.getNullable(Lazy.java:229)
at org.springframework.data.util.Lazy.get(Lazy.java:113)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:285)
at org.springframework.data.mongodb.repository.support.MongoRepositoryFactoryBean.afterPropertiesSet(MongoRepositoryFactoryBean.java:101)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1799)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1749)
... 79 more
I'm using the spring-data-mongodb version 4.0.0-M6.
This is caused by JEP 396, Java 17 has more restrictive approach regarding modules. As a workaround you have to pass --add-opens=java.base/java.time=ALL-UNNAMED with specified module and package in JVM args but it may break again once Java 18 rolls out.
To be more precise, it's due to the fact that SpringData use the Spring Commons converter mechanism as a principal way to read data from mongodb, and the converter use Constructor (and try to make private one accessible) as a main way to initialize the data. And doing so with java.time class throw this exception. One solution could be to interconnect more tightly Spring Data reading part and mongoDb connect.
I'm confused by this two line of codes:
https://github.com/spring-projects/spring-data-mongodb/blob/240e53794c8868c204f4154ab0dbbd2070753cab/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoSimpleTypes.java#L76
https://github.com/spring-projects/spring-data-mongodb/blob/240e53794c8868c204f4154ab0dbbd2070753cab/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoSimpleTypes.java#L126-L128
Seems like Instant is considered as a simple type, but in that isSimpleType it excludes the java.time package.
But Spring Data Commons' behavior is different
https://github.com/spring-projects/spring-data-commons/blob/ac2f8ded22b3708c14d34958627e3c36a3df9e28/src/main/java/org/springframework/data/mapping/model/SimpleTypeHolder.java#L141-L175
The error can occur when using a not fully intialized mapping context. Please help us analyze the issue and provide a complete minimal sample (something that we can unzip or git clone, build, and deploy) that reproduces the problem.
If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.
Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.