[java] what is an illegal reflective access

There are a lot of questions about illegal reflective access in Java 9.

I have found plenty of discussion about working around the error messages, but I would love to know what an illegal reflective access actually is.

So my question is:

What defines an illegal reflective access and what circumstances trigger the warning?

I have gathered that it has something to do with the encapsulation principles that were introduced in Java 9, but I can't find an explanation of how it all hangs together, what triggers the warning, and in what scenario.

This question is related to java java-9 java-module java-platform-module-system

The answer is


If you want to go with the add-open option, here's a command to find which module provides which package ->

java --list-modules | tr @ " " | awk '{ print $1 }' | xargs -n1 java -d

the name of the module will be shown with the @ while the name of the packages without it

NOTE: tested with JDK 11

IMPORTANT: obviously is better than the provider of the package does not do the illegal access


Just look at setAccessible() method used to access private fields and methods:

https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/AccessibleObject.html#setAccessible-boolean-

https://docs.oracle.com/javase/9/docs/api/java/lang/reflect/AccessibleObject.html#setAccessible-boolean-

Now there is a lot more conditions required for this method to work. The only reason it doesn't break almost all of older software is that modules autogenerated from plain JARs are very permissive (open and export everything for everyone).


There is an Oracle article I found regarding Java 9 module system

By default, a type in a module is not accessible to other modules unless it’s a public type and you export its package. You expose only the packages you want to expose. With Java 9, this also applies to reflection.

As pointed out in https://stackoverflow.com/a/50251958/134894, the differences between the AccessibleObject#setAccessible for JDK8 and JDK9 are instructive. Specifically, JDK9 added

This method may be used by a caller in class C to enable access to a member of declaring class D if any of the following hold:

  • C and D are in the same module.
  • The member is public and D is public in a package that the module containing D exports to at least the module containing C.
  • The member is protected static, D is public in a package that the module containing D exports to at least the module containing C, and C is a subclass of D.
  • D is in a package that the module containing D opens to at least the module containing C. All packages in unnamed and open modules are open to all modules and so this method always succeeds when D is in an unnamed or open module.

which highlights the significance of modules and their exports (in Java 9)