Eclipse running with JDK 11 -> Gradle 6.2.1 fails to compile source for JDK 8

Hi all,

until Eclipse 2020-03 I executed it with JDK 8, since Eclipse 2020-06 I’m doing so with JDK 11. Reasons are that I need the C+±plugin CDT, which seems to only work with JDK 11, and Eclipse requires JDK 11 for itself with the next release anyway. Besides that, I have still registered JDK 8 as default JRE to be used by Eclipse. Coding in Eclipse itself seems to work as expected, especially I don’t get any errors or warnings about deprecations or missing classes because of changes JDK 8 vs. JDK 11.

The problem is with Buildship: When using the Gradle’s task view to publish some projects, compilation fails with errors which are clearly related to using JDK 11 as well:

C:\Users[…]\jooq\Sequences.java:7: error: package javax.annotation does not exist
import javax.annotation.Generated;

My build.gradle already contained the following two statements, which don’t seem to have any effect:

sourceCompatibility = 1.8
targetCompatibility = 1.8

Changing those lines to the following didn’t change anything as well:

java
{
	sourceCompatibility = JavaVersion.VERSION_1_8
	targetCompatibility = JavaVersion.VERSION_1_8
}

When publishing the projects on the shell things succeed again, because JDK 8 is still the default JDK of the system. Only Eclipse knows about JDK 11 and I configured the path to use it in eclipse.ini. What does seem to work as well is configuring the directory where JDK 8 is placed in the Gradle-configs of Eclipse:

Afterwards publishing within Eclipse using Gradle’s task view succeeds again, after removing that config things fail again.

Is that by design? I had expected that I’m configuring the source and target compatibility to prevent exactly those problems. Or what am I doing wrong?

Thanks for your explanations!

I’m somewhat sure now that I’m not doing something wrong, but I simply misunderstood things: The problem is that my project gets build with JDK 11 in Eclipse and some packages have simply been removed from that JDK. Neither the source- nor target compatibility of Gradle can change that, they only influence the generated byte code in case compiling succeeds:

Buildship updates the compiler properties as follows:

  • Eclipse’s compiler compliance level and source compatibility is updated to Gradle’ sourceCompatibility
  • Eclipse’s generated .class file compatibility is updated to Gradle’s targetCompatibility .

But to make the build succeed using JDK 11, the missing packages need to be made available as additional dependency. To do so, I decided to create a new Gradle-file documenting that problem with the following code:

if (JavaVersion.current().isJava8())
{
	return
}

dependencies
{
	compileOnly 'javax.annotation:javax.annotation-api:1.3.2'
}

This can then be applied to build.gradle using the following line:

apply from:		'buildSrc/src/main/java/BuildByJdk11Workarounds.gradle'

So, when build with JDK 11, additional dependencies are simply made available and compiling succeeds again. The important thing in my setup is that I want to keep targeting JDK 8, that’s while the dependency is compileOnly and why my compatibility-options still look like the following:

java
{
	sourceCompatibility = JavaVersion.VERSION_1_8
	targetCompatibility = JavaVersion.VERSION_1_8
}

In theory, with JDK 11 those could be easier set using the newly introduced release-option. But I currently don’t know about the influence at development time, like the settings done in Eclipse.

tasks.withType<JavaCompile> {
	options.compilerArgs.addAll(['--release', '11')]
}

What might be of additional interest is planned support for toolchains, which sounds pretty mich like what Maven already has. Not sure, though, how that would work in the context of Eclipse, in which the JVM used by Eclipse itself is reused by Gradle by default.