web-dev-qa-db-ja.com

Maven Spring Bootプラグイン:別のプロジェクトからSpringBootを実行する方法

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プラグインを構成することは可能ですか?

私は成功せずにこのようなことを試みました

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

これは機能しません。

また、プラグインのスーパークラスのソースを読み取った後、「プロジェクト」パラメーターを追加しようとしました 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に追加しましたが、同じ結果です

7
Filip

startの目標では、ローカルリポジトリまたはMavenからアプリケーションを解決する手段が得られないようであるため、spring-boot-maven-pluginを使用して別のモジュールに対して統合テストを実行することはできないと思います。おそらくあなたが望むものであるリアクター。試したproject構成プロパティは、そのようにオーバーライドされるようには設計されていません。プラグインの実行は、プラグインの目標 docs にリストされているプロパティのみを使用して構成する必要があります。

代わりに、少なくとも2つの可能なアプローチがあると思います。

  1. サーバーを制御するために別のプラグインを使用します。または
  2. コード内のテストから直接サーバーを実行します。

オプション1

このためには、実行したいサーバーアーティファクトをコピーするアプローチと、それを開始および停止するためのもう少し一般的なもの( cargo-maven2-plugin または ))が必要だと思います。 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依存関係を宣言し、フックの前に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();
    }
}

これはあなたのニーズには十分かもしれません。

4
ryanp

RyanPのソリューションは、ニーズに完全に適合します。

しかし、運が悪かったので、なんとか機能させることができました:)

  1. アプリの実行に必要な依存関係をTESTモジュールに再度追加する必要がありました。 (この場合はspring-boot.starter-web)

  2. テストクラスを追加するには、非常に興味深い構文が必要でした

これまでのところ、実行中のサーバーでテストを実行できるという利点がありますが、プロファイルとサービスのテストクラスを使用していくつかのサービスをモックします。

正直なところ、私はまだ上記の両方の解決策を試しますが、ショーのためだけに、これが私が最終的に機能したものです

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