升级到JDK 8后,为什么我的Spock单元测试在Gradle构建中失败?

时间:2015-09-28 19:36:23

标签: unit-testing groovy gradle java-8 spock

我正在尝试使用JDK 8,Groovy 2.4.4,Spock 1.0-groovy-2.4,Gradle 1.11(我的公司hass自定义插件构建在此之上)编译我的应用程序源。

gradle -version
Groovy:       1.8.6
Ant:          Apache Ant(TM) version 1.9.2 compiled on July 8 2013
Ivy:          2.2.0
JVM:          1.7.0_51 (Oracle Corporation 24.51-b03)
OS:           Windows 7 6.1 amd64

在我的构建环境中,我需要将JAVA_HOME保留到Java 7以用于其他项目。

JAVA_HOME = C:\Program Files\Java\jdk1.7.0_51
JAVA8_HOME = C:\Program Files\Java\jdk1.8.0_60

因此,在我的build.gradle中,我明确告诉Gradle使用JDK 8

tasks.withType(JavaCompile) {
    options.fork = true;
    options.forkOptions.executable = "${System.env.JAVA8_HOME}/bin/javac"
}

tasks.withType(Test) {
    executable = "${System.env.JAVA8_HOME}/bin/java"
}

compileJava{
    sourceCompatibility = 1.8
    targetCompatibility = 1.8
}

源文件编译成功,但是当它到达单元测试(用Spock编写)时,它会因以下错误而失败。

Caused by: java.lang.UnsupportedClassVersionError: org/model/SDA : Unsupported major.minor version 52.0

我确认SDA.class是使用JDK 8编译的。

javap -verbose SDA.class | findstr "major"
  major version: 52

为什么只有在单元测试中我才得到上述错误?这是否意味着在JDK 7上运行单元测试?

2 个答案:

答案 0 :(得分:0)

将此添加到您的gradle.properties:

org.gradle.java.home=/path/to/java8

或者,当您启动gradle时,可以将其指定为jvm参数:

gradle -Dorg.gradle.java.home=/path/to/java8 task1 task2

答案 1 :(得分:0)

所以,如果你真的陷入困境,你可以做些什么。它确实涉及覆盖一些Gradle内部 - 因此它可能不适用于除1.11之外的任何Gradle版本。可能还有意想不到的副作用。

import org.gradle.internal.Factory
import org.gradle.process.internal.WorkerProcessBuilder
import org.gradle.api.internal.tasks.compile.daemon.CompilerDaemonStarter

tasks.withType(GroovyCompile) {
    options.fork = true
    options.forkOptions.executable = "${System.env.JAVA8_HOME}/bin/javac"

    doFirst {
        def compilerFactory = compiler.compiler.compilerFactory
        def clientsManager = compilerFactory.compilerDaemonManager.clientsManager
        def oldDaemonStarter = clientsManager.compilerDaemonStarter
        if (!(oldDaemonStarter.workerFactory instanceof CustomWorkerProcessFactory)) {
            println "HACK, installing custom daemon worker"
            clientsManager.compilerDaemonStarter = new CompilerDaemonStarter(
                    new CustomWorkerProcessFactory(oldDaemonStarter.workerFactory),
                    oldDaemonStarter.startParameter)
        }
    }
}

class CustomWorkerProcessFactory implements Factory<WorkerProcessBuilder> {
    Factory<WorkerProcessBuilder> delegate

    CustomWorkerProcessFactory(Factory<WorkerProcessBuilder> delegate) {
        this.delegate = delegate
    }

    public WorkerProcessBuilder create() {
        def newWorker = delegate.create()
        newWorker.javaCommand.executable("${System.env.JAVA8_HOME}/bin/java")
        newWorker
    }
}