Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How build multiple projects with gradle with multiple jdk versions?

I have multiple projects and build using different jdks(IBM,SUN) and versions(1.6,1.7,1.8).

In my gradle script of the each project I have defined the sourceCompatibility and targetCompatibility. How can I define the each project specific org.gradle.java.home?

If I define the IBM jdk 6 as org.gradle.java.home in my main project gradle.properties file other projects build will fail.

I have gradle.properties file only main gradle project.

I don't want to use JAVA_HOME class path variable to run my gradle scripts. I'm using gradle 2.3.

Please give some advice to fix this issue?

like image 863
user3496599 Avatar asked May 29 '15 10:05

user3496599


1 Answers

Since Gradle 6.7, Gradle introduced the notion of toolchains for the JVM. Toolchains allow to define a JDK version to be used to compile/run a project, that is a JDK different than the one running gradle.

This is as easy as writing in the build script :

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(15)
    }
}

Gradle will look up the requested toolchain on usual standard local paths (and you can evn provide your own lookup location via the org.gradle.java.installations.paths property), and can eventually download it. It even support multiple OpenJDK vendors. Their documentation explains it all.

So for a multi-project setup, you can do something like :

.
├── jdk11
│   ├── build.gradle
│   └── src
├── jdk16
│   ├── build.gradle
│   └── src
├── jdk17
│   ├── build.gradle
│   └── src
├── build.gradle
├── gradle.properties
└── settings.gradle
  • settings.gradle

    rootProject.name = 'THE-project'    
    include("jdk11", "jdk16", "jdk17")
    
  • build.gradle

    subprojects {
      apply(plugin: "java-library") // or whatever applies to the sub-project
    
      // repositories, test, ...
    }
    ``
    
    
  • gradle.properties the property is optional, it is only if additional lookup path are needed

    org.gradle.java.installations.paths=/path to panama jdk,/path to loom jdk,etc
    
  • jdk11/build.gradle

    java {
      toolchain {
        languageVersion = JavaLanguageVersion.of(11)
      }
    }
    
    tasks.withType(JavaCompile) {
      options.release.set(11)
    }
    
    // dependencies, etc.
    
  • jdk16/build.gradle

    java {
      toolchain {
        languageVersion = JavaLanguageVersion.of(16)
      }
    }
    
    tasks.withType(JavaCompile) {
      options.release.set(16)
    }
    
    // dependencies, etc.
    
  • jdk17/build.gradle

    java {
      toolchain {
        languageVersion = JavaLanguageVersion.of(17)
      }
    }
    
    tasks.withType(JavaCompile) {
      options.release.set(17)
      options.compilerArgs = ['--add-modules=jdk.incubator.foreign',
                              '--enable-preview',
                              '-Xlint:preview']
    }
    
    // dependencies, etc.
    

I don't know about Eclipse, but this work just fine in IntelliJ IDEA 2021.1. I use a JDK 11 to run gradle in the shell, and IntelliJ IDEA is setup to run Gradle with JDK 11 as well (Settings | Build tools | Gradle).


The only downside at the moment is that JavaExec tasks must be configured with the right launcher (eg using the (sub-)project's toolchain). IntelliJ runs main class using a JavaExec task, which will benefit form this as well.

tasks.withType(JavaExec){
    javaLauncher.set(javaToolchains.launcherFor(java.toolchain))
}

Track gradle/gradle#14363 on this matter.


like image 185
Brice Avatar answered Sep 21 '22 13:09

Brice