【问题标题】:Compile and run different jdk within one jenkins job在一个 jenkins 作业中编译和运行不同的 jdk
【发布时间】:2020-03-03 07:44:47
【问题描述】:

我想收到 jenkins 的工作,它首先用 java 8 编译测试,然后用 java 11 运行它们。项目中使用了 Gradle,它有很多子项目。有可能吗?
我尝试了方法(这实际上是我想出的最好的方法)

tasks.withType(AbstractCompile) {
    options.with {
        fork = true
        forkOptions.javaHome = [java-8-home]
    }
}

放置在 main build.gradle 但我不确定这是否会影响其他目录中子项目/任务中的所有编译类型任务。 然后我用-Dorg.gradle.java.home=[java-11-home]调用了gradle任务

告诉我你的想法,谢谢!

【问题讨论】:

    标签: java jenkins gradle


    【解决方案1】:

    您想要达到的目标是完全可能的。让我们一步一步地检查这个可以是如何完成的。首先,我们指示 Gradle 编译所有与 Java 8 源和目标兼容的 Java 源,并使用从环境变量 JAVA8_HOME 获取的 Java 8 可执行文件执行编译:

    plugins {
        id 'java'
    }
    
    java {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
    
    tasks.withType(JavaCompile) {
        options.with {
            fork = true
            forkOptions.javaHome = System.env.'JAVA8_HOME' as File
        }
    }
    

    使用--info 开关运行构建表明Java 8 可执行文件确实取自环境变量JAVA8_HOME,并适用于所有Java 编译任务。

    > Task :compileJava
    Compiling with Java command line compiler 'C:\dev\java\jdk-8\bin\javac.exe'.
    
    > Task :compileTestJava
    Compiling with Java command line compiler 'C:\dev\java\jdk-8\bin\javac.exe'.
    

    使用取自环境变量 JAVA11_HOME 的 Java 11 执行测试的工作方式类似。

    test {
       executable = "${System.env.'JAVA11_HOME'}/bin/java"
    }
    

    这会再次产生以下输出:

    > Task :test
    Command: C:\dev\java\jdk-11/bin/java -Dorg.gradle.native=false ...
    

    子项目

    将此配置应用于多模块项目中的所有子项目非常简单。下面显示了一个根项目的build.gradle,它仅将所有规则应用于应用了 Java 插件的那些子项目。

    plugins {
        id 'base'
    }
    
    allprojects {
        plugins.withId('java') {
            repositories {
                mavenCentral()
            }
    
            java {
                sourceCompatibility = JavaVersion.VERSION_1_8
                targetCompatibility = JavaVersion.VERSION_1_8
            }
    
            tasks.withType(JavaCompile) {
                options.with {
                    fork = true
                    forkOptions.javaHome = System.env.'JAVA8_HOME' as File
                }
            }
    
            test {
                useJUnitPlatform()
    
                executable = "${System.env.'JAVA11_HOME'}/bin/java"
            }
    
            dependencies {
                testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.0")
                testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.6.0")
            }
        }
    }
    
    

    由于您现在依赖于设置环境变量,因此在实际开始构建之前检查它们是有意义的。这可以通过在准备好后检查任务图来完成:

    gradle.taskGraph.whenReady { taskGraph ->
        if (taskGraph.getAllTasks().find { it instanceof JavaCompile } != null
                && (System.env.'JAVA8_HOME' == null || System.env.'JAVA11_HOME' == null)) {
            throw new GradleException("Please export 'JAVA8_HOME' and 'JAVA11_HOME'")
        }
    }
    

    詹金斯

    在 Jenkins 中,您需要做的就是确保安装所需的 JDK 并正确导出环境变量。 Jenkinsfile 可能看起来像这样(持保留态度,我还没有测试它):

    pipeline {
        tools {
            jdk 'jdk-8'
            jdk 'jdk-11'
        }
    
        environment {
            JAVA8_HOME = "${tool 'jdk-8'}"
            JAVA11_HOME = "${tool 'jdk-11'}"
        }
    
        stages {
            stage('Build') {
                steps {
                    checkout scm
    
                    sh "./gradlew --no-daemon --info --stacktrace clean build"
                }
            }
        }
    }
    

    【讨论】:

    • 哇...看起来非常棒。将尝试用我的案例来实现它。谢谢!
    猜你喜欢
    • 2015-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多