如何使用Gradle和多个JDK版本构建多个项目?

11

我有多个项目,使用不同的JDK(IBM,SUN)和版本(1.6,1.7,1.8)进行构建。

在每个项目的gradle脚本中,我已经定义了sourceCompatibility和targetCompatibility。如何定义每个项目特定的org.gradle.java.home

如果我在主项目的gradle.properties 文件中将IBM jdk 6定义为org.gradle.java.home,则其他项目的构建将失败。

我只有一个gradle.properties文件,它属于主gradle项目。

我不想使用JAVA_HOME类路径变量来运行我的gradle脚本。我正在使用gradle 2.3。

请给一些建议来解决这个问题?


使用if else条件基于项目更改Java版本。例如,如果您在build xml中有A、B和C项目,则将定义java home路径为null,并根据项目更改java home。我认为这将帮助您解决问题。 - stacktome
@stacktome 我正在使用Gradle。我该如何添加它?你能给一些示例吗? - user3496599
1
你唯一的选择是修改JavaCompile任务。在2.3版本中,你需要查看文档不太完整的JavaToolChain:https://docs.gradle.org/2.3/dsl/org.gradle.api.tasks.compile.JavaCompile.html#org.gradle.api.tasks.compile.JavaCompile:toolChain和https://docs.gradle.org/2.3/javadoc/org/gradle/jvm/toolchain/JavaToolChain.html,但是从2.4版本开始,该工具链已被更加文档不太完整的工具解析器所取代:https://docs.gradle.org/2.4/dsl/org.gradle.api.tasks.compile.JavaCompile.html#org.gradle.api.tasks.compile.JavaCompile:toolResolver - Johan Stuyts
2个回答

5
自从Gradle 6.7以来,Gradle引入了JVM的工具链的概念。 工具链允许定义用于编译/运行项目的JDK版本,该版本与运行gradle的JDK不同。
这很容易在构建脚本中编写:
java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(15)
    }
}

Gradle会在通常的标准本地路径上查找所需的工具链(您甚至可以通过org.gradle.java.installations.paths属性提供自己的查找位置),并最终可以下载它。它甚至支持多个OpenJDK供应商。他们的文档解释了这一切。
因此,对于多项目设置,您可以这样做:
.
├── 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.
    
我不了解Eclipse,但在IntelliJ IDEA 2021.1中这个工作正常。 我使用JDK 11在shell中运行gradle,而IntelliJ IDEA也设置为使用JDK 11运行Gradle(设置| 构建工具 | Gradle)。

目前唯一的缺点是,必须使用正确的启动器(例如使用(子)项目的工具链)对JavaExec任务进行配置。IntelliJ使用JavaExec任务运行主类,这也会受益于此。

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

在这个问题上跟踪gradle/gradle#14363



所以我有点困惑。我看到(/jdk11/src/和/jdk16/src/和/jdk17/src)。如果我有一个名为“MyCoolHelperMethods.java”的文件......我该如何拥有一个副本,可以编译到不同的JDK中?还是我漏掉了什么? - granadaCoder
@granadaCoder 这是一个不同的问题。当前答案是关于多个项目的。如果你的项目需要由不同的JDK编译,那么你需要注册不同的编译任务。我很乐意在另一个问题中回答这个问题,但很可能已经有人问过了这样的问题。 - bric3
谢谢你的“提示”。我会找找看。 - granadaCoder

0

我并不是Gradle的专家,但是有几点需要注意:

如果你想使用gradle.properties来编译你的项目,并针对特定的JVM进行设置,你需要知道以下内容:

"...配置按照以下顺序应用(如果在多个位置配置了某个选项,则以最后一个为准):

来自项目构建目录中的gradle.properties。
来自gradle用户主目录中的gradle.properties。
来自系统属性,例如在命令行上设置-Dsome.property。"

参考https://docs.gradle.org/current/userguide/userguide_single.html#build_environment

其次,如果你想动态配置编译器,下面的信息可能会对你有所帮助:

apply plugin: "java"
   sourceSets.main.java.srcDirs = ["MyProject/src"]
   dependencies {
      compile fileTree(dir: "MyProject/lib/jar")
   }
   tasks.withType(JavaCompile) {
       options.fork = true
       options.forkOptions.executable = "path/to/javac"
   }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接