-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Description
Search before asking
- I searched in the issues and found nothing similar.
Describe the bug
Please consider the following trivial Java code:
package org.myapp;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.OptionalInt;
public class Main {
public static void main(final String[] args) throws Exception {
final ObjectMapper objectMapper = new ObjectMapper();
final String json = "{ }"; // empty
final Data data = objectMapper.readValue(json, Data.class);
System.out.println("Read data: " + data);
}
public static class Data {
private OptionalInt value;
public Data() {
}
public void setValue(OptionalInt i) {
this.value = i;
}
public OptionalInt getValue() {
return this.value;
}
@Override
public String toString() {
return "Data[value=" + this.value + "]";
}
}
}
When using jackson-databind
2.15.2
and Java version 17 and running this program, it results in:
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make private java.util.OptionalInt() accessible: module java.base does not "opens java.util" to unnamed module @4cf328c3
at java.lang.reflect.AccessibleObject.throwInaccessibleObjectException (AccessibleObject.java:387)
at java.lang.reflect.AccessibleObject.checkCanSetAccessible (AccessibleObject.java:363)
at java.lang.reflect.AccessibleObject.checkCanSetAccessible (AccessibleObject.java:311)
at java.lang.reflect.Constructor.checkCanSetAccessible (Constructor.java:192)
at java.lang.reflect.Constructor.setAccessible (Constructor.java:185)
at com.fasterxml.jackson.databind.util.ClassUtil.checkAndFixAccess (ClassUtil.java:995)
at com.fasterxml.jackson.databind.deser.impl.CreatorCollector._fixAccess (CreatorCollector.java:278)
at com.fasterxml.jackson.databind.deser.impl.CreatorCollector.setDefaultCreator (CreatorCollector.java:130)
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory._addExplicitConstructorCreators (BasicDeserializerFactory.java:438)
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory._constructDefaultValueInstantiator (BasicDeserializerFactory.java:293)
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.findValueInstantiator (BasicDeserializerFactory.java:222)
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.buildBeanDeserializer (BeanDeserializerFactory.java:262)
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.createBeanDeserializer (BeanDeserializerFactory.java:151)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2 (DeserializerCache.java:415)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer (DeserializerCache.java:350)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2 (DeserializerCache.java:264)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer (DeserializerCache.java:244)
at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer (DeserializerCache.java:142)
at com.fasterxml.jackson.databind.DeserializationContext.findNonContextualValueDeserializer (DeserializationContext.java:644)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.resolve (BeanDeserializerBase.java:539)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2 (DeserializerCache.java:294)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer (DeserializerCache.java:244)
at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer (DeserializerCache.java:142)
at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer (DeserializationContext.java:654)
at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer (ObjectMapper.java:4956)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose (ObjectMapper.java:4826)
at com.fasterxml.jackson.databind.ObjectMapper.readValue (ObjectMapper.java:3772)
at com.fasterxml.jackson.databind.ObjectMapper.readValue (ObjectMapper.java:3740)
at org.myapp.Main.main (Main.java:10)
So com.fasterxml.jackson.databind.util.ClassUtil
is trying to setAccessible()
on the private constructor of a JDK class java.util.OptionalInt
. One way to solve this issue is to configure the ObjectMapper
instance as follows:
objectMapper.configure(MapperFeature.CAN_OVERRIDE_ACCESS_MODIFIERS, false);
However, while looking at the code in com.fasterxml.jackson.databind.util.ClassUtil
I noticed that there's a specific logic which tries to not setAccessible()
on JDK internal classes here https://github.com/FasterXML/jackson-databind/blob/jackson-databind-2.15.2/src/main/java/com/fasterxml/jackson/databind/util/ClassUtil.java#L994 which looks like:
if (!isPublic || (evenIfAlreadyPublic && !isJDKClass(declaringClass))) {
ao.setAccessible(true);
}
Should that !isJDKClass(declaringClass)
be perhaps applied even when evenIfAlreadyPublic
is false? Something like:
if (!isJDKClass(declaringClass) && (!isPublic || evenIfAlreadyPublic)) {
ao.setAccessible(true);
}
That way, it won't try to access the internal JDK classes and run into these exceptions on Java 17+?
Version Information
2.15.2
Reproduction
No response
Expected behavior
No response
Additional context
No response