Spring 引导应用程序 class 在测试模块 (JPMS) 中不存在
Spring Boot Application class does not existed in the test module(JPMS)
我尝试使用Java 9+内置的JPMS(Java平台模块系统)来模块化Spring启动应用程序,检查the complete sample codes here。
在 IDEA 中,当 运行 测试时,它运行良好。
但是当我 运行 它通过根文件夹中的 mvn clean verify
时, greeting.application.test
将由于异常而失败“找不到包 com.example.greeting.application
和class GreetingApplication
".
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project greeting-application-test: Compilation failure: Compilation fai
lure:
[ERROR] /D:/hantsylabs/spring-puzzles/modular-jpms/greeting-application-test/src/main/java/com/example/greeting/application/test/GreetingApplicationTests.java:[3,40] package com.exampl
e.greeting.application does not exist
[ERROR] /D:/hantsylabs/spring-puzzles/modular-jpms/greeting-application-test/src/main/java/com/example/greeting/application/test/GreetingApplicationTests.java:[13,19] cannot find symbo
l
[ERROR] symbol: class GreetingApplication
模块-info.java中的greeting.application.test是这样的。
module greeting.application.test {
requires greeting.application;
requires spring.web;
requires spring.core;
requires spring.beans;
requires spring.context;
requires spring.boot;
requires spring.boot.autoconfigure;
requires spring.webflux;
requires spring.test;
requires spring.boot.test;
requires spring.boot.test.autoconfigure;
requires org.junit.jupiter;
requires org.junit.jupiter.api;
requires org.junit.jupiter.params;
requires org.junit.jupiter.engine;
requires org.junit.platform.commons;
requires org.assertj.core;
requires org.mockito.junit.jupiter;
requires transitive net.bytebuddy;
opens com.example.greeting.application.test to spring.core, org.junit.platform.commons;
}
问题不在于“测试”模块,而是试图访问您构建的应用程序的任何其他模块。
这是由于spring-boot-maven-plugin
用于repackage
对应于其java模块的maven模块greeting-application
引起的。
文档中的#Classifier部分进一步讲清楚了原因(我高亮显示):
By default, the repackage goal replaces the original artifact with the
repackaged one. That is a sane behavior for modules that represent an
application but if your module is used as a dependency of another
module, you need to provide a classifier for the repackaged one. The
reason for that is that application classes are packaged in
BOOT-INF/classes so that the dependent module cannot load a repackaged
jar’s classes.
因此,为了解决这个问题,您可以使用
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>exec</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
进一步引用文档并与配置更新相关:
此配置将生成两个工件:原始工件和重新打包目标生成的重新打包计数器部分。两者都会installed/deployed透明。
我尝试使用Java 9+内置的JPMS(Java平台模块系统)来模块化Spring启动应用程序,检查the complete sample codes here。
在 IDEA 中,当 运行 测试时,它运行良好。
但是当我 运行 它通过根文件夹中的 mvn clean verify
时, greeting.application.test
将由于异常而失败“找不到包 com.example.greeting.application
和class GreetingApplication
".
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project greeting-application-test: Compilation failure: Compilation fai
lure:
[ERROR] /D:/hantsylabs/spring-puzzles/modular-jpms/greeting-application-test/src/main/java/com/example/greeting/application/test/GreetingApplicationTests.java:[3,40] package com.exampl
e.greeting.application does not exist
[ERROR] /D:/hantsylabs/spring-puzzles/modular-jpms/greeting-application-test/src/main/java/com/example/greeting/application/test/GreetingApplicationTests.java:[13,19] cannot find symbo
l
[ERROR] symbol: class GreetingApplication
模块-info.java中的greeting.application.test是这样的。
module greeting.application.test {
requires greeting.application;
requires spring.web;
requires spring.core;
requires spring.beans;
requires spring.context;
requires spring.boot;
requires spring.boot.autoconfigure;
requires spring.webflux;
requires spring.test;
requires spring.boot.test;
requires spring.boot.test.autoconfigure;
requires org.junit.jupiter;
requires org.junit.jupiter.api;
requires org.junit.jupiter.params;
requires org.junit.jupiter.engine;
requires org.junit.platform.commons;
requires org.assertj.core;
requires org.mockito.junit.jupiter;
requires transitive net.bytebuddy;
opens com.example.greeting.application.test to spring.core, org.junit.platform.commons;
}
问题不在于“测试”模块,而是试图访问您构建的应用程序的任何其他模块。
这是由于spring-boot-maven-plugin
用于repackage
对应于其java模块的maven模块greeting-application
引起的。
文档中的#Classifier部分进一步讲清楚了原因(我高亮显示):
By default, the repackage goal replaces the original artifact with the repackaged one. That is a sane behavior for modules that represent an application but if your module is used as a dependency of another module, you need to provide a classifier for the repackaged one. The reason for that is that application classes are packaged in BOOT-INF/classes so that the dependent module cannot load a repackaged jar’s classes.
因此,为了解决这个问题,您可以使用
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>exec</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
进一步引用文档并与配置更新相关:
此配置将生成两个工件:原始工件和重新打包目标生成的重新打包计数器部分。两者都会installed/deployed透明。