How to compile a Java 9 project with Lombok in Gradle?

7

TL; DR

  

How to pass multiple parameters -J--add-opens=<pacote>=ALL-UNNAMED so that Gradle uses them when invoking javac ?

Details

I have a HelloWorld.java code using Lombok in Java 9:

import lombok.NonNull;

public class HelloWorld {
    public static void main(@NonNull String[] args) {
        System.out.println("Hello World");
    }
}

The Lombok version is the unstable version edge (this link may change in the future, this is version 1.16. 19). I placed the lombok-edge.jar in the same folder as HelloWorld.java above.

Lombok is not yet mature enough to be used in Java 9 due to the numerous difficulties that Java 9's modularization has introduced. However, you can compile and run it yourself with proper abuses at the command line:

javac -parameters -Xlint:all,-processing --add-modules=java.xml.ws.annotation -J--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED -cp lombok-edge.jar HelloWorld.java

With this, no warning appears and the HelloWorld.class file is generated. And then:

java HelloWorld

Produce this output:

Hello World

So far so good, but now I wanted to do that in Gradle.

I tried this file:

apply plugin: 'java'

sourceCompatibility = '1.9'

if (!hasProperty('mainClass')) {
    ext.mainClass = 'HelloWorld'
}

repositories {
    flatDir {
        dirs 'libs'
    }
}

dependencies {
    compileOnly files('libs/lombok-edge.jar')
    testCompileOnly files('libs/lombok-edge.jar')
}

tasks.withType(JavaCompile) {
    options.encoding = "UTF-8"
    options.compilerArgs << "-parameters" << "-Xlint:all,-processing"
    options.compilerArgs << "--add-modules=java.xml.ws.annotation"
    options.compilerArgs << "-J--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED"
    options.compilerArgs << "-J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED"
    options.compilerArgs << "-J--add-opens=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED"
    options.compilerArgs << "-J--add-opens=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED"
    options.compilerArgs << "-J--add-opens=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED"
    options.compilerArgs << "-J--add-opens=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED"
    options.compilerArgs << "-J--add-opens=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED"
    options.compilerArgs << "-J--add-opens=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED"
    options.compilerArgs << "-J--add-opens=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED"
}

Of course, I put the lombok-edge.jar inside a libs folder.

When trying to build build with Gradle 4.2:

gradle build

The result was this:

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':compileJava'.
> invalid flag: -J--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

* Get more help at https://help.gradle.org

BUILD FAILED in 0s
1 actionable task: 1 executed
Since command line compilation works, this should not be a problem in Lombok (the problem with it is that you need this absurd and esoteric amount of command line parameters to work in Java 9). I think the problem is simply that I do not know how to use Gradle, a problem that simply comes down to:

  

How to pass multiple parameters -J--add-opens=<pacote>=ALL-UNNAMED so that Gradle uses them when invoking javac ?

Edited: I also tried Gradle 4.3.1, and the result was even worse than Gradle 4.2:

> Task :compileJava FAILED
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.gradle.api.internal.tasks.compile.reflect.SourcepathIgnoringInvocationHandler (file:/C:/Users/d841156/.gradle/wrapper/dists/gradle-4.3.1-bin/7yzdu24db77gi3zukl2a7o0xx/gradle-4.3.1/lib/plugins/gradle-language-java-4.3.1.jar) to method com.sun.tools.javac.file.BaseFileManager.handleOption(java.lang.String,java.util.Iterator)
WARNING: Please consider reporting this to the maintainers of org.gradle.api.internal.tasks.compile.reflect.SourcepathIgnoringInvocationHandler
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release


FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':compileJava'.
> invalid flag: -J--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

* Get more help at https://help.gradle.org

BUILD FAILED in 1s
1 actionable task: 1 executed
    
asked by anonymous 14.11.2017 / 16:36

1 answer

2

Try the following:

apply plugin: 'java-library'

dependencies {
    compileOnly files("libs/lombok-edge.jar")
}

tasks.withType(JavaCompile) { 
    options.fork = true
    options.forkOptions.jvmArgs += [
          '--add-opens', 'jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED',
          '--add-opens', 'jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED',
          '--add-opens', 'jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED',
          '--add-opens', 'jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED',
          '--add-opens', 'jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED',
          '--add-opens', 'jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED',
          '--add-opens', 'jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED',
          '--add-opens', 'jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED',
          '--add-opens', 'jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED'
        ]
}

As this comment in GitHub this combination is working with lombok-edge , Gradle 4.2. 1 and Java 9. The comment author even claims to have gotten a clean build with the java-library plugin even after commenting on the forkOptions .

    
15.11.2017 / 00:30