Mavenと実行可能War / Jarを使用したSpring Bootアプリの実行

1. 前書き

このチュートリアルでは、_mvn spring-boot:run_コマンドを使用してSpring Boot Webアプリケーションを起動することと、_java -jar_コマンドを使用してjar / warパッケージにコンパイルした後に実行することの違いについて説明します。
ここで、Spring Bootの_repackage_ゴールの設定に既に精通していると仮定しましょう。 このトピックの詳細については、https://www.baeldung.com/deployable-fat-jar-spring-boot [Spring BootでFat Jarアプリを作成]をご覧ください。

2. Spring Boot Mavenプラグイン

  • Spring Bootアプリケーションを作成する場合、https://docs.spring.io/spring-boot/docs/current/maven-plugin/ [Spring Boot Mavenプラグイン]は、コードをビルド、テスト、およびパッケージ化するための推奨ツールです。*

    このプラグインには、次のような多くの便利な機能が付属しています。
  • 正しい依存関係バージョンを解決します

  • すべての依存関係(組み込みアプリケーションを含む)をパッケージ化できます
    サーバー(必要に応じて)単一の実行可能なファットjar / warで、以下も実行します。

  • クラスパスの設定を管理してください
    java -jar_コマンドの-cp_オプション

  • カスタム_ClassLoader_を実装して、すべての外部
    パッケージ内にネストされたjarライブラリ

  • _main()_メソッドを自動的に見つけて、
    マニフェスト。したがって、_java -jar_コマンドでメインクラスを指定する必要はありません。

3. Mavenを使用したコードの展開形式での実行

Webアプリケーションで作業しているとき、Spring Boot Mavenプラグインの別の非常に興味深い機能を利用できます。
Tomcatを使用してコードを実行することをプラグインに知らせるために必要な依存関係は1つだけです。
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
これで、プロジェクトのルートフォルダで_mvn spring-boot:run_コマンドを実行すると、プラグインはpom設定を読み取り、Webアプリケーションコンテナが必要であることを理解します。
  • _mvn spring-boot:run_コマンドを実行すると、Apache Tomcatのダウンロードがトリガーされ、Tomcatの起動が初期化されます。*

    試してみよう:
$ mvn spring-boot:run
...
...
[INFO] --------------------< com.baeldung:spring-boot-ops >--------------------
[INFO] Building spring-boot-ops 0.0.1-SNAPSHOT
[INFO] --------------------------------[ war ]---------------------------------
[INFO]
[INFO] >>> spring-boot-maven-plugin:2.1.3.RELEASE:run (default-cli) > test-compile @ spring-boot-ops >>>
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/tomcat/embed/tomcat-embed-core/9.0.16/tomcat-embed-core-9.0.16.pom
Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/tomcat/embed/tomcat-embed-core/9.0.16/tomcat-embed-core-9.0.16.pom (1.8 kB at 2.8 kB/s)
...
...
[INFO] --- spring-boot-maven-plugin:2.1.3.RELEASE:run (default-cli) @ spring-boot-ops ---
...
...
11:33:36.648 [main] INFO  o.a.catalina.core.StandardService - Starting service [Tomcat]
11:33:36.649 [main] INFO  o.a.catalina.core.StandardEngine - Starting Servlet engine: [Apache Tomcat/9.0.16]
...
...
11:33:36.952 [main] INFO  o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring embedded WebApplicationContext
...
...
11:33:48.223 [main] INFO  o.a.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-8080"]
11:33:48.289 [main] INFO  o.s.b.w.e.tomcat.TomcatWebServer - Tomcat started on port(s): 8080 (http) with context path ''
11:33:48.292 [main] INFO  org.baeldung.boot.Application - Started Application in 22.454 seconds (JVM running for 37.692)
ログに「Started Application」を含む行が表示されたら、アドレスhttp:// localhost:8080 /のブラウザーを介してWebアプリケーションを照会する準備ができています。

4. スタンドアロンパッケージアプリケーションとしてのコードの実行

*開発フェーズを通過し、アプリケーションを本番環境に移行させるには、アプリケーションをパッケージ化する必要があります。*
残念ながら、_jar_パッケージを使用している場合、基本的なMaven _package_の目標には外部依存関係は含まれません。
これは、より大きなプロジェクトのライブラリとしてのみ使用できることを意味します。
*この制限を回避するには、* * Maven Spring Bootプラグインの_repackage_ゴールを活用して、jar / warをスタンドアロンアプリケーションとして実行する必要があります。*

4.1. 設定

通常、ビルドプラグインを設定するだけです。
<build>
    <plugins>
        ...
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
        ...
    </plugins>
</build>
しかし、サンプルプロジェクトには複数のメインクラスが含まれているため、プラグインを設定することにより、実行するクラスをJavaに指示する必要があります。
<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <executions>
        <execution>
            <configuration>
                <mainClass>com.baeldung.webjar.WebjarsdemoApplication</mainClass>
            </configuration>
        </execution>
    </executions>
</plugin>
または、_start-class_プロパティを設定することにより:
<properties>
    <start-class>com.baeldung.webjar.WebjarsdemoApplication</start-class>
</properties>

4.2. アプリケーションを実行する

これで、2つの簡単なコマンドを使用してサンプルのwarを実行できます。
$ mvn clean package spring-boot:repackage
$ java -jar target/spring-boot-ops.war
jarファイルの実行方法に関する詳細は、https://www.baeldung.com/java-run-jar-with-arguments [コマンドライン引数でJARアプリケーションを実行]の記事に記載されています。

4.3. 戦争ファイルの内部

*上記のコマンドが完全なサーバーアプリケーションを実行する方法をよりよく理解するには、_spring-boot-ops.war _。*を調べます。
圧縮解除して内部を覗くと、通常の容疑者が見つかります。
  • META-INF、自動生成_MANIFEST.MF_

  • WEB-INF / classes、コンパイル済みクラスを含む

  • WEB-INF / lib。これは、戦争の依存関係と組み込みの
    Tomcat jarファイル

    脂肪パッケージ構成に固有のフォルダーがいくつかあるため、それだけではありません。
  • WEB-INF / lib-provided、次の場合に必要な外部ライブラリを含む
    組み込みで実行されますが、デプロイ時には必要ありません

  • org / springframework / boot / loader:Spring Bootカスタムを保持します
    クラスローダー-このライブラリは、外部依存関係をロードし、実行時にアクセス可能にする役割を果たします。

4.4. 戦争マニフェストの内側

前述したように、Maven Spring Bootプラグインはメインクラスを見つけ、_java_コマンドの実行に必要な構成を生成します。
結果の_MANIFEST.MF_には追加の行がいくつかあります。
Start-Class: com.baeldung.webjar.WebjarsdemoApplication
Main-Class: org.springframework.boot.loader.WarLauncher
特に、最後のものは、使用するSpring Bootクラスローダーランチャーを指定していることがわかります。

4.5. jarファイルの内部

デフォルトのパッケージング戦略により、_Spring Boot Mavenプラグインを使用するかどうかにかかわらず、_warパッケージング_シナリオはほとんど変わりません。
プラグインの利点をよりよく理解するために、pom _packaging_設定を_jar_に変更して、_mvn clean package_を再度実行してみてください。
これで、ファットjarが以前のwarファイルとは少し異なって編成されていることがわかります。
  • すべてのクラスとリソースフォルダーは以下にあります。
    BOOT-INF / classes

  • _BOOT-INF / lib_はすべての外部ライブラリを保持します

    *プラグインなしでは、_lib_フォルダーは存在せず、_BOOT-INF / classes_のすべてのコンテンツはパッケージのルートに配置されます。*

4.6. 瓶マニフェストの内側

また、__ MANIFEST .__ MFも変更され、次の追加行が追加されました。
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Spring-Boot-Version: 2.1.3.RELEASE
Main-Class: org.springframework.boot.loader.JarLauncher
_Spring-Boot-Classes_と_Spring-Boot-Lib_は、クラスローダーがクラスと外部ライブラリを見つける場所を教えてくれるので、特に興味深いものです。

5. 選び方

ツールを分析する場合、*これらのツールが作成された目的を考慮することが不可欠です*。開発を容易にするか、スムーズな展開と移植性を確保したいですか この選択によって最も影響を受けるフェーズを見てみましょう。

5.1. 開発

開発者として、多くの場合、コードをローカルで実行するための環境のセットアップに多くの時間を費やすことなく、コーディングにほとんどの時間を費やします。 単純なアプリケーションでは、通常、これは問題になりません。 ただし、より複雑なプロジェクトの場合は、環境変数の設定、サーバーの起動、データベースの作成が必要になる場合があります。
*アプリケーションを実行するたびに適切な環境を構成することは、特に複数のサービスを同時に実行する必要がある場合、非常に非現実的です*。
そこで、Mavenでコードを実行すると役立ちます。 すでにコードベース全体をローカルでチェックアウトしているため、pom構成とリソースファイルを活用できます。 環境変数を設定し、メモリ内データベースを生成し、1つのコマンドで正しいサーバーバージョンをダウンロードし、アプリケーションをデプロイすることもできます。
各モジュールに異なる変数とサーバーバージョンが必要なマルチモジュールコードベースでも、Mavenプロファイルを介して適切な環境を簡単に実行できます。

5.2. 製造

生産に移行するほど、会話は安定性とセキュリティに移行します。 そのため、開発マシンで使用されているプロセスを実際の顧客がいるサーバーに適用することはできません。
*この段階でMavenを介してコードを実行するのは、いくつかの理由で悪い習慣です:*
  • まず、Mavenをインストールする必要があります

  • 次に、コードをコンパイルする必要があるという理由だけで、完全なJava
    開発キット(JDK)

  • 次に、コードベースをサーバーにコピーして、すべての
    プレーンテキストの独自コード

  • _mvn_コマンドは、ライフサイクルのすべてのフェーズを実行する必要があります(検索
    ソース、コンパイル、実行)

  • 前のポイントのおかげで、CPUも無駄になり、その場合は
    クラウドサーバー、お金の

  • Mavenは複数のJavaプロセスを生成し、それぞれがメモリを使用します(デフォルトでは、
    それぞれ、親プロセスと同じメモリ量を使用します)

  • 最後に、展開するサーバーが複数ある場合、上記のすべてが
    それぞれに繰り返されます

    これらは、*アプリケーションをパッケージとして出荷するのが実稼働により適している理由のほんの一部です。

6. 結論

このチュートリアルでは、Mavenを介してコードを実行する場合と_java -jar_コマンドを使用してコードを実行する場合の違いを調べました。 また、いくつかの実際的なケースシナリオの概要を簡単に実行しました。
この記事で使用されているソースコードは、https://github.com/eugenp/tutorials/tree/master/spring-boot-ops [GitHub上]で入手できます。