Java 9 Modularity (WARNING: An illegal reflective access)

You are here probably because you're wondering what do the following warnings logged by rnode mean.

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.google.protobuf.UnsafeUtil (file:/usr/share/rnode/lib/com.google.protobuf.protobuf-java-3.5.1.jar) to field java.nio.Buffer.address
WARNING: Please consider reporting this to the maintainers of com.google.protobuf.UnsafeUtil
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

Java 9 introduced modularity — aka Project Jigsaw — for stronger encapsulation (hiding of library internals and exposing only intended APIs). The goal is to make library authors not worry about potential impact of internal refactorings on users of internal APIs. This project makes it way more harder to depend on library internals. It also makes library organization somewhat elegant. For instance, transitive dependencies are not seen by dependency siblings.

Sadly, the mechanism hasn't gained much traction yet, and most of the libraries that depend on Java's JDK internal APIs, in most cases on sun.misc.Unsafe class for performance reasons, haven't migrated to new APIs (if there are any). So far JVM just issues warnings on accesses to non-exported APIs one of which you see above. In case of RChain, most, if not all, of these accesses occur in 3rd party libraries, which makes it really hard to properly eliminate these warnings. It would mean to record every such illegal access warning, check if the library that caused it has a new version that fixed it, and if not, fix the library or at least submit a bug report.

There's no straightforward way to silence these warnings. The JVM command line parameter that controls it is --illegal-access=<policy> (see https://docs.oracle.com/en/java/javase/11/tools/java.html), it is set to permit by default — warning on first illegal access only per module (library JAR in our case) — and that is the most liberal option. We can use --add-opens though. It can entirely open one module — export all its classes —  to another. The illegal accesses here CORE-1438 - Getting issue details... STATUS are to internal JDK APIs so we can just open JDK modules.

Applications running on JVM >= 9 run either on class path or module path. Running on class path is like running an application in any JVM < 9 — i.e. bunch of JARs on class path with main class in one (or more) of them — except additional access checks on library JARs that are also modules, which are just console warnings so far. Library JARs that aren't modules yet are turned unnamed modules which basically means that they can't be referenced individually in module linkage. When running on module path, library JARs that aren't modules are turned into automatic modules and it's possible to reference them individually, so you can for example open any module to a single automatic module. See links below for details.

RNode, and as of now probably 99% of all Java applications, runs on class path. Turning RNode into module would require effort I cannot estimate, but it certainly wouldn't bring any fruits at this moments. We can just silence warnings by opening required modules and packages. This effort is tracked in aforementioned ticket.

For details see

Information about transitioning from class path to module path: