I want to migrate from Java 8 to Java 9. When running my tests I get a CNFE regarding javax.xml.bind.JAXBContext. Therefore, "--add-modules java.xml.bind" seems to be required. I tried to extend my GRADLE_OPTS env variable, but the error remains. Any hint is appreciated.
-
Did you take a look at [How to express dependency in maven on java ee features for transition to Java 9?](https://stackoverflow.com/questions/46084751/how-to-express-dependency-in-maven-on-java-ee-features-for-transition-to-java-9/46086920#46086920) ? Could you detail your setup otherwise please. – Naman Oct 28 '17 at 15:43
-
It's a runtime failure, and not a compilation issue. I'm using Kotlin (not Java) and Spring Boot. @nullpointer: Does it mean, that I've only to adapt the 2nd part of your answer? – Juergen Zimmermann Oct 29 '17 at 00:20
-
Yes, just the test execution phase, in that case, should be the change required for you. – Naman Oct 29 '17 at 00:51
-
2To add to @nullpointer's comment. Java SE has deprecated the java.xml.bind module for removal. This means that `--add-modules java.xml.bind` is a short term workaround and you'll have to re-visit it. Better to move to the standalone API/implementation (javax.xml.bind:jaxb-api:2.3.0 and org.glassfish.jaxb:jaxb-runtime:2.3.0). – Alan Bateman Oct 29 '17 at 05:57
2 Answers
You can follow the five basic steps while migrating as stated in the gradle-building java9 modules which are:-
When converting a java-library project to produce a Java 9 module, there are five changes you should to make to your project.
Add a
module-info.java
describing the module.Modify the
compileJava
task to produce a module.Modify the
compileTestJava
task to locally alter the module.Modify the
test
task to consume the locally altered module.(Optional) Add
Automatic-Module-Name
manifest entries for all other projects.
In your use case, you need to ensure that the
compileTestJava {
inputs.property("moduleName", moduleName)
doFirst {
options.compilerArgs = [
'--module-path', classpath.asPath,
'--add-modules', 'org.junit.jupiter.api', // junit5 automatic module specific
'--add-modules', 'java.xml.bind', // jaxb specific
'--add-reads', "$moduleName=org.junit.jupiter.api", // allow junit to read your module
'--patch-module', "$moduleName=" + files(sourceSets.test.java.srcDirs).asPath, // add test source files to your module
]
classpath = files()
}
}
and then for executing the test, you would need not to udpate the test
task as
test {
inputs.property("moduleName", moduleName)
doFirst {
jvmArgs = [
'--module-path', classpath.asPath,
'--add-modules', 'ALL-MODULE-PATH', // to resolve all module in the module path to be accessed by gradle test runner
'--add-reads', "$moduleName=org.junit.jupiter.api",
'--patch-module', "$moduleName=" + files(sourceSets.test.java.outputDir).asPath,
]
classpath = files()
}
}
Note: For a long-term solution though I would also suggest you follow the important point mentioned in this answer as well.
According to Alan Bateman, I added the following lines to build.gradle
so that gradle bootRun
also works:
runtime('org.glassfish.jaxb:jaxb-runtime:2.3.0', 'javax.activation:activation:1.1.1')

- 27,789
- 26
- 218
- 353

- 2,084
- 7
- 29
- 43