IllegalAccessError even when -XaddExports adds ALL-UNNAMED to the reported module/package
jonathan.gibbons at oracle.com
Fri Dec 4 01:48:20 UTC 2015
To understand the problem, you need to understand something of how javac
javac is a Java program, and as such it is composed of a set of modules
that run in a JVM. The primary module is jdk.compiler, and if you follow
the dependencies, you'll see it references java.compiler, and of course
java.base. Call that the "execution environment".
Now, the function of javac is to analyze and compile source code, which
exists in a conceptually separate collection of modules. It will
typically be uncommon for the compiled code to depend on javac's
modules, like jdk.compiler and java.compiler, and will likely depend on
its own modules, specified on the module path provided to javac. All
modules depend on java.base, but there is no requirement or assumption
that the version of the java.base module being referenced by the code
being compiled is the same version of java.base being used by javac code
itself. Wind the clock forward a few years, and imagine running javac
on JDK 10, compiling code to run on JDK 9. Just as on JDK 8, we
recommend setting the bootclasspath when compiling code for earlier
versions of JDK, in future, we will recommend that you specify the set
of system modules appropriate to your setting of -target. All of which
is to say that the set of modules used by javac to analyze and compile
your program is conceptually distinct from the set of modules being used
to execute javac itself. Call this new set of modules the "compilation
Now consider javac options like -modulepath, -modulesource path and so
on. These affect the compilation environment. So too does the javac
-XaddExports option. When you specify -modulepath to javac, you are
making additional modules available for use by the code being compiled.
When you specify -XaddExports to javac, you are instructing javac to
make some specific packages visible to code in other modules that would
not otherwise be able to do so. Neither of these options affect the
configuration of modules in the JVM being used to execute javac itself.
The same is true for all other module-related options for javac.
Now consider an annotation processor. Annotation processors are like
plugins or extensions to javac. As such, they run in the same JVM as
javac, and more specifically, in the same execution environment as
javac. (Not 100% true, but close enough for now.) So, using "javac
-XaddExports" will not have any direct effect on an annotation
processor, because javac -XaddExports affects the compilation
environment available to the annotation processor, not the execution
environment in which it will be running.
So how do you affect the execution environment used to execute javac and
any annotation processors that you specify?
You need to pass -XaddExports not to javac but to the underlying
runtime. The standard practice for all JDK tools invoked from the
command line is (and has long been) that options prefixed with -J are
passed to the underlying runtime. And so, in this case, if you are
running javac from the command line, you need a command like
$ javac -J-XaddExports:jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED -cp lombok.jar Test.java
Here's a different way of looking at it. javac is "just" a Java
program, and so running "javac args" is equivalent to executing the
$ java ...some.options... com.sun.tools.javac.Main args
So when you specify "javac -XaddExports" the effective command is
$ java ...some.options... com.sun.tools.javac.Main -XaddExports... args
But if you want to affect javac's execution environment, the command you
really want is
$ java ...some.options... -XaddExports... com.sun.tools.javac.Main args
i.e. you want -XaddExports passed to the java command, not to the javac
command. That is what "javac -J-XaddExports..." does.
On 12/03/2015 03:26 PM, Roel Spilker wrote:
> I have a problem using -XaddExports in jigsaw build 94. This is the first
> build I tried so I don't know if the problem also occurs in earlier
> In Lombok we use unsupported internal APIs (yes at our own risk)
> After reading the instructions on http://openjdk.java.net/jeps/261
> "Breaking encapsulation" I've added the -XaddExports flag. The exception I
> got luckily gave me the module name as well as the package to export.
> However I still got the same exception (details below).
> Am I doing something wrong (apart from using unsupported internal APIs)? Is
> the exception wrong?
> $ java -version
> java version "1.9.0-ea"
> Java(TM) SE Runtime Environment (build
> Java HotSpot(TM) 64-Bit Server VM (build
> 1.9.0-ea-jigsaw-nightly-h403-20151201-b94, mixed mode)
> $ javac
> -XaddExports:jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED -cp
> lombok.jar Test.java
> An annotation processor threw an uncaught exception.
> Consult the following stack trace for details.
> java.lang.IllegalAccessError: class lombok.javac.apt.LombokProcessor (in
> module: Unnamed Module) cannot access class
> com.sun.tools.javac.processing.JavacProcessingEnvironment (in module:
> jdk.compiler), com.sun.tools.javac.processing is not exported to Unnamed
> at lombok.javac.apt.LombokProcessor.init(LombokProcessor.java:84)
> com.sun.tools.javac.processing.JavacProcessingEnvironment$ProcessorState.<init>(jdk.compiler at 9.0
> com.sun.tools.javac.processing.JavacProcessingEnvironment$DiscoveredProcessors$ProcessorStateIterator.next(jdk.compiler at 9.0
> com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(jdk.compiler at 9.0
> com.sun.tools.javac.processing.JavacProcessingEnvironment.access$2100(jdk.compiler at 9.0
> com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(jdk.compiler at 9.0
> com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(jdk.compiler at 9.0
> com.sun.tools.javac.main.JavaCompiler.processAnnotations(jdk.compiler at 9.0
> at com.sun.tools.javac.main.JavaCompiler.compile(jdk.compiler at 9.0
> at com.sun.tools.javac.main.Main.compile(jdk.compiler at 9.0
> at com.sun.tools.javac.main.Main.compile(jdk.compiler at 9.0
> at com.sun.tools.javac.Main.compile(jdk.compiler at 9.0/Main.java:56)
> at com.sun.tools.javac.Main.main(jdk.compiler at 9.0/Main.java:42)
More information about the jigsaw-dev