切换到JPMS(Java平台模块系统)时出现Spring NoSuchBeanDefinitionException

时间:2020-10-02 14:20:13

标签: java spring java-module java-platform-module-system

我正在尝试将大型项目迁移到JPMS(Java平台模块系统)。

它包含一些Spring组件,这些组件给我带来了一些麻烦。 我创建了一个test repo来演示此问题。当我删除module-info.java文件时,它工作正常,如TestControllerTest.java中的测试所示。但是,如果我添加module-info.java,它将停止工作并出现以下异常:

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'RESTConfiguration': Unsatisfied dependency expressed through field 'fooAuthenticationProvider'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.spacemetric.spring.jpmstest.auth.FooAuthenticationProvider' 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.2.6.RELEASE/org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:643)
at spring.beans@5.2.6.RELEASE/org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:130)
at … 

堆栈跟踪似乎表明ApplicationContext无法找到@Autowired实现。我打开了整个模块以进行深层思考。我对此没有高度的猜测,这可能与classpath和modulepath有关,但我对此无所适从。

module-info.java文件如下:

open module com.spacemetric.spring.jpmstest {       
    requires spring.core;
    requires spring.context;
    requires spring.beans;
    requires spring.security.config;
    requires spring.security.web;
    requires spring.webmvc;
    requires spring.security.core;
    requires javax.servlet.api;
    requires spring.web;
}

以下是Eclipse用于运行测试的命令行(根据要求):

C:\ Program 文件\ Java \ java-11-openjdk-11.0.7.10-1.windows.redhat.x86_64 \ bin \ javaw.exe -ea --add-opens com.spacemetric.spring.jpmstest / com.spacemetric.spring.jpmstest =全部取消命名 --add-modules = ALL-MODULE-PATH -Dfile.encoding = UTF-8 -p“ C:\ dev \ source \ spring-jpms-test \ target \ classes; C:\ Users \ Oscar Haglund.m2 \ repository \ org \ springframework \ spring-core \ 5.2.6.RELEASE \ spring-core-5.2.6.RELEASE.jar; C:\ Users \ Oscar Haglund.m2 \ repository \ org \ springframework \ security \ spring-security-web \ 5.3.2.RELEASE \ spring-security-web-5.3.2.RELEASE.jar; C:\ Users \ Oscar Haglund.m2 \ repository \ org \ springframework \ security \ spring-security-core \ 5.3.2.RELEASE \ spring-security-core-5.3.2.RELEASE.jar; C:\ Users \ Oscar Haglund.m2 \ repository \ org \ springframework \ spring-beans \ 5.2.6.RELEASE \ spring-beans-5.2.6.RELEASE.jar; C:\ Users \ Oscar Haglund.m2 \ repository \ org \ springframework \ spring-context \ 5.2.6.RELEASE \ spring-context-5.2.6.RELEASE.jar; C:\ Users \ Oscar Haglund.m2 \ repository \ org \ springframework \ spring-work web \ 5.2.6.RELEASE \ spring-web-5.2.6.RELEASE.jar; C:\ Users \ Oscar Haglund.m2 \ repository \ org \ springframework \ security \ spring-security-config \ 5.3.2.RELEASE \ spring-security-config-5.3.2.RELEASE.jar; C:\ Users \ Oscar Haglund.m2 \ repository \ org \ springframework \ spring-webmvc \ 5.2.6.RELEASE \ spring-webmvc-5.2.6.RELEASE.jar; C:\ Users \ Oscar Haglund.m2 \ repository \ javax \ servlet \ javax.servlet-api \ 3.1.0 \ javax.servlet-api-3.1.0.jar“ -classpath“ C:\ Users \ Oscar Haglund.m2 \ repository \ org \ springframework \ spring-jcl \ 5.2.6.RELEASE \ spring-jcl-5.2.6.RELEASE.jar; C:\ Users \ Oscar Haglund.m2 \ repository \ org \ springframework \ spring-aop \ 5.2.6.RELEASE \ spring-aop-5.2.6.RELEASE.jar; C:\ Users \ Oscar Haglund.m2 \ repository \ org \ springframework \ spring-expression \ 5.2.6.RELEASE \ spring-expression-5.2.6.RELEASE.jar; C:\ Users \ Oscar Haglund.m2 \ repository \ org \ junit \ jupiter \ junit-jupiter-engine \ 5.7.0 \ junit-jupiter-engine-5.7.0.jar; C:\ Users \ Oscar Haglund.m2 \ repository \ org \ apiguardian \ apiguardian-api \ 1.1.0 \ apiguardian-api-1.1.0.jar; C:\ Users \ Oscar Haglund.m2 \ repository \ org \ junit \ platform \ junit-platform-engine \ 1.7.0 \ junit-platform-engine-1.7.0.jar; C:\ Users \ Oscar Haglund.m2 \ repository \ org \ opentest4j \ opentest4j \ 1.2.0 \ opentest4j-1.2.0.jar; C:\ Users \ Oscar Haglund.m2 \ repository \ org \ junit \ platform \ junit-platform-commons \ 1.7.0 \ junit-platform-commons-1.7.0.jar; C:\ Users \ Oscar Haglund.m2 \ repository \ org \ junit \ jupiter \ junit-jupiter-api \ 5.7.0 \ junit-jupiter-api-5.7.0.jar; C:\ Users \ Oscar Haglund.m2 \ repository \ org \ springframework \ spring-test \ 5.2.6.RELEASE \ spring-test-5.2.6.RELEASE.jar; C:\ Users \ Oscar Haglund.m2 \ repository \ org \ springframework \ restdocs \ spring-restdocs-mockmvc \ 2.0.5.RELEASE \ spring-restdocs-mockmvc-2.0.5.RELEASE.jar; C:\ Users \ Oscar Haglund.m2 \ repository \ org \ springframework \ restdocs \ spring-restdocs-core \ 2.0.5.RELEASE \ spring-restdocs-core-2.0.5.RELEASE.jar; C:\ Users \ Oscar Haglund.m2 \ repository \ com \ fasterxml \ jackson \ core \ jackson-databind \ 2.9.5 \ jackson-databind-2.9.5.jar; C:\ Users \ Oscar Haglund.m2 \ repository \ com \ fasterxml \ jackson \ core \ jackson-annotations \ 2.9.0 \ jackson-annotations-2.9.0.jar; C:\ Users \ Oscar Haglund.m2 \ repository \ com \ fasterxml \ jackson \ core \ jackson-core \ 2.9.5 \ jackson-core-2.9.5.jar; C:\ Users \ Oscar Haglund.m2 \ repository \ org \ mockito \ mockito-junit-jupiter \ 3.5.10 \ mockito-junit-jupiter-3.5.10.jar; C:\ Users \ Oscar Haglund.m2 \ repository \ org \ mockito \ mockito-core \ 3.5.10 \ mockito-core-3.5.10.jar; C:\ Users \ Oscar Haglund.m2 \存储库\ net \ bytebuddy \ byte-buddy \ 1.10.13 \ byte-buddy-1.10.13.jar; C:\ Users \ Oscar Haglund.m2 \存储库\ net \ bytebuddy \ byte-buddy-agent \ 1.10.13 \ byte-buddy-agent-1.10.13.jar; C:\ Users \ Oscar Haglund.m2 \ repository \ org \ objenesis \ objenesis \ 3.1 \ objenesis-3.1.jar; C:\ Users \ Oscar Haglund.m2 \ repository \ org \ junit \ platform \ junit-platform-launcher \ 1.7.0 \ junit-platform-launcher-1.7.0.jar; C:\ dev \ eclipse \ configuration \ org.eclipse.osgi \ 259 \ 0.cp; C:\ dev \ eclipse \ configuration \ org.eclipse.osgi \ 257 \ 0.cp“ --patch-module“ com.spacemetric.spring.jpmstest = C:\ dev \ source \ spring-jpms-test \ target \ test-classes” --add-reads com.spacemetric.spring.jpmstest =全部取消命名org.eclipse.jdt.internal.junit.runner.RemoteTestRunner-版本3 端口55245 -testLoaderClass org.eclipse.jdt.internal.junit5.runner.JUnit5TestLoader -loaderpluginname org.eclipse.jdt.junit5.runtime -classNames com.spacemetric.spring.jpmstest.TestControllerTest

1 个答案:

答案 0 :(得分:1)

首先将module-info.java放在src/main/java中,而不要放在src/test/java中。另外我将其略微更改为:

module spring.jpms.test {
   requires spring.core;
   requires spring.context;
   requires spring.beans;
   requires spring.security.config;
   requires spring.security.web;
   requires spring.webmvc;
   requires spring.security.core;
   requires javax.servlet.api;
   requires spring.web;

   opens com.spacemetric.spring.jpmstest;

}

但是无论如何,这只能“部分解决”,因为:

欢迎来到modulesspring(或一般工具)的粗略现实。看看here, where people have the same problems。我发现唯一可行的解​​决方案是:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>3.0.0-M5</version>
    <configuration>
        <useModulePath>false</useModulePath>
    </configuration>
</plugin>

此功能可与mvn clean install(和junit5)一起使用,我还没有尝试或充分发挥intellij来使其正常工作。