3

I have an open-source Java library project, for which I would like the built artifact to maintain compatibility with Java 8 as long as possible.

I recently received a pull request, to add a module-info.java file and setup Gradle for Java 9+ support. Between that PR and the Gradle documentation, I have re-worked the relevant portion of build.gradle to look like this:

sourceCompatibility = 1.9
targetCompatibility = 1.8

ext.moduleName = 'vault.java.driver'
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', 'junit',
                '--add-reads', "$moduleName=junit",
                '--patch-module', "$moduleName=" + files(sourceSets.test.java.srcDirs).asPath,
        ]
        classpath = files()
    }
}

This is great, but I'm noticing some serious confusion between Gradle and IntelliJ.

When I import the project in IntelliJ, it does so cleanly, and the project structure clearly shows "Language Level" 9. IntelliJ seems to understand my build.gradle just fine, as it changes the language level to 8 when I temporarily set sourceCompatibility=1.8 and refresh.

However, when I click "Build Project" from the "Build" pull-down menu, I get the error:

Error:(1, 1) java: modules are not supported in -source 8
  (use -source 9 or higher to enable modules)

Meanwhile, when I try to bypass IntelliJ and run ./gradlew build from the command-line, Gradle doesn't seem to understand my sourceCompatibility or targetCompatability settings:

* What went wrong:
Execution failed for task ':compileJava'.
> invalid source release: 1.9

I'm really confused. How does on create a build.gradle file, which both:

  • allows for Java 9+,
  • while still maintaining built artifact compatibility with Java 8, and
  • makes both Gradle and IntelliJ happy?
Steve Perkins
  • 11,520
  • 19
  • 63
  • 95
  • NOTE: Upgrading my Gradle wrapper from 4.10 to 5.4 had no effect. – Steve Perkins Jun 18 '19 at 18:30
  • 1
    You might be able to use [the `--release`](https://stackoverflow.com/questions/43102787/what-is-the-release-flag-in-the-java-9-compiler) flag. [This Gradle blog](https://blog.gradle.org/mrjars) may also be helpful (haven't read it thoroughly), which seems to have been written in response to [JEP 238](https://openjdk.java.net/jeps/238). – Slaw Jun 18 '19 at 22:03
  • `java: modules are not supported in -source 8` You can not use module-info when compiling against 1.8 source, see https://bugs.openjdk.java.net/browse/JDK-8206896 Check this thread: https://stackoverflow.com/questions/55100737/compile-a-jdk-8-project-a-jdk-9-module-info-java-in-gradle Enable Settings (Preferences on macOS) | Build, Execution, Deployment | Build Tools | Gradle | Runner | **Delegate IDE build/run actions to Gradle** option to get identical results in IDE and Gradle. – Andrey Jun 19 '19 at 06:50
  • @Andrey: Hmm... but I am setting "sourceCompatability" to 1.9 for this very reason. Only the "targetCompatability" is set for 1.8 (because I want the built artifact to maintain Java 8 backwards compatibility). Why would Gradle or IntelliJ reference "targetCompatability" rather than "sourceCompatability" for this? – Steve Perkins Jun 19 '19 at 14:24

0 Answers0