Spring NoSuchBeanDefinitionException เมื่อเปลี่ยนเป็น JPMS (Java Platform Module System)
ฉันกำลังพยายามย้ายโครงการขนาดใหญ่ไปยัง JPMS (Java Platform Module System)
มันมีส่วนประกอบของสปริงที่ทำให้ฉันมีปัญหา ฉันได้สร้าง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 [email protected]/org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:643)
at [email protected]/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 Files \ 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 = ALL-UNNAMED --add-module = ALL-MODULE-PATH -Dfile.encoding = UTF-8 -p "C: \ dev \ source \ spring-jpms-test \ target \ class; 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- bean-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-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-anno tations-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 \ repository \ net \ bytebuddy \ byte-buddy \ 1.10.13 \ byte-buddy-1.10.13 โถ; C: \ Users \ Oscar Haglund.m2 \ repository \ 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 = ALL-UNNAMED org eclipse.jdt.internal.junit.runner.RemoteTestRunner -version 3 -port 55245 -testLoaderClass org.eclipse.jdt.internal.junit5.runner.JUnit5TestLoader -loaderpluginname org.eclipse.jdt.junit5.runtime -classemet .jpmstest.TestControllerTest
คำตอบ
ครั้งแรกของทั้งหมดใส่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;
}
แต่อย่างไรก็ตามสิ่งนี้แก้ได้เพียง "บางส่วน" เท่านั้นเนื่องจาก:
ยินดีต้อนรับสู่ความเป็นจริงที่ค่อนข้างหยาบของmodulesและspring(หรือเครื่องมือโดยทั่วไป) ได้ดูที่นี่ที่ผู้คนมีปัญหาเดียวกัน ทางออกเดียวที่ฉันพบคือทำ:
<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จะทำให้มันใช้งานได้