Gradle:具有不同来源的多项目&目标兼容性

时间:2016-02-09 16:47:19

标签: java gradle build.gradle

我有多项目gradle配置,它使用java 7进行构建。我正在添加一个必须使用Java 6构建的新项目。

Q&A开始,我尝试了所提出的不同解决方案,但没有一种方法有效。

这是顶级build.gradle:

allprojects {
    apply plugin: 'idea'
    apply plugin: 'java'


    repositories {
        maven { url 'http://repo1.maven.org/maven2' }
        mavenLocal()
    }

    sourceCompatibility = 1.7
    targetCompatibility = 1.7

    gradle.projectsEvaluated {
        tasks.withType(JavaCompile) {
            options.compilerArgs << "-Xlint:-options"
        }
    }
}

我试图在子项目中提供源代码兼容性,但似乎这没有效果。

更新

我创建了一个多模块gradle项目的示例,其中一个子项目使用Java 6,另一个使用java 8.我在org.gradle.java.home中为每个子项使用了gradle.properties属性-projects为每个人设置Java主目录。这是github repo

子项目使用Java 8中的Apis包含每个类,使用java 6的子项目预计会失败,但构建运行成功。

这是父build.gradle文件:

group 'com.test'
version '1.0-SNAPSHOT'
repositories {
   mavenCentral()
}

父settings.gradle:

的内容
rootProject.name = 'Parent'
include 'child2Java6'
include 'child1Java8'

Java 6子项目的build.gradle的内容:

group 'com.test'
version '1.0-SNAPSHOT'

apply plugin: 'java'

sourceCompatibility = JavaVersion.VERSION_1_6
targetCompatibility = JavaVersion.VERSION_1_6
repositories {
    mavenCentral()
}
compileJava.doFirst {
    println "source compatibility  " + sourceCompatibility
    println "target compatibility  " + targetCompatibility
}
dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.11'
}

Java 6子项目的gradle.properties的内容:

org.gradle.java.home=/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/

build.gradle for java 8子项目:

group 'com.test'
version '1.0-SNAPSHOT'

apply plugin: 'java'


sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
repositories {
    mavenCentral()
}
compileJava.doFirst {
    println "source compatibility  " + sourceCompatibility
    println "target compatibility  " + targetCompatibility
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.11'
}

它的gradle.properties:

org.gradle.java.home=/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/

我正在打印sourceCompatibilitytargetCompatibility,并且每个项目的值都很高。

我正在使用gradle clean build进行构建。

gradle -v输出:

------------------------------------------------------------
Gradle 2.9
------------------------------------------------------------

Build time:   2015-11-17 07:02:17 UTC
Build number: none
Revision:     b463d7980c40d44c4657dc80025275b84a29e31f

   Groovy:       2.4.4
   Ant:          Apache Ant(TM) version 1.9.3 compiled on December 23 2013
   JVM:          1.8.0_65 (Oracle Corporation 25.65-b01)
   OS:           Mac OS X 10.11.1 x86_64

我使用Java 8作为默认的Jdk。

提前致谢,

2 个答案:

答案 0 :(得分:1)

与其他编程语言类似,Gradle有很多方法可以完成相同的任务。通过多项目构建中的项目定义特定插件或依赖项将使您的构建自包含,并希望创建更易于维护的代码。

来自Gradle文档Chapter 11 Section 2

  

您还可以使用属性向项目对象添加属性   文件。您可以将Gradle.properties文件放在Gradle用户主目录中   目录(由“GRADLE_USER_HOME”环境变量定义,   如果没有设置默认值为USER_HOME / .gradle)或在您的项目中   目录。对于多项目构建,您可以放置​​gradle.properties   任何子项目目录中的文件。设置的属性   可以通过项目对象访问gradle.properties文件。该   用户主目录中的属性文件优先于   项目目录中的属性文件。

这意味着在每个子项目gradle.properties文件中,您可以定义项目将使用的Java版本或其他依赖项。在Gradle项目根gradle.properties文件中设置Gradle Java版本的示例如下:

org.gradle.java.home=/path_to_jdk_7

在您的子项目gradle.properties文件中,您将获得类似于:

的内容
com.myproject.app=/path_to_jdk_6

<强>更新

Gradle提供了监视子项目的工具。通过在父build.gradle中包含以下内容,可以调用任务来打印子项目及其父项。

allprojects {
    task versioner << {task -> println "Loaded: $task.project.name"}
}
subprojects {
    versioner << {println " - Depends on parent"}
}

为了验证Java版本是否不同,您可以尝试通过JavaExec从子项目中运行一个类。这可以在子项目build.gradle文件中调用,如下所示:

task runApp(type: JavaExec) {

    classpath = sourceSets.main.runtimeClasspath

    //make sure the path points to project's java class being called 
    main = "com.test.MainClass"
}

答案 1 :(得分:1)

我引用了gradle论坛上的答案:

您无法在每个项目级别更改java.home,因为它适用于整个多项目构建。

设置编译器的源级别只会影响您可以使用的语言功能(例如Lambdas)。它对API没有影响。这与Gradle无关,即使你直接运行javac也是如此。为了确保您没有使用错误的API,您必须设置编译任务的bootClasspath。

tasks.withType(JavaCompile) {
  options.fork = true
  options.bootClasspath = "path/to/rt.jar"
}