从Java 8升级到11,为什么弹簧测试组件不能正常扫描?

问题描述 投票:0回答:1

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

我已经完成了所有更新,然后我的测试在最后一步中失败了。看来,当我指示Gradle使用module-path运行测试时,Spring没有拿起我的@Component对象,我的自动装配失败了。

要清楚,测试在使用Java 11和默认类路径时通过,但是一旦我添加了如下所示的compileTestJavatest gradle任务就失败了。 (这些任务基于gradle.org java 9 guide上的示例)代码仍然编译(我已经超过了所有与模块相关的构建错误),当我收到下面的错误时,Spring上下文会尝试站起来。

当我使用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 [email protected]/org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1651)
    at [email protected]/org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1210)
    at [email protected]/org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1164)
    at [email protected]/org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:593)
    ... 52 more
java spring gradle junit java-module
1个回答
0
投票

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

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

基本上,运行测试的方式在模块路径上设置应用程序类,同时使用测试类的类路径。

© www.soinside.com 2019 - 2024. All rights reserved.