Maven Spring Boot插件:如何从另一个项目运行spring boot

时间:2018-05-29 02:20:32

标签: java maven spring-boot spring-boot-maven-plugin

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 failsafe插件)。

在父模块的集成测试期间,是否可以配置spring boot maven插件来启动/停止子模块?

我尝试了这样的事情没有成功

        <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>

哪个不起作用。

我还尝试在读取插件超类的源代码后添加“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,结果相同

2 个答案:

答案 0 :(得分:3)

我认为使用spring-boot-maven-plugin对其他模块进行集成测试是不可能的,因为start目标似乎无法为您提供方法从本地存储库或Maven反应器解析应用程序,这可能是你想要的。您尝试过的project配置属性并未设计为以这种方式覆盖。应仅使用插件目标docs中列出的属性配置插件执行。

相反,我认为你至少有两种可能的方法:

  1. 使用其他插件来控制服务器;或
  2. 直接从代码中的测试运行服务器。
  3. 选项1

    为此,我认为您需要一种方法可以复制您想要运行的服务器工件,以及一些更通用的方法来启动和停止它,例如cargo-maven2-pluginprocess-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依赖关系,然后在挂钩之前在JUnit中运行服务器的@SpringBootApplication类,或者你有什么,例如。

    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();
        }
    }
    

    这可能足以满足您的需求。

答案 1 :(得分:2)

RyanP的解决方案完全符合需求。

但是,我确实设法让它发挥作用,运气不好我想:)

  1. 它需要在TEST模块中重新添加运行应用程序所需的依赖项。 (在这种情况下,spring-boot.starter-web)

  2. 添加测试类,需要一个非常有趣的语法

  3. 到目前为止,优点是我可以在正在运行的服务器上运行测试,但仍然使用配置文件和服务的测试类来模拟一些服务。

    老实说,我仍然会尝试上面的两个解决方案,但仅仅是为了节目,这是我最终的工作

            <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>