Correct gradle Eclipse JUni5 Java9 configuration?


(Sverre Moe) #1

Modular application in Eclipse with a module-info.java

Using Gradle and JUnit 5 with Java 10.

build.gradle

dependencies {
    compile group: 'org.controlsfx', name: 'controlsfx', version: '9.0.0'
    compile group: 'com.jfoenix', name: 'jfoenix', version: '9.0.4'
    compile group: 'org.jfxtras', name: 'jfxtras-controls', version: '9.0-r1'
    compile group: 'com.google.protobuf', name: 'protobuf-java', version: '3.5.1'

    testCompile group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.2.0'
    testRuntime group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version:'5.2.0'
}

compileJava {
    inputs.property("moduleName", moduleName)
    doFirst {
        options.compilerArgs = [
             '--module-path', classpath.asPath,
        ]
        classpath = files()
    }
}

compileTestJava {
    inputs.property("moduleName", moduleName)
    doFirst {
        options.compilerArgs = [
            '--module-path', classpath.asPath,
            '--add-modules', 'org.junit.jupiter.api',
            '--add-reads', "$moduleName=org.junit.jupiter.api",
            '--patch-module', "$moduleName=" + files(sourceSets.test.java.srcDirs).asPath,
        ]
        classpath = files()
    }
}

test {
    useJUnitPlatform()

    doFirst {
        jvmArgs = [
            '--module-path', classpath.asPath
        ]
    }
}

As taken from the Guide to build Java 9 Modules with Gradle:
https://guides.gradle.org/building-java-9-modules/#modify_the_code_compiletestjava_code_task_to_locally_alter_the_module

module-info.java

module com.djviking.movies { 

    requires javafx.controls;
    requires javafx.fxml;
    requires javafx.web;
    requires javafx.graphics;

    /* Named modules */
    requires jfxtras.controls;
    requires com.jfoenix;

    /* Automatic modules */
    requires controlsfx;
    requires protobuf.java;

    exports com.djviking.movies to javafx.graphics;
    opens com.djviking.movies to javafx.graphics;
}

Running gradle test works fine. No problems.

Though Eclipse complains that it cannot find org.junit in my test classes.
import org.junit cannot be resolved

For the eclipse project configuration I have placed the JUnit dependencies in the classpath. All the others I have placed on the modulepath. If I place the JUnit dependencies also on modulepath it alone does not fix the problem. Now then eclipse says “The type org.junit.jupiter.api.Assertions is not accessible”.

I can fix the eclipse problem further by adding the automatic module for JUni5 to module-info.java
requires org.junit.jupiter.api;

However then it will not compile with gradle.

> Task :compileJava FAILED
/home/djviking/workspace/movies/src/main/java/module-info.java:20: error: module not found: 
org.junit.jupiter.api
    requires org.junit.jupiter.api;

Probably because JUnit is declared as a test dependency and not on the compileJava modulepath.

The guide should be updated.
Building Java 9 Modules shows how to use JUnit4. Maybe it should be updated to JUnit5. At least show how to set up properly with Eclipse.

I am unable to run the tests with gradle with the elaborate test configuration in the Guide
https://guides.gradle.org/building-java-9-modules/#modify_the_code_test_code_task_to_consume_the_locally_altered_module

test {
    useJUnitPlatform()

    doFirst {
        jvmArgs = [
            '--module-path', classpath.asPath, 
            '--add-modules', 'ALL-MODULE-PATH', 
            '--add-reads', "$moduleName=org.junit.jupiter.api", 
            '--patch-module', "$moduleName=" + files(sourceSets.test.java.outputDir).asPath, 
        ]
        classpath = files()
    }
}

com.djviking.movies.MoviesTest > movies() FAILED
    java.lang.reflect.InaccessibleObjectException: Unable to make public 
com.djviking.movies.MoviesTest() accessible: module com.djviking.movies does not "exports 
com.djviking.movies" to module org.junit.platform.commons