1. 概要

Apache Maven は、広く使用されているプロジェクト依存関係管理ツールおよびプロジェクト構築ツールです。

過去数年間で、 Spring Boot は、アプリケーションを構築するための非常に人気のあるフレームワークになりました。 ApacheMavenでSpringBootサポートを提供するSpringBootMavenプラグインもあります。

Mavenを使用してアプリケーションをJARまたはWARアーティファクトにパッケージ化する場合は、 mvnpackageを使用できます。 ただし、Spring BootMavenプラグインにはrepackage ゴールが付属しており、mvnコマンドでも呼び出されます。

2つのmvnコマンドが混乱する場合があります。 このチュートリアルでは、mvnパッケージspring -boot:repackageの違いについて説明します。

2. SpringBootアプリケーションの例

まず、例として簡単なSpring Bootアプリケーションを作成します。

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

アプリケーションが稼働しているかどうかを確認するために、簡単なRESTエンドポイントを作成しましょう。

@RestController
public class DemoRestController {
    @GetMapping(value = "/welcome")
    public ResponseEntity welcomeEndpoint() {
        return ResponseEntity.ok("Welcome to Baeldung Spring Boot Demo!");
    }
}

3. Mavenのパッケージの目標

Spring Bootアプリケーションを構築するには、spring-boot-starter-web依存関係のみが必要です。

<artifactId>spring-boot-artifacts-2</artifactId>
<packaging>jar</packaging>
...
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
...

Mavenのパッケージ目標は、コンパイルされたコードを取得し、配布可能な形式(この場合はJAR形式)でパッケージ化します。

$ mvn package
[INFO] Scanning for projects...
[INFO] ------< com.baeldung.spring-boot-modules:spring-boot-artifacts-2 >------
[INFO] Building spring-boot-artifacts-2 1.0.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
 ... 
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ spring-boot-artifacts-2 ---
[INFO] Building jar: /home/kent ... /target/spring-boot-artifacts-2.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
 ...

mvn package コマンドを実行すると、ビルドされたJARファイルspring-boot-artifacts-2.jartargetディレクトリにあります。 作成したJARファイルの内容を確認しましょう

$ jar tf target/spring-boot-artifacts-2.jar
META-INF/
META-INF/MANIFEST.MF
com/
com/baeldung/
com/baeldung/demo/
application.yml
com/baeldung/demo/DemoApplication.class
com/baeldung/demo/DemoRestController.class
META-INF/maven/...

上記の出力でわかるように、 mvn packageコマンドによって作成されたJARファイルには、プロジェクトのソースからのリソースとコンパイルされたJavaクラスのみが含まれています。

このJARファイルを別のプロジェクトの依存関係として使用できます。 ただし、Spring Bootアプリケーションであっても、 java -jarJAR_FILEを使用してJARファイルを実行することはできません。 これは、実行時の依存関係がバンドルされていないためです。 たとえば、Webコンテキストを開始するためのサーブレットコンテナがありません。

単純なjava-jarコマンドを使用してSpringBootアプリケーションを起動するには、 fatJARをビルドする必要があります。 SpringBootMavenプラグインはそれを支援してくれます。

4. Spring BootMavenプラグインの再パッケージ目標

それでは、 spring -boot:repackageの機能を理解しましょう。

4.1. SpringBootMavenプラグインの追加

repackage ゴールを実行するには、SpringBootMavenプラグインをpom.xmlに追加する必要があります。

<build>
    <finalName>${project.artifactId}</finalName>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

4.2. spring -boot:repackage目標の実行

それでは、以前に作成したJARファイルをクリーンアップして、 spring -boot:repackageを試してみましょう。

$ mvn clean spring-boot:repackage     
 ...
[INFO] --- spring-boot-maven-plugin:2.3.3.RELEASE:repackage (default-cli) @ spring-boot-artifacts-2 ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
...
[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.3.3.RELEASE:repackage (default-cli) 
on project spring-boot-artifacts-2: Execution default-cli of goal 
org.springframework.boot:spring-boot-maven-plugin:2.3.3.RELEASE:repackage failed: Source file must not be null -> [Help 1]
...

おっと、それは動作しません。 それの訳は spring-boot:repackageゴールは、既存のJARまたはWARアーカイブをソースとして取得し、プロジェクトクラスとともに最終アーティファクト内のすべてのプロジェクトランタイム依存関係を再パッケージ化します。 このように、再パッケージ化されたアーティファクトは、コマンドラインjava-jarJAR_FILE.jarを使用して実行可能です。

したがって、 spring-boot:repackage の目標を実行する前に、まずJARファイルをビルドする必要があります。

$ mvn clean package spring-boot:repackage
 ...
[INFO] Building spring-boot-artifacts-2 1.0.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
 ...
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ spring-boot-artifacts-2 ---
[INFO] Building jar: /home/kent/.../target/spring-boot-artifacts-2.jar
[INFO] 
[INFO] --- spring-boot-maven-plugin:2.3.3.RELEASE:repackage (default-cli) @ spring-boot-artifacts-2 ---
[INFO] Replacing main artifact with repackaged archive
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
 ...

4.3. 再パッケージ化されたJARファイルの内容

ここで、 target ディレクトリを確認すると、再パッケージ化されたJARファイルと元のJARファイルが表示されます。

$ ls -1 target/*jar*
target/spring-boot-artifacts-2.jar
target/spring-boot-artifacts-2.jar.original

再パッケージ化されたJARファイルの内容を確認しましょう。

$ jar tf target/spring-boot-artifacts-2.jar 
META-INF/
META-INF/MANIFEST.MF
 ...
org/springframework/boot/loader/JarLauncher.class
 ...
BOOT-INF/classes/com/baeldung/demo/
BOOT-INF/classes/application.yml
BOOT-INF/classes/com/baeldung/demo/DemoApplication.class
BOOT-INF/classes/com/baeldung/demo/DemoRestController.class
META-INF/maven/com.baeldung.spring-boot-modules/spring-boot-artifacts-2/pom.xml
META-INF/maven/com.baeldung.spring-boot-modules/spring-boot-artifacts-2/pom.properties
BOOT-INF/lib/
BOOT-INF/lib/spring-boot-starter-web-2.3.3.RELEASE.jar
...
BOOT-INF/lib/spring-boot-starter-tomcat-2.3.3.RELEASE.jar
BOOT-INF/lib/tomcat-embed-core-9.0.37.jar
BOOT-INF/lib/jakarta.el-3.0.3.jar
BOOT-INF/lib/tomcat-embed-websocket-9.0.37.jar
BOOT-INF/lib/spring-web-5.2.8.RELEASE.jar
...
BOOT-INF/lib/httpclient-4.5.12.jar
...

上記の出力を確認すると、 mvnpackageコマンドで作成されたJARファイルよりもはるかに長くなっています。

ここで、再パッケージ化されたJARファイルには、プロジェクトからコンパイルされたJavaクラスだけでなく、SpringBootアプリケーションを起動するために必要なすべてのランタイムライブラリも含まれています。 たとえば、埋め込まれたtomcatライブラリはBOOT-INF/libディレクトリにパッケージ化されています。

次に、アプリケーションを起動して、機能するかどうかを確認しましょう。

$ java -jar target/spring-boot-artifacts-2.jar 
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/

2020-12-22 23:36:32.704  INFO 115154 [main] com.baeldung.demo.DemoApplication      : Starting DemoApplication on YK-Arch with PID 11515...
...
2020-12-22 23:36:34.070  INFO 115154 [main] o.s.b.w.embedded.tomcat.TomcatWebServer: Tomcat started on port(s): 8080 (http) ...
2020-12-22 23:36:34.078  INFO 115154 [main] com.baeldung.demo.DemoApplication      : Started DemoApplication in 1.766 seconds ...

SpringBootアプリケーションが稼働しています。 それでは、 /welcomeエンドポイントを呼び出して確認しましょう。

$ curl http://localhost:8080/welcome
Welcome to Baeldung Spring Boot Demo!

すごい! 期待どおりの反応が得られました。 アプリケーションは正常に実行されています。

4.4. springの実行-Mavenのパッケージライフサイクル中のboot:repackage目標

pom.xmlでSpringBootMavenプラグインを構成して、Mavenライフサイクルのpackageフェーズでアーティファクトを再パッケージ化できます。 つまり、 mvnパッケージを実行すると、 spring-boot:repackageが自動的に実行されます。

構成は非常に簡単です。 repackageゴールをexecution要素に追加するだけです。

<build>
    <finalName>${project.artifactId}</finalName>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

それでは、 mvn cleanpackageをもう一度実行してみましょう。

$ mvn clean package
 ...
[INFO] Building spring-boot-artifacts-2 1.0.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
...
[INFO] --- spring-boot-maven-plugin:2.3.3.RELEASE:repackage (default) @ spring-boot-artifacts-2 ---
[INFO] Replacing main artifact with repackaged archive
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
 ...

出力は、再パッケージ化の目標が実行されたことを示しています。 ファイルシステムを確認すると、再パッケージ化されたJARファイルが作成されていることがわかります。

$ ls -lh target/*jar*
-rw-r--r-- 1 kent kent  29M Dec 22 23:56 target/spring-boot-artifacts-2.jar
-rw-r--r-- 1 kent kent 3.6K Dec 22 23:56 target/spring-boot-artifacts-2.jar.original

5. 結論

この記事では、 mvnpackagespring-boot:repackageの違いについて説明しました。

また、Mavenライフサイクルのpackageフェーズでspring-boot:repackageを実行する方法も学びました。

いつものように、この記事のコードはすべてGitHub利用できます。