-
Notifications
You must be signed in to change notification settings - Fork 2k
Description
Hello!
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.Generatedwhich shall be used instead (module:java.compiler). So, your code generator can work like this:- if
javax.annotation.processing.Generatedis loaded, generate the output code with this annotation, - if
javax.annotation.Generatedis loaded, use it, - otherwise, don't add any annotation to the generated code.
- if
The changes are backward compatible.