Building Java 9 projects with Eclipse and Gradle

What: Using gradle to build and setup a Java 9 project in Eclipse Oxygen (4.7.1)
Why: Automate settings in Eclipse like module path, … for Java 9 projects
How: Using gradle ‚eclipse’/’java‘ plugin

Background

The following is taken from this buildship issue.

If you create a Java 9 project, a module-info.java file is needed describing your module. The dependencies defined in the build.gradle file are not automatically added to the project settings and your module-info.java file will have compile errors in Eclipse. If added manually, the settings are gone if the project is refreshed via gradle or each dependency has to be added manually if no refresh is used. This can be avoided with the gradle ‚eclipse‘ plugin.

At compile time, the dependencies of your project needs to be available as (automatic) modules and at runtime the dependencies should be available somewhere in the module path.

Requirements

Buildship 2.2

You can install the buildship plugin from Eclipse Marketplace or from the update site. You need version 2.2 at least. Currently, only the update site has this version.

Eclipse project nature

Your project needs to be a gradle project. If this is not the case, you can convert it to a gradle project by right-click on the project -> Configure -> Add Gradle Nature.

Modifications of build.gradle

Add the following to your build.gradle file:

apply plugin 'eclipse'
eclipse {
    classpath {
        file {
            whenMerged {
                entries.findAll { isModule(it) }.each { it.entryAttributes['module'] = 'true' }
            }
        }
    }
}
 
boolean isModule(entry) {
    // filter java 9 modules
	entry.kind == 'lib'  // Only libraries can be modules
}

Update Eclipse project

Rightclick on your project -> Gradle -> Refresh Gradle Project.

Now, the project is set up in such a way, that all your dependencies are available for use in module-info.java.

Add dependencies as modules for compilation

The dependencies defined by the build.gradle are by default not added to the module path if you are using Java 9 for compilation. They can be added by:

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

Add dependencies in a folder which can be used as module path

A simple derived copy task can be used to put all the dependencies in a subfolder of the build diretory:

task makePackage(type: Copy) {
    into "$buildDir/lib"
    from configurations.runtime
}

This folder can be used as module path while running your project:

java --module-path <other entries>:<buildDir/lib> <modulename>/<Main class>