Maven Spring Boot Plugin : 如何 运行 spring 从另一个项目启动
Maven Spring Boot Plugin : how to run spring boot from another project
https://docs.spring.io/spring-boot/docs/current/maven-plugin/usage.html
我有一个项目,有 2 个模块。
[Parent]
|-pom.xml
| [SpringBoot2App]
| |-pom.xml
| [test]
| |-pom.xml (start goal here!)
我想 运行 在另一个模块的单独项目中进行集成测试(maven 故障安全插件)。
在父模块的集成测试期间,是否可以将 spring boot maven 插件配置到 start/stop 子模块?
我尝试过类似的方法但没有成功
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.SimpleServiceApplication</mainClass>
<classesDirectory>../SpringBoot2App/target/classes</classesDirectory>
<folders>
<param>../SpringBoot2App/target/test-classes</param>
</folders>
</configuration>
<executions>
<execution>
<goals>
<goal>start</goal>
</goals>
<phase>pre-integration-test</phase>
</execution>
</executions>
</plugin>
这是行不通的。
看了插件的超级class源码后,我也试过加一个"project"参数
https://github.com/spring-projects/spring-boot/blob/master/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractRunMojo.java
<configuration>
<mainClass>com.SimpleServiceApplication</mainClass>
<project>${project.parent.collectedProjects[0]}</project>
</configuration>
如调试所示,这指的是正确的项目,但也不起作用。
请不要对 [0] 发表评论,我知道 [0] 不干净并且是一个需要直接了解父 pom 模块排序的耦合。
我在 org/springframework/boot/SpringApplication
上收到 java.lang.NoClassDefFoundError
我将 starter-web 项目添加到测试中 pom.xml,结果相同
我认为不可能 运行 使用 spring-boot-maven-plugin
对另一个模块进行集成测试,因为 start
目标似乎没有给你解决问题的方法来自本地存储库或 Maven 反应器的应用程序,这可能是您想要的。您尝试过的 project
配置 属性 并非旨在以这种方式覆盖。插件执行应仅使用插件目标 docs.
中列出的属性进行配置
相反,我认为您至少有两种可能的方法:
- 使用不同的插件来控制服务器;或
- 运行 服务器直接来自代码中的测试。
选项 1
为此,我认为您需要一种方法来复制您想要 运行 的服务器工件,以及一些更通用的启动和停止它的方法,例如 cargo-maven2-plugin or process-exec-maven-plugin.
只需在服务器工件构建中配置 repackage
目标:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludeDevtools>true</excludeDevtools>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
然后在集成测试模块中,您可以执行如下操作:
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-server-artifact</id>
<goals>
<goal>copy</goal>
</goals>
<phase>pre-integration-test</phase>
<configuration>
<artifactItems>
<artifactItem>
<groupId>${project.groupId}</groupId>
<artifactId>SpringBoot2App</artifactId>
<version>${project.version}</version>
<classifier>jar</classifier>
<outputDirectory>${project.build.directory}</outputDirectory>
<destFileName>app.jar</destFileName>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.bazaarvoice.maven.plugins</groupId>
<artifactId>process-exec-maven-plugin</artifactId>
<version>0.7</version>
<executions>
<execution>
<id>start-server</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
</goals>
<configuration>
<name>run-server</name>
<waitForInterrupt>false</waitForInterrupt>
<healthcheckUrl>http://localhost:8080</healthcheckUrl>
<arguments>
<argument>java</argument>
<argument>-jar</argument>
<argument>${project.build.directory}/app.jar</argument>
</arguments>
</configuration>
</execution>
<execution>
<id>stop-server</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop-all</goal>
</goals>
</execution>
</executions>
</plugin>
选项 2
只需在测试工件中声明对服务器工件的正常 Maven 依赖关系,然后 运行 服务器的 @SpringBootApplication
class 在 JUnit 中挂钩之前或您有什么,例如
private static ConfigurableApplicationContext context;
@BeforeClass
public static void setUp() {
context = new SpringApplicationBuilder(SimpleServiceApplication.class).run();
}
@AfterClass
public static void tearDown() {
if (context != null) {
context.close();
}
}
这可能足以满足您的需求。
RyanP 的解决方案完全符合需求。
但是,我确实成功了,我想运气不好 :)
它需要在 TEST 模块中重新添加依赖项,运行 应用程序需要这些依赖项。 (在本例中为 spring-boot.starter-web)
添加测试 类,需要非常有趣的语法
到目前为止,优点是我可以 运行 在 运行ning 服务器上进行测试,但仍然使用配置文件和服务的测试 -类 模拟一些服务.
老实说,我仍然会尝试上面的两种解决方案,但只是为了展示,这就是我最终得到的结果
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>start-mocked-app</id>
<configuration>
<arguments>
<argument>--server.port=${tomcat.http.port}</argument>
</arguments>
<mainClass>xxx.TestApplication</mainClass>
<classesDirectory>../${api-module}/target/classes</classesDirectory>
<folders>
<!-- wow! notice the weird "./" rather than the expected "../" -->
<folder>./${api-module}/target/test-classes</folder>
</folders>
<profiles>
<profile>MOCKED</profile>
</profiles>
</configuration>
<goals>
<goal>start</goal>
</goals>
<phase>pre-integration-test</phase>
</execution>
<execution>
<id>stop</id>
<goals>
<goal>stop</goal>
</goals>
<phase>post-integration-test</phase>
</execution>
</executions>
</plugin>
还有...
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<scope>provided</scope>
</dependency>
<!-- ... -->
</dependencies>
https://docs.spring.io/spring-boot/docs/current/maven-plugin/usage.html
我有一个项目,有 2 个模块。
[Parent]
|-pom.xml
| [SpringBoot2App]
| |-pom.xml
| [test]
| |-pom.xml (start goal here!)
我想 运行 在另一个模块的单独项目中进行集成测试(maven 故障安全插件)。
在父模块的集成测试期间,是否可以将 spring boot maven 插件配置到 start/stop 子模块?
我尝试过类似的方法但没有成功
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.SimpleServiceApplication</mainClass>
<classesDirectory>../SpringBoot2App/target/classes</classesDirectory>
<folders>
<param>../SpringBoot2App/target/test-classes</param>
</folders>
</configuration>
<executions>
<execution>
<goals>
<goal>start</goal>
</goals>
<phase>pre-integration-test</phase>
</execution>
</executions>
</plugin>
这是行不通的。
看了插件的超级class源码后,我也试过加一个"project"参数 https://github.com/spring-projects/spring-boot/blob/master/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractRunMojo.java
<configuration>
<mainClass>com.SimpleServiceApplication</mainClass>
<project>${project.parent.collectedProjects[0]}</project>
</configuration>
如调试所示,这指的是正确的项目,但也不起作用。
请不要对 [0] 发表评论,我知道 [0] 不干净并且是一个需要直接了解父 pom 模块排序的耦合。
我在 org/springframework/boot/SpringApplication
上收到 java.lang.NoClassDefFoundError我将 starter-web 项目添加到测试中 pom.xml,结果相同
我认为不可能 运行 使用 spring-boot-maven-plugin
对另一个模块进行集成测试,因为 start
目标似乎没有给你解决问题的方法来自本地存储库或 Maven 反应器的应用程序,这可能是您想要的。您尝试过的 project
配置 属性 并非旨在以这种方式覆盖。插件执行应仅使用插件目标 docs.
相反,我认为您至少有两种可能的方法:
- 使用不同的插件来控制服务器;或
- 运行 服务器直接来自代码中的测试。
选项 1
为此,我认为您需要一种方法来复制您想要 运行 的服务器工件,以及一些更通用的启动和停止它的方法,例如 cargo-maven2-plugin or process-exec-maven-plugin.
只需在服务器工件构建中配置 repackage
目标:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludeDevtools>true</excludeDevtools>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
然后在集成测试模块中,您可以执行如下操作:
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-server-artifact</id>
<goals>
<goal>copy</goal>
</goals>
<phase>pre-integration-test</phase>
<configuration>
<artifactItems>
<artifactItem>
<groupId>${project.groupId}</groupId>
<artifactId>SpringBoot2App</artifactId>
<version>${project.version}</version>
<classifier>jar</classifier>
<outputDirectory>${project.build.directory}</outputDirectory>
<destFileName>app.jar</destFileName>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.bazaarvoice.maven.plugins</groupId>
<artifactId>process-exec-maven-plugin</artifactId>
<version>0.7</version>
<executions>
<execution>
<id>start-server</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
</goals>
<configuration>
<name>run-server</name>
<waitForInterrupt>false</waitForInterrupt>
<healthcheckUrl>http://localhost:8080</healthcheckUrl>
<arguments>
<argument>java</argument>
<argument>-jar</argument>
<argument>${project.build.directory}/app.jar</argument>
</arguments>
</configuration>
</execution>
<execution>
<id>stop-server</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop-all</goal>
</goals>
</execution>
</executions>
</plugin>
选项 2
只需在测试工件中声明对服务器工件的正常 Maven 依赖关系,然后 运行 服务器的 @SpringBootApplication
class 在 JUnit 中挂钩之前或您有什么,例如
private static ConfigurableApplicationContext context;
@BeforeClass
public static void setUp() {
context = new SpringApplicationBuilder(SimpleServiceApplication.class).run();
}
@AfterClass
public static void tearDown() {
if (context != null) {
context.close();
}
}
这可能足以满足您的需求。
RyanP 的解决方案完全符合需求。
但是,我确实成功了,我想运气不好 :)
它需要在 TEST 模块中重新添加依赖项,运行 应用程序需要这些依赖项。 (在本例中为 spring-boot.starter-web)
添加测试 类,需要非常有趣的语法
到目前为止,优点是我可以 运行 在 运行ning 服务器上进行测试,但仍然使用配置文件和服务的测试 -类 模拟一些服务.
老实说,我仍然会尝试上面的两种解决方案,但只是为了展示,这就是我最终得到的结果
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>start-mocked-app</id>
<configuration>
<arguments>
<argument>--server.port=${tomcat.http.port}</argument>
</arguments>
<mainClass>xxx.TestApplication</mainClass>
<classesDirectory>../${api-module}/target/classes</classesDirectory>
<folders>
<!-- wow! notice the weird "./" rather than the expected "../" -->
<folder>./${api-module}/target/test-classes</folder>
</folders>
<profiles>
<profile>MOCKED</profile>
</profiles>
</configuration>
<goals>
<goal>start</goal>
</goals>
<phase>pre-integration-test</phase>
</execution>
<execution>
<id>stop</id>
<goals>
<goal>stop</goal>
</goals>
<phase>post-integration-test</phase>
</execution>
</executions>
</plugin>
还有...
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<scope>provided</scope>
</dependency>
<!-- ... -->
</dependencies>