Does anyone know why Gradle does not support the most recent JDK's, like 20/21? It's a build tool th...
g
Does anyone know why Gradle does not support the most recent JDK's, like 20/21? It's a build tool that wraps
javac
right, at a 10,000ft view, so if there is a java compiler on the system capable of compiling those versions why can't Gradle use it? For instance, why can't I run the Gradle daemon with JDK17, and ask it to use JDK21 to compile my
.java
files 🤔
m
Have you tried the toolchains?
c
some Gradle versions had fixed constants for the JavaLanguageVersion used in toolchains. Looking at Gradle 8 that limitation appears to be removed (unsure exactly when that was done).
g
Ah you can do it with Toolchains? Does anyone know how to do it? I'm using
8.0-rc
I'm familiar with toolchains in general and love them for normal use, I didn't know you could use them for this sort of thing though
If I set my Gradle JVM to 19, and use the following, I get the below error:
Copy code
java {
    toolchain {
        languageVersion.set(JavaLanguageVersion.of(21))
    }
}
Copy code
2023-01-10T14:43:46.776-0500 [ERROR] [system.err] 	java.lang.UnsupportedClassVersionError: postgres/wire/protocol/App has been compiled by a more recent version of the Java Runtime (class file version 65.0), this version of the Java Runtime only recognizes class file versions up to 63.0
m
So 63 is Java19
I'm guessing 65 is Java21. Can you post the full error with
--stacktrace
?
And including the failing task?
Made a small test and it's working fine for me
Of course you need to run your jar with a 21 JVM
That's my build file:
Copy code
plugins {
    id("java")
    id("application")
}

repositories {
    mavenCentral()
}

java {
    toolchain {
        languageVersion.set(JavaLanguageVersion.of(21))
    }
}

application {
    mainClass.set("com.example.Main")
}
(main is trivial)
(I installed 21 through
sdk uninstall java 21.ea.4-open
)
t
FYI: if, for example, you want to use some JDK preview with "toolchain" in Kotlin - you could use second approach via Tasks DSL:
Copy code
tasks.withType<UsesKotlinJavaToolchain>().configureEach {
    kotlinJavaToolchain.jdk.use(
        "/path/to/local/jdk", // Put a path to your JDK
        JavaVersion.<LOCAL_JDK_VERSION> // For example, JavaVersion.17
    )
}
Note though that this will not configure any Java/Groovy etc tasks with this toolchain.
g
Huh very strange, thank you for investigating @mbonnin and @tapchicoma This is what ended up finally working, maybe this gives some hints as to what is wrong with my current setup?
Copy code
java {
    toolchain {
        // Tell Gradle itself to use JDK19
        languageVersion.set(JavaLanguageVersion.of(19))
    }
}

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

val JDK_VERSION = JavaLanguageVersion.of(21)
val JDK_FLAGS = listOf("--enable-preview")

val JDK_21_COMPILER: Provider<JavaCompiler> = javaToolchains.compilerFor {
    languageVersion.set(JDK_VERSION)
}

val JDK_21_LAUNCHER: Provider<JavaLauncher> = javaToolchains.launcherFor {
    languageVersion.set(JDK_VERSION)
}

tasks.withType<JavaCompile>().configureEach {
    javaCompiler.set(JDK_21_COMPILER)
    options.isIncremental = true
    options.isFork = true
    options.compilerArgs = JDK_FLAGS
}

tasks.withType<Test>().configureEach {
    useJUnitPlatform()
    javaLauncher.set(JDK_21_LAUNCHER)
    jvmArgs = JDK_FLAGS
}

tasks.withType<JavaExec>().configureEach {
    javaLauncher.set(JDK_21_LAUNCHER)
    jvmArgs = JDK_FLAGS
}
207 Views