Unused import of javax.annotation.Generated breaks annotation processing on JDK9 with Jigsaw
See original GitHub issueHello!
Today, I tried to write a modular JDK9 application with Dagger. Unfortunately, it turned out to be impossible without hacks. The problem is that the file SourceFileGenerator.java
contains an unused import of javax.annotation.Generated
.
This annotation is a part of java.xml.ws.annotation
module, which is not loaded by default and is deprecated (to be removed in future Java versions). Historically, it was incorrectly placed in a package together with Java EE annotations. Furthermore, there exist several crappy JSR-305 JAR-s used by many libraries, that also add new annotations to the same package. In Jigsaw, the package can be owned by only one module. Java 9 refuses to compile an appplication and run it, if there are two modules that contain the same package.
Now, to actually build Dagger modular application, we need to use some hacks. First of all, if we have any JSR-305 in our dependency list, we need to physically copy the JAR somewhere and use --patch-module
compiler flag:
--patch-module java.xml.ws.annotation=C:\path\to\my\jsr305.jar
The second thing is to enable that module explicitly:
--add-modules java.xml.ws.annotation
And, configure the build system to exclude all the possible variants of jsr305 (Gradle example below):
configurations {
all*.exclude group: 'com.google.code.findbugs', module: 'jsr305'
}
However, we’re not done yet. The annotation processor seems to ignore the flag --add-modules
(and --add-reads
, --add-open
, etc.), which causes the following compiler error:
NoClassDefFoundError: javax/annotation/Generated
As a workaround, we need to use javax.annotation:jsr250-api:1.0
dependency for annotation processors. Below, there’s a configuration for Gradle:
dependencies {
// other dependencies here
apt 'com.google.dagger:dagger-compiler:2.11`
apt 'javax.annotation:jsr250-api:1.0'
}
Now Dagger is generating the code, but to make it work, we must modify our module-info.java
files to add the dependency on the deprecated java.xml.ws.annotation
:
module com.example.mymodule {
requires java.xml.ws.annotation;
requires dagger;
}
As you can see, using Dagger is pretty complicated 😃.
You can do the following things to fix it:
- remove that import from
SourceFileGenerator.java
(the code is already refering to the annotation as a String). - JDK9 introduces a new annotation:
javax.annotation.processing.Generated
which shall be used instead (module:java.compiler
). So, your code generator can work like this:- if
javax.annotation.processing.Generated
is loaded, generate the output code with this annotation, - if
javax.annotation.Generated
is loaded, use it, - otherwise, don’t add any annotation to the generated code.
- if
The changes are backward compatible.
Issue Analytics
- State:
- Created 6 years ago
- Reactions:2
- Comments:12
Top GitHub Comments
I created a Pull Request that fixes this issue 16 days ago: https://github.com/google/dagger/pull/882 - has anyone looked at it? Any ETA for merging it and improving Dagger cooperation with JDK9?
Hi!
No, it won’t solve any problem, because the application will still have two “modules” that are trying to write to the same package
javax.annotation
. The only difference is that instead of patchingjava.xml.ws.annotation
, the application has to patchjsr250
withjsr305
.jsr305.jar
is unfortunately used by many popular libraries (including your own Guava), so in practice, your solution will only work only for applications that do not rely on thirdparty libraries at all.In addition, adding a dependency on JSR-250 makes little sense for a library like Dagger, because these annotations are JavaEE-specific (except
Generated
), and it also pollutes application dependencies with unnecessary stuff.The right way to fix it is presented above:
jsr250
dependency andjava.xml.ws.annotation
module, so we can remove it, too,javax.annotation.processing.Generated
for JDK9 applications - in this way the application does not have to load anything extra to work.I’m looking forward to your feedback.