1. 序章

このチュートリアルでは、spring -boot-thin-launcherプロジェクトを使用して、プロジェクトをシンJARファイルにビルドする方法を見ていきます。

Spring Bootは、単一の実行可能アーティファクトにアプリケーションコードとそのすべての依存関係の両方が含まれる「ファット」なJARデプロイメントで知られています。

ブートは、マイクロサービスの開発にも広く使用されています。 多くのアーティファクトに同じ依存関係を何度も含めると、リソースの重要な浪費になる可能性があるため、これは「ファットJAR」アプローチと相反する場合があります。

2. 前提条件

もちろん、まず最初に、SpringBootプロジェクトが必要です。 この記事では、Mavenビルドと、最も一般的な構成でのGradleビルドについて説明します。

すべてのビルドシステムとビルド構成を網羅することは不可能ですが、うまくいけば、特定のセットアップに適用できるはずの一般的な原則を十分に理解することができます。

2.1. Mavenプロジェクト

MavenでビルドされたBootプロジェクトでは、プロジェクトの pom.xml ファイル、その親、またはその祖先の1つでSpring BootMavenプラグインを構成する必要があります。

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>    
</plugin>

Spring Bootの依存関係のバージョンは、通常、BOMを使用するか、参照プロジェクトのように親POMから継承することによって決定されます。

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.4.0</version>
    <relativePath/>
</parent>

2.2. Gradleプロジェクト

GradleでビルドされたBootプロジェクトには、BootGradleプラグインがあります。

buildscript {
    ext {
        springBootPlugin = 'org.springframework.boot:spring-boot-gradle-plugin'
        springBootVersion = '2.4.0'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("${springBootPlugin}:${springBootVersion}")
    }
}

// elided

apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

springBoot {
    mainClassName = 'com.baeldung.DemoApplication'
}

この記事では、Boot2.x以降のプロジェクトのみを検討することに注意してください。 Thin Launcherは以前のバージョンもサポートしていますが、簡単にするために省略しているわずかに異なるGradle構成が必要です。 詳細については、プロジェクトのホームページをご覧ください。

3. シンJARを作成する方法は?

Spring Boot Thin Launcherは、アーカイブ自体にバンドルされているファイルからアーティファクトの依存関係を読み取り、Mavenリポジトリからダウンロードして、最終的にアプリケーションのメインクラスを起動する小さなライブラリです。

したがって、ライブラリを使用してプロジェクトをビルドすると、コードを含むJARファイル、その依存関係を列挙するファイル、および上記のタスクを実行するライブラリからのメインクラスを取得します。

もちろん、物事は私たちの簡単な説明よりも少し微妙です。 いくつかのトピックについては、この記事の後半で詳しく説明します。

4. 基本的な使用法

次に、通常のSpring Bootアプリケーションから「薄い」JARを構築する方法を見てみましょう。

通常のアプリケーションを起動します java -jar シンランチャーを制御するオプションの追加コマンドライン引数を使用します。 次のセクションでそれらのいくつかを見ていきます。 プロジェクトのホームページには完全なリストが含まれています。

4.1. Mavenプロジェクト

Mavenプロジェクトでは、カスタムの「薄い」レイアウトへの依存関係を含めるために、ブートプラグインの宣言(セクション2.1を参照)を変更する必要があります。

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <dependencies>
        <!-- The following enables the "thin jar" deployment option. -->
        <dependency>
            <groupId>org.springframework.boot.experimental</groupId>
            <artifactId>spring-boot-thin-layout</artifactId>
            <version>1.0.11.RELEASE</version>
        </dependency>
    </dependencies>
</plugin>

launcher は、Mavenが生成されたJARの META-INF /mavenディレクトリに保存するpom.xmlファイルから依存関係を読み取ります。

ビルドは通常どおり実行します。たとえば、 mvninstallを使用します。

シンビルドとファットビルドの両方を生成できるようにしたい場合(たとえば、複数のモジュールを含むプロジェクトで)、専用のMavenプロファイルでカスタムレイアウトを宣言できます。

4.2. Mavenと依存関係: thin.properties

pom.xmlに加えてMavenにthin.propertiesファイルを生成させることもできます。 その場合、ファイルには推移的な依存関係を含む依存関係の完全なリストが含まれ、ランチャーはそれを優先します pom.xml

そのためのmojo(プラグイン)は spring-boot-thin-maven-plugin:properties、であり、デフォルトでは、thin.propertiesファイルをsrc/に出力します。 main / resources / META-INF ですが、その場所はthin.outputプロパティで指定できます。

$ mvn org.springframework.boot.experimental:spring-boot-thin-maven-plugin:properties -Dthin.output=.

デフォルトのディレクトリを保持している場合でも、目標を成功させるには出力ディレクトリが存在する必要があることに注意してください。

4.3. Gradleプロジェクト

代わりに、Gradleプロジェクトでは、専用のプラグインを追加します。

buildscript {
    ext {
        //...
        thinPlugin = 'org.springframework.boot.experimental:spring-boot-thin-gradle-plugin'
        thinVersion = '1.0.11.RELEASE'
    }
    //...
    dependencies {
        //...
        classpath("${thinPlugin}:${thinVersion}")
    }
}

//elided

apply plugin: 'maven'
apply plugin: 'org.springframework.boot.experimental.thin-launcher'

シンビルドを取得するには、GradleにthinJarタスクを実行するように指示します。

~/projects/baeldung/spring-boot-gradle $ ./gradlew thinJar

4.4. Gradleと依存関係: pom.xml

前のセクションのコード例では、Thin Launcherに加えてMavenプラグイン(および前提条件のセクションですでに見たBoot and Dependency Managementプラグイン)を宣言しました。

これは、前に見たMavenの場合と同様に、アーティファクトにはアプリケーションの依存関係を列挙するpom.xmlファイルが含まれて使用されるためです。 pom.xml ファイルは、 thinPom というタスクによって生成されます。これは、jarタスクの暗黙的な依存関係です。

専用のタスクを使用して、生成されたpom.xmlファイルをカスタマイズできます。ここでは、シンプラグインがすでに自動的に実行していることを複製します。

task createPom {
    def basePath = 'build/resources/main/META-INF/maven'
    doLast {
        pom {
            withXml(dependencyManagement.pomConfigurer)
        }.writeTo("${basePath}/${project.group}/${project.name}/pom.xml")
    }
}

カスタムpom.xmlファイルを使用するには、上記のタスクをjarタスクの依存関係に追加します。

bootJar.dependsOn = [createPom]

4.5. Gradleと依存関係: thin.properties

以前にMavenで行ったように、pom.xmlではなくthin.propertiesファイルをGradleに生成させることもできます。

thin.properties ファイルを生成するタスクは、 thinProperties、と呼ばれ、デフォルトでは使用されません。 jarタスクの依存関係として追加できます。

bootJar.dependsOn = [thinProperties]

5. 依存関係の保存

シンジャーの要点は、依存関係をアプリケーションにバンドルしないようにすることです。 ただし、依存関係は魔法のように消えることはなく、単に他の場所に保存されます。

特に、Thin LauncherはMavenインフラストラクチャを使用して依存関係を解決するため、次のようになります。

  1. ローカルのMavenリポジトリーをチェックします。これはデフォルトで〜/ .m2 / repository にありますが、他の場所に移動できます。
  2. 次に、不足している依存関係をMaven Central(またはその他の構成済みリポジトリー)からダウンロードします。
  3. 最後に、それらをローカルリポジトリにキャッシュするため、次回アプリケーションを実行するときに再度ダウンロードする必要はありません。

もちろん、ダウンロードフェーズはプロセスの遅くてエラーが発生しやすい部分です。インターネット経由でMaven Centralにアクセスするか、ローカルプロキシにアクセスする必要があるため、これらがどのように行われるかは誰もが知っています。一般的に信頼性がありません。

幸いなことに、たとえばクラウド展開用に事前にパッケージ化されたコンテナーで、アプリケーションと一緒に依存関係を展開するさまざまな方法があります。

5.1. ウォームアップのためのアプリケーションの実行

依存関係をキャッシュする最も簡単な方法は、ターゲット環境でアプリケーションのウォームアップ実行を実行することです。 前に見たように、これにより依存関係がダウンロードされ、ローカルのMavenリポジトリにキャッシュされます。 複数のアプリを実行すると、リポジトリには重複することなくすべての依存関係が含まれることになります。

アプリケーションを実行すると望ましくない副作用が発生する可能性があるため、ユーザーコードを実行せずに依存関係を解決してダウンロードするだけの「ドライラン」を実行することもできます。

$ java -Dthin.dryrun=true -jar my-app-1.0.jar

Spring Bootの規則に従って、 -Dthin.dryrun プロパティは、アプリケーションへの –thin.dryrunコマンドライン引数またはTHIN_DRYRUNでも設定できることに注意してください。 システムプロパティ。 false 以外の値は、シンランチャーにドライランを実行するように指示します。

5.2. ビルド中の依存関係のパッケージ化

もう1つのオプションは、JARにバンドルせずに、ビルド中に依存関係を収集することです。 次に、展開手順の一部として、それらをターゲット環境にコピーできます。

ターゲット環境でアプリケーションを実行する必要がないため、これは一般的に簡単です。 ただし、複数のアプリケーションをデプロイする場合は、手動またはスクリプトを使用して、それらの依存関係をマージする必要があります。

MavenおよびGradle用のThinPluginがビルド中に依存関係をパッケージ化する形式は、Mavenローカルリポジトリと同じです。

root/
    repository/
        com/
        net/
        org/
        ...

実際、Thin Launcherを使用するアプリケーションは、 thin.root プロパティを使用して、実行時にそのようなディレクトリ(ローカルのMavenリポジトリを含む)を指すことができます。

$ java -jar my-app-1.0.jar --thin.root=my-app/deps

また、このような複数のディレクトリを相互にコピーすることで安全にマージし、必要なすべての依存関係を持つMavenリポジトリを取得することもできます。

5.3. Mavenを使用した依存関係のパッケージ化

Mavenに依存関係をパッケージ化させるために、 解決の目標 spring-boot-thin-maven-plugin。 手動または自動で呼び出すことができます pom.xml:

<plugin>
    <groupId>org.springframework.boot.experimental</groupId>
    <artifactId>spring-boot-thin-maven-plugin</artifactId>
    <version>${thin.version}</version>
    <executions>
        <execution>
        <!-- Download the dependencies at build time -->
        <id>resolve</id>
        <goals>
            <goal>resolve</goal>
        </goals>
        <inherited>false</inherited>
        </execution>
    </executions>
</plugin>

プロジェクトをビルドすると、前のセクションで説明した構造のディレクトリ target / thin / root/が見つかります。

5.4. Gradleで依存関係をパッケージ化する

代わりに、 thin-launcher プラグインでGradleを使用している場合は、thinResolveタスクを使用できます。 このタスクは、前のセクションのMavenプラグインと同様に、アプリケーションとその依存関係を build / thin / root/ディレクトリに保存します。

$ gradlew thinResolve

6. 結論と参考文献

この記事では、薄いjarの作成方法について説明しました。 また、Mavenインフラストラクチャを使用して依存関係をダウンロードして保存する方法も確認しました。

シンランチャーのホームページには、Herokuへのクラウド展開などのシナリオに関するHOW-TOガイドと、サポートされているコマンドライン引数の完全なリストがいくつかあります。

すべてのMavenの例とコードスニペットの実装は、 GitHubプロジェクトにあります– Mavenプロジェクトとして、そのままインポートして実行するのは簡単です。

同様に、すべてのGradleの例は、このGitHubプロジェクトを参照しています。