Home > Back-end >  Can we force the use of a JDK as Gradle Java toolchain?
Can we force the use of a JDK as Gradle Java toolchain?

Time:07-23

Gradle 6.7 introduced Java toolchains.

In the documentation, they state that Gradle chooses a JRE/JDK matching the requirements of the build ... By default, Gradle prefers installed JDKs over JREs... (from docs.gradle.org: Toolchains for JVM projects).

Thus, the JDK is chosen if we have both, JRE and JDK, installed.

Problem:

Imagine that the user only has a JRE installed.

Yet, we want to run our application via Gradle (JavaExec task) using a Java toolchain, but have to ensure that a JDK is used for running because this application relies on tools.jar, which is not part of a JRE.

Question:

Is it possible to force Gradle to use a JDK for all tasks (including running / launching), not just for compiling, when using a Java toolchain? (see following minimal example with comment)

// This build.gradle should ensure that the application is run using a JDK of version 9 
plugins {
    id 'application'
}
java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(9)
        // QUESTION: How to force JDK here? <------
    }
}
// for JavaExec task runJar
tasks.withType(JavaExec).configureEach {
    javaLauncher = javaToolchains.launcherFor(java.toolchain)
}
task runJar(type: JavaExec) {
    classpath = files(jar.archiveFile)
}
...

CodePudding user response:

What is the tool you are using? If it is IntelliJ, then

A feature in IntelliJ that where it would look up if java tool chain is configured and if it is, make it impossible for me to have mismatching configuration within:

Run configurations Project Structure > Project SDK Project Structure > Project Language Level

enter image description here

CodePudding user response:

One always has to add rt.jar first:

task runJar(type: JavaExec) {
    classpath = files(new File(System.getProperty('java.home')   File.separator   'lib'   File.separator   'rt.jar'))
    classpath  = files(jar.archiveFile)
    ...
}
runJar.onlyIf {
    new File(System.getProperty('java.home')   File.separator   'lib'   File.separator   'rt.jar')).exists()
}

This probably would still would require a mainClassName inside jar.archiveFile. With JavaExec one can set up whatever environment variable ...incl. JAVA_HOME, so this could be alternated per task. But one can as well use an Exec task on then directly run java -jar some.jar.
I wouldn't even be too certain, that these "runtime only" JRE distributions still exist?
All I know is that there is no tools.jar

  • Related