Skip to content

JDK 12+ illegal reflective access operation for Throwable, setCause() #2464

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
cowtowncoder opened this issue Sep 19, 2019 · 13 comments
Closed

Comments

@cowtowncoder
Copy link
Member

(from mailing list)

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.fasterxml.jackson.databind.util.ClassUtil (...) to method java.lang.Throwable.setCause(java.lang.Throwable)
WARNING: Please consider reporting this to the maintainers of com.fasterxml.jackson.databind.util.ClassUtil
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

This is probably due to deserializer constructed in BeanDeserializerFactory.buildThrowableDeserializer() -- ThrowableDeserializer will handle "cause" property by generating a property. It should use initCause(), but perhaps there is non-public setCause() accidentally found...

@cowtowncoder cowtowncoder changed the title JDK 11+ illegal reflective access operation for Throwable, setCause() JDK 12+ illegal reflective access operation for Throwable, setCause() Sep 19, 2019
@cowtowncoder
Copy link
Member Author

Ah ha! So JDK 12 added setCause() in Throwable... and that is what should be blocked. It would not occur on JDK 11 as there was no such setter. So that explains why there was no earlier report for LTS version.

Now the question is just how to block attempt(s), if there's a clean way etc.

@GedMarc
Copy link

GedMarc commented Sep 20, 2019

Hmmm, I've got 2.10pr2 in production in module-mode on jdk 12 (databind,anno,jaxb,guice) - built JRE

I have not seen this at all xD !!!

@cowtowncoder
Copy link
Member Author

Not even in unit tests? Hmmh. Interesting.

@cowtowncoder
Copy link
Member Author

Ok. Will put on hold, need some sort of reproduction. I do not see warnings from mvn test with JDK 12; not that that was high bar. But need something to also verify fix, if any was added: I'm sure it's possible to avoid triggering setCause().

@bh3605
Copy link

bh3605 commented Oct 3, 2019

Inherited a 5 year old project that was built in 1.8. Going through the process of upgrading everything. At this point it's just the tests that fail when mvn install is ran.

Using JDK 13. I'm receiving the same error as well, but related to a creation of an OffsetDateTime instance. Tried versions 2.10.0 and 2.10.0.pr3.

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.fasterxml.jackson.databind.util.ClassUtil (file:/C:/Users/hairb3/.m2/repository/com/fasterxml/jackson/core/jackson-databind/2.10.0.pr3/jackson-databind-2.10.0.pr3.jar) to field java.time.OffsetDateTime.offset
WARNING: Please consider reporting this to the maintainers of com.fasterxml.jackson.databind.util.ClassUtil
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `java.time.OffsetDateTime` (no Creators, like default construct, exist): no String-argument constructor/factory method to deserialize from String value ('2015-11-18T12:17:00+00:00')
at [Source: (File); line: 3, column: 15] (through reference chain: com.usquared.icecream.xapi.model.Statement["timestamp"])
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67)
at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1589)
at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1055)
at com.fasterxml.jackson.databind.deser.ValueInstantiator._createFromStringFallbacks(ValueInstantiator.java:371)
at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.createFromString(StdValueInstantiator.java:323)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromString(BeanDeserializerBase.java:1373)
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:171)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:161)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:288)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4202)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3070)

pom.xml (or at least what's relevant)

<properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  <java.version>13</java.version>
  <jackson.version>2.10.0.pr3</jackson.version>
</properties>

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>${jackson.version}</version><!--$NO-MVN-MAN-VER$-->
<exclusions>
    <exclusion>
           <groupId>com.fasterxml.jackson.core</groupId>
           <artifactId>jackson-core</artifactId>
       </exclusion>
       <exclusion>
           <groupId>com.fasterxml.jackson.core</groupId>
           <artifactId>jackson-annotations</artifactId>
       </exclusion>
   </exclusions>
</dependency>

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>${jackson.version}</version><!--$NO-MVN-MAN-VER$-->
</dependency>

<dependency>
	<groupId>com.fasterxml.jackson.core</groupId>
	<artifactId>jackson-annotations</artifactId>
	<version>${jackson.version}</version><!--$NO-MVN-MAN-VER$-->
</dependency>

Since this involves JDK 13 you would rather have this as a separate issue?

@GedMarc
Copy link

GedMarc commented Oct 3, 2019

Java.time is in the physical JDK, you will need to add the add-opens clause to your surefire args and startup command lines.

No error.

@cowtowncoder
Copy link
Member Author

I think this may actually be slightly different problem: not registering Java 8 date-time module -- in which case "new" Java date/time types were handled as POJOs. And this would trigger the warning.

While it would be good to figure out some more graceful way to handle things, I agree with @GedMarc that this is probably not a specific issue to tackle (that is, not for this particular type).

But ... maybe it'd make sense to not try force access to Fields, Methods declared in java. package. Checking that may be bit costly, but could possible be checked just once for AnnotatedClass or something.

@cowtowncoder
Copy link
Member Author

Ok. So, have been playing with introspection quite a bit lately, trying to optimize for certain things.
I think that many of the warnings could actually be avoided, but I would need reproduction to see.
The reason why access is often not really needed is that (de)serializers for known JDK types, 3rd party libraries use explicit API: it is only Bean-style automatic access that needs it.
So often what remains is "accidental" support, which uses Bean style access even if that is not necessarily the right way.

Anyway. Will close this for now, will re-file when this or something similar resurfaces.

@bh3605
Copy link

bh3605 commented Oct 16, 2019

Sounds good! I was trying to update this app from 1.8 to 13 and eventually settled on just keeping the thing in 1.8 until actually needed. No errors in 1.8

@jxtps
Copy link

jxtps commented Aug 10, 2020

I have an app developed & built with Java 8, but deployed on Java 14 and get this error message when it starts. It appears very repeatable (= has happened every single time that I've looked at the log).

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.fasterxml.jackson.databind.util.ClassUtil (file:/.../com.fasterxml.jackson.core.jackson-databind-2.10.4.jar) to method java.lang.Throwable.setCause(java.lang.Throwable)
WARNING: Please consider reporting this to the maintainers of com.fasterxml.jackson.databind.util.ClassUtil
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

Jackson is getting pulled in from the Play Framework, but I can presumably override the version used (happening in 2.10.4 judging from the error message above).

Would be happy to test out any version that's accessible via maven to help get this issue sorted.

@cowtowncoder
Copy link
Member Author

@jxtps Unfortunately this message by JDK is pretty useless as it does not give an idea of value type(s) that trigger this. What typically happens is that something included in JDK is not recognized as something explicitly supported and ends up using general-purpose Bean introspection. To work around this, a specific (de)serializer should be added (or type itself ignored). But to do that, type needs to be known.

There are some other things that could be considered, such as maybe adding blocks to prevent all "java.*" types from ever being handled as POJOs; this might help.

As to why 2.10.x gives this: it is just because earlier versions do not contain Java 9 module info declarations so JDK will probably treat code in a way as to suppress warnings.
So it is probably not anything newer versions do but with how JDK/JVM treat it based on metadata available.

@edudar
Copy link
Contributor

edudar commented Jun 8, 2021

In my case, this happens with amazon was sdk v1 and databind 2.12.3. Results in runtime exception on Java 16 though, not just warning printout. They try to create an exception from the JSON response like {"__type":"ExpiredTokenException","message":"The security token included in the request is expired"} that causes

java.lang.reflect.InaccessibleObjectException: Unable to make final void java.lang.Throwable.setCause(java.lang.Throwable) accessible: module java.base does not "opens java.lang" to unnamed module @43738a82

@cowtowncoder
Copy link
Member Author

@edudar As usual it'd be necessary to get a reproduction of this: description along is unfortunately not enough. If you can create one, it'd be good to file a separate issue: these typically need to be handled on case-by-case basis as the fundamentally it is not possible to have an overall solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants