java - 从Java 8升级到11,为什么spring测试组件无法正常扫描?

标签 java spring gradle junit java-module

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

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

需要明确的是,使用 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 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

最佳答案

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

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

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

关于java - 从Java 8升级到11,为什么spring测试组件无法正常扫描?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54350953/

相关文章:

intellij-idea - 在 Gradle 中设置 IntelliJ 编译器参数

java - 有没有办法告诉 Gradle 在生成的 Javadoc 中包含依赖项 Javadoc?

java - 将嵌入的 JSON 字符串反序列化为类型化对象

java - 如何使依赖注入(inject)对组件起作用

部署在 STS 中的 Spring Boot 应用程序运行良好,但在 IntelliJ Idea 中则不行

java - Spring 3.0 的 Google App Engine 实体管理器配置

java - 使用 restclient 或 postman 发送 gzip 数据

java - 我想在运行时在 Eclipse RCP 应用程序中重新加载插件

Java InputMismatchException 与 Scanner 循环

android - 使用 API 28 和 "androidx.appcompat"库项目表示找不到 "AppCompatActivity"符号