IllegalAccessError even when -XaddExports adds ALL-UNNAMED to the reported module/package

Jonathan Gibbons jonathan.gibbons at oracle.com
Fri Dec 4 01:48:20 UTC 2015


Roel,

To understand the problem, you need to understand something of how javac 
works.

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 
environment".

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 
following command:

$ 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.


-- Jon





On 12/03/2015 03:26 PM, Roel Spilker wrote:
> Hi,
>
> 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
> versions.
>
> 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?
>
> Roel
>
>
>
> $ java -version
> java version "1.9.0-ea"
> Java(TM) SE Runtime Environment (build
> 1.9.0-ea-jigsaw-nightly-h403-20151201-b94)
> 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
> Module
>          at lombok.javac.apt.LombokProcessor.init(LombokProcessor.java:84)
>          at
> lombok.core.AnnotationProcessor$JavacDescriptor.want(AnnotationProcessor.java:87)
>          at
> lombok.core.AnnotationProcessor.init(AnnotationProcessor.java:141)
>          at
> lombok.launch.AnnotationProcessorHider$AnnotationProcessor.init(AnnotationProcessor.java:53)
>          at
> com.sun.tools.javac.processing.JavacProcessingEnvironment$ProcessorState.<init>(jdk.compiler at 9.0
> /JavacProcessingEnvironment.java:669)
>          at
> com.sun.tools.javac.processing.JavacProcessingEnvironment$DiscoveredProcessors$ProcessorStateIterator.next(jdk.compiler at 9.0
> /JavacProcessingEnvironment.java:766)
>          at
> com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(jdk.compiler at 9.0
> /JavacProcessingEnvironment.java:857)
>          at
> com.sun.tools.javac.processing.JavacProcessingEnvironment.access$2100(jdk.compiler at 9.0
> /JavacProcessingEnvironment.java:104)
>          at
> com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(jdk.compiler at 9.0
> /JavacProcessingEnvironment.java:1183)
>          at
> com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(jdk.compiler at 9.0
> /JavacProcessingEnvironment.java:1291)
>          at
> com.sun.tools.javac.main.JavaCompiler.processAnnotations(jdk.compiler at 9.0
> /JavaCompiler.java:1247)
>          at com.sun.tools.javac.main.JavaCompiler.compile(jdk.compiler at 9.0
> /JavaCompiler.java:921)
>          at com.sun.tools.javac.main.Main.compile(jdk.compiler at 9.0
> /Main.java:261)
>          at com.sun.tools.javac.main.Main.compile(jdk.compiler at 9.0
> /Main.java:143)
>          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 mailing list