Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JUnit 5, Java 9 and Gradle: How to pass --add-modules?

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.

like image 631
Juergen Zimmermann Avatar asked Oct 28 '17 14:10

Juergen Zimmermann


People also ask

Does Gradle support Java modules?

Building, testing and running Java Modules With this release, Gradle supports the Java Module System with everything you need to compile and execute tests for Java modules. You can also build Javadoc and run applications.

Can't resolve all dependencies for configuration Gradle?

This is because of slow internet connection or you haven't configure proxy settings correctly. Gradle needs to download some dependencies , if it cant access the repository it fires this error. All you have to do is check your internet connection and make sure gradle can access the maven repository.


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.

like image 81
Naman Avatar answered Oct 16 '22 13:10

Naman


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')
like image 35
Juergen Zimmermann Avatar answered Oct 16 '22 14:10

Juergen Zimmermann