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@9.0
/JavacProcessingEnvironment.java:669)
         at
com.sun.tools.javac.processing.JavacProcessingEnvironment$DiscoveredProcessors$ProcessorStateIterator.next(jdk.compiler@9.0
/JavacProcessingEnvironment.java:766)
         at
com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(jdk.compiler@9.0
/JavacProcessingEnvironment.java:857)
         at
com.sun.tools.javac.processing.JavacProcessingEnvironment.access$2100(jdk.compiler@9.0
/JavacProcessingEnvironment.java:104)
         at
com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(jdk.compiler@9.0
/JavacProcessingEnvironment.java:1183)
         at
com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(jdk.compiler@9.0
/JavacProcessingEnvironment.java:1291)
         at
com.sun.tools.javac.main.JavaCompiler.processAnnotations(jdk.compiler@9.0
/JavaCompiler.java:1247)
         at com.sun.tools.javac.main.JavaCompiler.compile(jdk.compiler@9.0
/JavaCompiler.java:921)
         at com.sun.tools.javac.main.Main.compile(jdk.compiler@9.0
/Main.java:261)
         at com.sun.tools.javac.main.Main.compile(jdk.compiler@9.0
/Main.java:143)
         at com.sun.tools.javac.Main.compile(jdk.compiler@9.0/Main.java:56)
         at com.sun.tools.javac.Main.main(jdk.compiler@9.0/Main.java:42)

Reply via email to