Spring NoSuchBeanDefinitionException lors du passage à JPMS (Java Platform Module System)
J'essaye de migrer un grand projet vers JPMS (Java Platform Module System).
Il contient des composants Spring qui me posent quelques problèmes. J'ai créé un dépôt de test pour démontrer le problème. Lorsque je supprime le fichier module-info.java, cela fonctionne très bien, comme le montre le test dans TestControllerTest.java . Cependant, si j'ajoute le module-info.java, il cesse de fonctionner avec l'exception suivante:
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 …
La trace de pile semble indiquer que le ApplicationContextest incapable de trouver l' @Autowiredimplémentation. J'ai ouvert tout le module pour une réflexion approfondie. Ma supposition très inculte est que cela pourrait être lié au classpath par rapport au modulepath, mais je ne sais pas quoi faire à ce sujet.
Le fichier module-info.java est le suivant:
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;
}
Voici la ligne de commande utilisée par Eclipse pour exécuter le test (comme demandé):
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-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: \ Utilisateurs \ 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 \ fastxml \ jackson \ core \ jackson-databind \ 2.9.5 \ jackson-databind-2.9.5.jar; C : \ Utilisateurs \ Oscar Haglund.m2 \ repository \ com \ Fastxml \ jackson \ core \ jackson-annotations \ 2.9.0 \ jackson-anno tations-2.9.0.jar; C: \ Users \ Oscar Haglund.m2 \ repository \ com \ fastxml \ 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. jar; 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 \ référentiel \ 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. .jpmstest.TestControllerTest
Réponses
Tout d'abord, mettez le module-info.javadedans src/main/java, pas dedans src/test/java. Aussi je l'ai légèrement changé en:
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;
}
Mais de toute façon, cela ne résout que "partiellement" parce que:
Bienvenue dans une réalité assez grossière de moduleset spring(ou des outils en général). Jetez un œil ici, où les gens ont les mêmes problèmes . La seule solution viable que j'ai trouvée est de faire:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
<configuration>
<useModulePath>false</useModulePath>
</configuration>
</plugin>
Cela fonctionne avec mvn clean install(et junit5), je n'ai pas suffisamment essayé ou joué avec intellijpour le faire fonctionner.