从Java 8升级到11,为什么弹簧测试组件扫描无法正确进行?

时间:2019-01-24 16:13:49

标签: java spring gradle junit java-module

我开始对我们的基础架构进行一些升级,更新一些库以使用Gradle 5.1(从4.2开始),Spring Boot 2(从1.5开始),Java 11(从8开始),然后以使用Java 11为目标。模块系统。

我已经进行了所有更新,然后我的测试在最后一步中失败了。看来,当我指示Gradle使用模块路径运行测试时,Spring并未拾取@Component对象,并且自动装配失败。

为清楚起见,使用Java 11和默认类路径时测试通过,但是一旦添加以下所示的compileTestJavatest gradle任务,测试将失败。 (这些任务基于gradle.org java 9 guide的示例)代码仍然可以编译(我已经克服了所有与模块相关的构建错误),当我遇到以下错误时,Spring上下文会尝试立起来。 / p>

当我使用Spring启用JPA存储库时,它确实找到了这些类(在同一项目的不同包中)并按预期方式创建了它们的单例bean。但是,当我针对需要测试的服务实例的服务运行测试时,它不会创建该bean。

所以显而易见的问题是,为什么我的测试不能再找到要创建的类了?

build.gradle (已修剪)

plugins {
    id 'java'
    id 'com.gradle.build-scan' version "2.1"
    id 'org.springframework.boot' version "2.1.2.RELEASE"
    id 'maven-publish'
}

//sourceCompatibility = '1.8'
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'

if (!hasProperty('mainClass')) {
    ext.mainClass = ''
}

jar {
    enabled = true
    baseName = "my-jar"

    // For embedded tomcat apps
    manifest.attributes provider: 'gradle'
}

compileJava {
    inputs.property("moduleName", "com.mypackage.academics")

    doFirst {
        options.compilerArgs = [
            '--module-path', classpath.asPath,
        ]
        classpath = files()  
    }
}

compileTestJava {
    inputs.property("moduleName", "com.mypackage.academics")
    doFirst {
        options.compilerArgs = [
            '--module-path', classpath.asPath, 
            '--add-modules', 'junit',  
            '--add-reads', "com.mypackage.academics=junit", 
            '--patch-module', "com.mypackage.academics=" + "src/test/resources:" + files(sourceSets.test.java.srcDirs).asPath, 
        ]
        classpath = files()
    }
}

test {
    inputs.property("moduleName", "com.mypackage.academics")
    doFirst {
        jvmArgs = [
            '--module-path', classpath.asPath, 
            '--add-modules', 'ALL-MODULE-PATH', 
            '--add-reads', "com.mypackage.academics=junit,spring.test,org.hamcrest", 
            '--patch-module', "com.mypackage.academics=" + "src/test/resources:" + files(sourceSets.test.java.outputDir).asPath, 
        ]
        classpath = files()
    }
}

module-info.java (已修剪)

module com.mypackage.academics {
    exports com.mypackage.academics.config;

    opens com.mypackage.academics.config to org.hibernate.orm.core, spring.core;

    requires spring.beans;
    requires spring.data.commons;
    requires spring.context;
    requires spring.core;
    requires spring.data.jpa;
    requires spring.tx;
}

错误:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.mypackage.academics.config.AcademicsConfigService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at spring.beans@5.1.4.RELEASE/org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1651)
    at spring.beans@5.1.4.RELEASE/org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1210)
    at spring.beans@5.1.4.RELEASE/org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1164)
    at spring.beans@5.1.4.RELEASE/org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:593)
    ... 52 more

1 个答案:

答案 0 :(得分:0)

据我了解,就Java 11而言,这是预期的行为。

此线程中讨论了该问题。 http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-July/054228.html

基本上,测试的运行方式是在模块路径上设置应用程序类,而将类路径用于测试类。