Maven Assembly Plugin 設定例付き使い方ガイド

はい、承知いたしました。Maven Assembly Plugin の使い方ガイドとして、約5000語の詳細な記事を作成します。設定例を豊富に含め、Pluginの機能、Descriptorの書き方、様々なユースケース、ベストプラクティスなどを網羅します。

以下に記事の本文を直接表示します。


Maven Assembly Plugin 完全ガイド:成果物パッケージングを自動化する

はじめに

ソフトウェアプロジェクトの開発において、ビルドの最終成果物は単一のJARファイルやWARファイルだけとは限りません。実行可能なスクリプト、設定ファイル、ドキュメント、依存するライブラリ一式をまとめた配布パッケージや、特定のディレクトリ構造を持つデプロイメントアーカイブなど、様々な形式の成果物が必要となることが頻繁にあります。

Mavenはプロジェクトのビルドプロセスを標準化する強力なツールですが、これらの多様な成果物パッケージングの要求に応えるために提供されているのが Maven Assembly Plugin です。このPluginを使用することで、プロジェクトのファイル、依存関係、他のモジュールの成果物などを組み合わせて、指定された形式(ZIP, TAR, JAR, ディレクトリなど)でアセンブリ(集合体)を作成する処理を自動化できます。

本記事では、Maven Assembly Pluginの基本的な使い方から、Assembly Descriptorの詳細な設定方法、様々な設定要素(FileSets, ModuleSets, DependencySetsなど)、実践的なユースケース、デバッグ方法、そしてベストプラクティスまでを、豊富な設定例を交えながら徹底的に解説します。この記事を読むことで、あなたのプロジェクトにおける複雑な成果物パッケージング要件をAssembly Pluginで満たすための知識とスキルを習得できるでしょう。

Maven Assembly Plugin の基本

Assembly Pluginを使用するための最初のステップは、プロジェクトの pom.xml にPluginの依存関係を追加することです。

1. Plugin の依存関係を追加する

<build> セクション内の <plugins> に、Assembly Pluginの設定を追加します。通常は <pluginManagement> ではなく、プロジェクトの <plugins> に直接追加します。

“`xml
4.0.0
com.example
my-app
1.0.0-SNAPSHOT

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>3.6.0</version> <!-- 最新の安定バージョンを指定 -->
            <configuration>
                <!-- ここにAssembly Pluginの設定を記述 -->
            </configuration>
            <executions>
                <execution>
                    <id>make-assembly</id>
                    <phase>package</phase> <!-- packageフェーズで実行 -->
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

<!-- 依存関係など -->
<dependencies>
    <!-- ... -->
</dependencies>

“`

上記の例では、package フェーズで single ゴールを実行するように設定しています。これにより、mvn package コマンドを実行した際に、プロジェクトのビルドと同時にアセンブリが作成されます。

2. Plugin のゴール

Assembly Pluginが提供する主なゴールは以下の通りです。

  • single: 最も一般的に使用されるゴールです。指定されたDescriptorファイルに基づいて、単一のアセンブリを作成します。通常、 <execution> ブロック内で使用されます。
  • directory: Assembly Descriptorで定義された内容を、アーカイブ形式ではなく、ファイルシステム上のディレクトリとして作成します。デバッグや、アーカイブ化の前に内容を確認したい場合に便利です。
  • help: Pluginの情報を表示します。

本記事では主に single ゴールに焦点を当てます。

3. 基本的な実行方法

Plugin設定後、Mavenのライフサイクルに従って実行できます。

  • mvn package: <execution>package フェーズが設定されている場合、このコマンドでアセンブリが作成されます。
  • mvn assembly:single: <execution> に関連付けずに、特定のゴールを直接実行することも可能です。この場合、Pluginの <configuration> セクションに記述した設定が使用されます(<execution> 内の <configuration> は実行時には優先されます)。

例えば、Descriptorファイルを src/main/assembly/distribution.xml とし、それを参照して実行する場合は、以下のように <configuration><descriptor> 要素を追加します。

xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<descriptors>
<descriptor>src/main/assembly/distribution.xml</descriptor>
</descriptors>
<!-- または <descriptorRefs> を使用する場合 -->
<!--
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
-->
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>

<descriptors> 要素には、参照するAssembly Descriptorファイルのパスを複数指定できます。また、Mavenが提供する事前定義されたDescriptorを参照する場合は <descriptorRefs> 要素を使用します(これについては後述します)。

アセンブリ Descriptor (Assembly Descriptors)

Maven Assembly Pluginの最も重要な要素は、Assembly Descriptor です。これは、作成するアセンブリに何を含めるか、どのようなディレクトリ構造にするか、どのような形式で出力するかなどを定義するXMLファイルです。

Descriptorファイルは通常、src/main/assembly/ ディレクトリに配置します。ファイル名は任意ですが、アセンブリの目的を示す名前(例: distribution.xml, bin.xml, src.xml)にすることが推奨されます。

1. Descriptor の基本構造

Assembly Descriptorのルート要素は <assembly> です。その主な子要素は以下の通りです。

  • <id>: このDescriptorによって作成されるアセンブリのIDです。出力されるファイル名にこのIDが付加されます(例: my-app-1.0.0-SNAPSHOT-distribution.zipdistribution 部分)。
  • <formats>: アセンブリの出力形式を指定します。複数の形式を指定できます。
  • <includeBaseDirectory>: 作成されるアーカイブのルートに、プロジェクト名とバージョンからなるベースディレクトリを含めるかどうかを指定します(デフォルトは true)。
  • <fileSets>: プロジェクト内の特定のファイルやディレクトリ構造をアセンブリに含める定義の集合です。
  • <moduleSets>: マルチモジュールプロジェクトにおいて、他のモジュールの成果物(JAR, WARなど)やソースコードをアセンブリに含める定義の集合です。
  • <dependencySets>: プロジェクトの依存関係(通常はライブラリJAR)をアセンブリに含める定義の集合です。
  • <files>: 個別のファイルをアセンブリに含める定義の集合です(<fileSets> の簡易版と考えられますが、通常は <fileSets> がより柔軟で推奨されます)。
  • <resources>: Maven Resource Pluginと同様に、リソースをフィルタリングして含める定義の集合です。
  • <component>: 再利用可能なアセンブリの構成要素を定義します(高度な使い方)。

基本的なDescriptorの構造は以下のようになります。

“`xml

<id>distribution</id> <!-- アセンブリのID -->

<formats>
    <format>zip</format>
    <format>tar.gz</format>
</formats> <!-- ZIPとtar.gz形式で出力 -->

<includeBaseDirectory>true</includeBaseDirectory> <!-- ベースディレクトリを含める -->
<!-- 例: my-app-1.0.0-SNAPSHOT/ -->

<!-- 以下にファイル、依存関係などの定義を追加 -->


“`

XML Schemaのバージョンは、使用するPluginのバージョンに合わせて調整してください。最新のスキーマは Assembly Pluginのドキュメントで確認できます。

2. <formats> 要素

<formats> 要素では、作成するアセンブリの出力形式を指定します。<format> 子要素で以下のいずれかを指定できます。

  • zip: ZIPアーカイブ形式。
  • tar: TARアーカイブ形式。
  • tar.gz (または tgz): Gzip圧縮されたTARアーカイブ形式。
  • tar.bz2 (または tbz2): Bzip2圧縮されたTARアーカイブ形式。
  • jar: JAR形式。通常は依存関係をbundledした”jar-with-dependencies”を作成する場合に使用されます(ただし、実行可能JARにする場合はMaven Shade Pluginなど他のPluginと組み合わせて使うことが一般的です)。
  • dir: アーカイブではなく、ファイルシステム上のディレクトリとして出力します。
  • war: WAR形式。非推奨です。WARファイルはWAR Pluginで作成するのが適切であり、Assembly PluginでWARを作成する特別な理由はほとんどありません。

複数の <format> 要素を指定すると、指定したすべての形式でアセンブリが作成されます。

3. <includeBaseDirectory> 要素

この要素は、作成されるアーカイブのルートに、プロジェクトの <artifactId>-<version> という形式のディレクトリを含めるかどうかを制御します。

  • true (デフォルト): my-app-1.0.0-SNAPSHOT/ というディレクトリがアーカイブのルートに作成され、その中にアセンブリの内容が格納されます。配布パッケージに適しています。
  • false: アセンブリの内容がアーカイブのルートに直接格納されます。デプロイメントアーカイブや、特定のツールで読み込む形式に適しています。

例えば、includeBaseDirectorytrue の場合:
my-app-1.0.0-SNAPSHOT/conf/application.properties
my-app-1.0.0-SNAPSHOT/lib/my-library.jar

includeBaseDirectoryfalse の場合:
conf/application.properties
lib/my-library.jar

ファイルセット (FileSets)

<fileSets> 要素は、プロジェクトのソースディレクトリ(src)、リソースディレクトリ、あるいはその他の任意のディレクトリからファイルやディレクトリを収集し、アセンブリ内の特定の場所に配置するために使用します。これはAssembly Descriptorの中で最も頻繁に使用される要素の一つです。

<fileSets> 要素は <fileSet> 子要素を複数持つことができます。各 <fileSet> は、収集元ディレクトリと、アセンブリ内の出力先ディレクトリ、および含める/除外するファイルを定義します。

1. <fileSet> 要素の構造

<fileSet> の主な子要素は以下の通りです。

  • <directory>: ファイルを収集するプロジェクト内のディレクトリのパスを指定します。プロジェクトのベースディレクトリからの相対パスで指定するのが一般的です(例: src/main/resources, src/main/scripts, ${project.build.directory}/classes)。Mavenプロパティ(${project.basedir}, ${project.build.directory} など)を使用できます。
  • <outputDirectory>: 収集したファイルをアセンブリ内のどこに配置するかを指定します。アセンブリのルートディレクトリからの相対パスで指定します(例: /, conf, bin, data)。includeBaseDirectorytrue の場合、このパスはベースディレクトリの下に配置されます(例: /my-app-1.0.0-SNAPSHOT/ になります)。
  • <includes>: 含めるファイルやディレクトリのglobパターン(ワイルドカード指定)のリストです。
  • <excludes>: 除外するファイルやディレクトリのglobパターンのリストです。
  • <filtered>: true に設定すると、リソースフィルタリング(Maven Resource Pluginと同様の機能)が適用され、プロパティプレースホルダー(例: ${project.version})が置換されます。
  • <directoryMode>: 収集したディレクトリをアセンブリに含める際のファイルシステムパーミッション(例: 0755)を指定します。アーカイブ形式によってはサポートされない場合があります。
  • <fileMode>: 収集したファイルをアセンブリに含める際のファイルシステムパーミッション(例: 0644, 0755)を指定します。実行可能なスクリプトなどを含める場合に重要です。アーカイブ形式によってはサポートされない場合があります。
  • <map/>: ファイル名を変更する高度な設定ですが、通常は <outputFileNameMapping> の方がシンプルです。この要素はあまり使用されません。

2. 具体的な設定例

いくつかの一般的な <fileSet> の設定例を示します。

例1: 設定ファイルをアセンブリの conf ディレクトリに含める

src/main/resources ディレクトリにある設定ファイル(.properties, .xml, .yml など)を収集し、アセンブリのルートディレクトリにある conf/ ディレクトリに配置する例です。フィルタリングも有効にしています。

xml
<fileSets>
<fileSet>
<directory>${project.basedir}/src/main/resources</directory> <!-- 収集元ディレクトリ -->
<outputDirectory>conf</outputDirectory> <!-- アセンブリ内の出力先ディレクトリ -->
<includes>
<include>*.properties</include>
<include>*.xml</include>
<include>*.yml</include>
</includes>
<excludes>
<exclude>log4j.properties</exclude> <!-- log4j設定は含めないなど -->
</excludes>
<filtered>true</filtered> <!-- プロパティ置換を有効化 -->
</fileSet>
</fileSets>

この設定により、例えば src/main/resources/application.properties というファイルは、アセンブリ内で conf/application.properties として含まれます。ファイルの内容に含まれる ${project.version} のようなMavenプロパティは、ビルド時に実際のバージョンに置き換えられます。

例2: 実行可能スクリプトを bin ディレクトリに含める

src/main/scripts ディレクトリにあるシェルスクリプトやバッチファイルを収集し、アセンブリのルートディレクトリにある bin/ ディレクトリに配置する例です。実行可能パーミッション (0755) を設定しています。

xml
<fileSets>
<fileSet>
<directory>${project.basedir}/src/main/scripts</directory>
<outputDirectory>bin</outputDirectory>
<includes>
<include>*.sh</include>
<include>*.bat</include>
</includes>
<fileMode>0755</fileMode> <!-- 実行可能パーミッションを設定 -->
</fileSet>
</fileSets>

例3: ビルド成果物ディレクトリから特定のファイルをコピーする

target ディレクトリにビルドされた特定のファイル(例: ドキュメント、生成された設定ファイルなど)をアセンブリに含める例です。

xml
<fileSets>
<fileSet>
<directory>${project.build.directory}</directory>
<outputDirectory>docs</outputDirectory>
<includes>
<include>README.txt</include>
<include>manual/*.html</include> <!-- target/manual以下のHTMLを含める -->
</includes>
</fileSet>
</fileSets>

ここでは ${project.build.directory} というMavenプロパティを使用しています。これは target ディレクトリのパスに展開されます。

例4: ルートディレクトリにファイルを含める

プロジェクトのルートディレクトリにある LICENSE.txtREADME.md を、アセンブリのルートディレクトリに含める例です。

xml
<fileSets>
<fileSet>
<directory>${project.basedir}</directory>
<outputDirectory>/</outputDirectory> <!-- アセンブリのルートディレクトリ -->
<includes>
<include>LICENSE.txt</include>
<include>README.md</include>
</includes>
</fileSet>
</fileSets>

<outputDirectory>/</outputDirectory> は、アセンブリのルートディレクトリを意味します。includeBaseDirectorytrue の場合は my-app-1.0.0-SNAPSHOT/ の直下に、false の場合はアーカイブのルートに配置されます。

<fileSets> は、プロジェクト内の静的なファイルや、ビルドプロセスで生成されたファイルを柔軟にアセンブリに組み込むための主要な手段です。<includes><excludes> の強力なパターンマッチングを活用することで、必要なファイルだけを正確に含めることができます。

モジュールセット (ModuleSets)

<moduleSets> 要素は、マルチモジュールプロジェクトにおいて、現在ビルドしているプロジェクト以外のモジュールの成果物(JAR, WARなど)やソースコードをアセンブリに含めたい場合に使用します。

<moduleSets> 要素は <moduleSet> 子要素を複数持つことができます。各 <moduleSet> は、含める対象のモジュールをフィルタリングし、そのモジュールから何(バイナリ成果物かソースコードか)を含めるかを定義します。

1. <moduleSet> 要素の構造

<moduleSet> の主な子要素は以下の通りです。

  • <includes>: 含めるモジュールのgroupId:artifactIdのパターンリスト。
  • <excludes>: 除外するモジュールのgroupId:artifactIdのパターンリスト。
  • <binaries>: 対象モジュールのバイナリ成果物(通常はJARやWAR)を含める設定。
  • <sources>: 対象モジュールのソースコードを含める設定。

通常、<moduleSet> の中では <binaries><sources> のいずれか、または両方を設定します。

2. <binaries> 要素

<binaries> 要素は、対象モジュールの主要な成果物(<packaging> タイプによって決まるJAR, WARなど)をアセンブリに含めるための設定です。

<binaries> の主な子要素は以下の通りです。

  • <outputDirectory>: モジュールの成果物をアセンブリ内のどこに配置するかを指定します(例: modules, lib)。
  • <includes>: 含めるモジュールの成果物のタイプ(例: <include>*.jar</include>)またはgroupId:artifactIdのパターン。通常は親要素の<moduleSet>でモジュールを指定するため、ここでは成果物のタイプや分類子を指定することが多いです。
  • <excludes>: 除外するモジュールの成果物のタイプや分類子。
  • <unpack>: true に設定すると、モジュールの成果物(例: JAR, WAR)を展開してアセンブリに含めます。アーカイブ形式によってはサポートされない場合があります。
  • <unpackOptions>: <unpack>true の場合の展開オプション(含める/除外するファイルパターンなど)。
  • <directoryMode>: 展開されたディレクトリのパーミッション。
  • <fileMode>: 展開されたファイルのパーミッション。
  • <dependencySets>: 注意! <moduleSet>/<binaries> の中の <dependencySets> は、そのモジュールの依存関係を含めるために使用します。これはルートレベルの <dependencySets> とは異なり、特定のモジュールの依存関係を扱います。

3. <sources> 要素

<sources> 要素は、対象モジュールのソースコードをアセンブリに含めるための設定です。通常、モジュールの src/main ディレクトリ以下の内容を含めます。

<sources> の主な子要素は以下の通りです。

  • <outputDirectory>: モジュールのソースコードをアセンブリ内のどこに配置するかを指定します(例: src/modules)。
  • <includes>: 含めるソースファイルやディレクトリのパターン。
  • <excludes>: 除外するソースファイルやディレクトリのパターン。
  • <directoryMode>: ディレクトリのパーミッション。
  • <fileMode>: ファイルのパーミッション。

4. 具体的な設定例

例1: 特定のモジュールのJARをアセンブリに含める

マルチモジュールプロジェクトで、特定のサブモジュールのJARをアセンブリの modules/ ディレクトリに含める例です。

xml
<moduleSets>
<moduleSet>
<includes>
<include>com.example:my-other-module</include> <!-- 含めるモジュールのgroupId:artifactId -->
</includes>
<binaries>
<outputDirectory>modules</outputDirectory> <!-- アセンブリ内の出力先 -->
<includes>
<include>*.jar</include> <!-- モジュールのJARを含める -->
</includes>
<!-- 必要であれば、モジュールの依存関係も含めることができます -->
<!--
<dependencySets>
<dependencySet>
<outputDirectory>modules/lib</outputDirectory>
<scope>runtime</scope>
</dependencySet>
</dependencySets>
-->
</binaries>
</moduleSet>
</moduleSets>

この例では、com.example:my-other-module というモジュールの成果物JARが収集され、アセンブリ内の modules/ ディレクトリに配置されます。コメントアウトされた <dependencySets> の部分は、もしそのモジュールの依存関係も一緒に含めたい場合に設定します。

例2: すべてのモジュールのソースコードを含める

すべてのサブモジュールのソースコードをアセンブリの src/ ディレクトリ以下に、モジュールごとに整理して含める例です。

xml
<moduleSets>
<moduleSet>
<!-- includes/excludes を指定しない場合、すべてのモジュールが対象 -->
<sources>
<!-- outputDirectory はモジュールの ArtifactId をベースに自動生成されます -->
<!-- 例: src/my-module-core/ -->
<outputDirectory>src/%{artifactId}</outputDirectory>
<includes>
<include>**/*.java</include>
<include>**/*.properties</include>
</includes>
</sources>
</moduleSet>
</moduleSets>

<outputDirectory>src/%{artifactId}</outputDirectory> のように、MavenプロパティやAssembly Plugin固有のプレースホルダー(%{artifactId})を使用できます。%{artifactId} は処理中のモジュールのartifactIdに置換されます。

例3: 特定のモジュールの成果物を展開して含める

あるモジュールがWARファイルを生成する場合に、そのWARを展開してアセンブリ内の特定のディレクトリに配置する例です。

xml
<moduleSets>
<moduleSet>
<includes>
<include>com.example:my-web-module</include>
</includes>
<binaries>
<outputDirectory>webroot</outputDirectory> <!-- 展開先ディレクトリ -->
<unpack>true</unpack> <!-- 展開を有効化 -->
<unpackOptions>
<!-- 展開時に特定のファイルを除外する場合 -->
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
</excludes>
</unpackOptions>
</binaries>
</moduleSet>
</moduleSets>

この設定により、my-web-module のWARファイルがアセンブリ内の webroot/ ディレクトリに展開され、WEB-INFやクラスファイルなどが配置されます。これは例えば、アプリケーションサーバーの特定ディレクトリに配置する形式のアーカイブを作成する場合などに有用です。

<moduleSets> はマルチモジュール構成のプロジェクトで非常に役立ちます。単一のDescriptorで、プロジェクト全体の成果物やソースコードをまとめてパッケージングできます。

依存関係セット (DependencySets)

<dependencySets> 要素は、プロジェクトの依存関係として定義されているライブラリ(通常はJARファイル)を収集し、アセンブリに含めるために使用します。これは実行可能JAR(jar-with-dependencies)や配布パッケージの lib ディレクトリを作成する際に不可欠な要素です。

<dependencySets> 要素は <dependencySet> 子要素を複数持つことができます。各 <dependencySet> は、含める依存関係のフィルタリング条件(スコープ、groupId, artifactIdなど)と、アセンブリ内の出力先、およびその他のオプションを定義します。

1. <dependencySet> 要素の構造

<dependencySet> の主な子要素は以下の通りです。

  • <outputDirectory>: 収集した依存関係をアセンブリ内のどこに配置するかを指定します(例: lib, app/lib)。
  • <includes>: 含める依存関係のgroupId:artifactId:type:classifierパターンのリスト。特定のライブラリだけを含めたい場合に指定します。
  • <excludes>: 除外する依存関係のgroupId:artifactId:type:classifierパターンのリスト。
  • <scope>: 含める依存関係のスコープを指定します。指定しない場合は compileruntime スコープがデフォルトで含まれます。その他の値として test, provided, system があります。通常は runtime または compile を指定します。
  • <useProjectArtifact>: true に設定すると、プロジェクト自身(現在ビルド中のモジュール)の成果物(JARなど)も含めます。デフォルトは false です。
  • <useTransitiveDependencies>: true に設定すると、指定した依存関係の推移的な依存関係も含まれます。デフォルトは true です。特定の直接依存関係のみを含めたい場合は false にします。
  • <unpack>: true に設定すると、依存関係(例: JAR, WAR)を展開してアセンブリに含めます。
  • <unpackOptions>: <unpack>true の場合の展開オプション(含める/除外するファイルパターンなど)。
  • <outputFileNameMapping>: 依存関係のファイル名をアセンブリに含める際に変更するためのパターンを指定します。非常に強力な機能です。
  • <directoryMode>: 展開されたディレクトリのパーミッション。
  • <fileMode>: 展開されたファイルのパーミッション。

2. 具体的な設定例

いくつかの一般的な <dependencySet> の設定例を示します。

例1: runtime スコープの依存関係を lib ディレクトリに含める

最も一般的なユースケースです。アプリケーションの実行に必要なライブラリ一式を lib/ ディレクトリに集めます。

xml
<dependencySets>
<dependencySet>
<outputDirectory>lib</outputDirectory> <!-- アセンブリ内の出力先 -->
<scope>runtime</scope> <!-- ランタイムスコープの依存関係のみ -->
<!-- includes/excludes を指定しない場合、スコープ内のすべての依存関係が含まれます -->
</dependencySet>
</dependencySets>

この設定により、pom.xmlruntime スコープまたは compile スコープ(デフォルトで runtime に含まれるため)として定義されている依存関係が、アセンブリ内の lib/ ディレクトリにコピーされます。

例2: 特定の依存関係のみを含める

すべての依存関係ではなく、特定のgroupIdやartifactIdを持つ依存関係だけを含めたい場合の例です。

xml
<dependencySets>
<dependencySet>
<outputDirectory>lib</outputDirectory>
<includes>
<include>com.example:my-library:*</include> <!-- com.exampleグループのmy-libraryアーティファクト -->
<include>org.apache.commons:commons-lang3</include> <!-- commons-lang3ライブラリ -->
</includes>
<excludes>
<exclude>*:slf4j-api:*</exclude> <!-- SLF4J APIは除外 -->
</excludes>
<scope>compile</scope> <!-- コンパイルスコープの依存関係 -->
</dependencySet>
</dependencySets>

<includes> および <excludes> のパターンは groupId:artifactId:type:classifier の形式で指定できます。アスタリスク * はワイルドカードです。

例3: プロジェクト自身の成果物と依存関係をすべて含める (jar-with-dependencies の考え方)

プロジェクト自身のJARと、その runtime スコープの依存関係をすべてフラットな構造で含める例です。これはMavenが提供する jar-with-dependencies Descriptor Refの基本的な考え方に近いです。

xml
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory> <!-- アセンブリのルートディレクトリ -->
<scope>runtime</scope> <!-- ランタイム依存関係 -->
<useProjectArtifact>true</useProjectArtifact> <!-- プロジェクト自身の成果物を含める -->
</dependencySet>
</dependencySets>

この設定では、プロジェクトのJAR (my-app-1.0.0-SNAPSHOT.jar など) と、そのランタイム依存関係がすべてアセンブリのルートディレクトリにコピーされます。これは、Javaアプリケーションのクラスパスに必要なすべてのJARを単一のディレクトリにまとめる際に便利です。ただし、大量のJARがルートに配置されるため、ディレクトリ構造を整理する場合は <outputDirectory>lib などに変更することが多いです。

例4: 依存関係を展開して含める

特定の依存関係(例えば、設定ファイルを含むJARや、WARファイル)をアセンブリ内で展開したい場合の例です。

“`xml


config

com.example:my-config-jar

true


*.properties


<dependencySet>
    <outputDirectory>webapps/myapp</outputDirectory>
    <includes>
        <include>com.example:my-webapp:war:*</include> <!-- WAR依存関係 -->
    </includes>
    <unpack>true</unpack>
</dependencySet>


“`

この例では、my-config-jar から .properties ファイルだけを展開して config/ ディレクトリに配置し、my-webapp のWARを展開して webapps/myapp/ ディレクトリに配置しています。

例5: 依存関係のファイル名を変更する (<outputFileNameMapping>)

依存関係のファイル名を、元のartifactIdやversionではなく、特定のルールに基づいて変更してアセンブリに含めることができます。これは非常に強力な機能です。

xml
<dependencySets>
<dependencySet>
<outputDirectory>lib</outputDirectory>
<scope>runtime</scope>
<outputFileNameMapping>
${artifact.artifactId}.${artifact.extension} <!-- artifactId.extension の形式 -->
</outputFileNameMapping>
</dependencySet>
</dependencySets>

<outputFileNameMapping> 内では、以下のMaven Artifactプロパティを使用できます。

  • ${artifact.groupId}
  • ${artifact.artifactId}
  • ${artifact.version}
  • ${artifact.scope}
  • ${artifact.type}
  • ${artifact.classifier}
  • ${artifact.extension} (通常は “jar”, “war” など)

例えば、commons-lang3-3.12.0.jar は、上記の例では commons-lang3.jar という名前でアセンブリに含まれます。バージョン情報を含めたくない場合に便利です。

より複雑なマッピングも可能です。例えば、groupId/artifactId.extension の形式にしたい場合:

xml
<dependencySets>
<dependencySet>
<outputDirectory>lib</outputDirectory>
<scope>runtime</scope>
<outputFileNameMapping>
${artifact.groupId}/${artifact.artifactId}.${artifact.extension}
</outputFileNameMapping>
</dependencySet>
</dependencySets>

この場合、commons-lang3-3.12.0.jarlib/org.apache.commons/commons-lang3.jar のように配置されます。

<dependencySets> は、外部ライブラリや依存モジュールを成果物に含めるための最も重要なメカニズムです。<scope>, <includes>, <excludes>, <unpack>, そして特に <outputFileNameMapping> を組み合わせることで、様々な要件に応じたライブラリ構成を持つアセンブリを作成できます。

リソースセット (ResourceSets)

<resourceSets> 要素は、Maven Resource Pluginと同様のリソースフィルタリング機能をAssembly Plugin内で実行するために使用します。<fileSets> と似ていますが、主な違いはリソースフィルタリングがデフォルトで有効である点と、FileSetsがファイルやディレクトリ構造のコピーに焦点を当てているのに対し、ResourceSetsはプロパティ置換などのリソース処理に特化している点です。

しかし、Assembly Pluginの <fileSets> にも <filtered>true</filtered> オプションがあるため、多くの場合 <fileSets> で十分であり、<resourceSets> はあまり頻繁に使用されません。特別な理由がない限り、<fileSets> を使用することをお勧めします。

1. <resourceSet> 要素の構造

<resourceSet> はMaven Resource Pluginの <resource> 要素と非常によく似た構造を持ちます。

  • <directory>: リソースファイルを収集するディレクトリ。
  • <outputDirectory>: アセンブリ内の出力先ディレクトリ。
  • <includes>: 含めるリソースファイルのパターン。
  • <excludes>: 除外するリソースファイルのパターン。
  • <filtered>: true に設定するとフィルタリングが有効になります(<resourceSets> の場合は通常 true にしますが、明示的に指定できます)。
  • <directoryMode>: ディレクトリのパーミッション。
  • <fileMode>: ファイルのパーミッション。
  • <filtering>: <filtered> の別名(非推奨)。
  • <targetPath>: <outputDirectory> の別名(非推奨)。

2. 設定例

src/main/config ディレクトリにある設定ファイルを収集し、プロパティ置換を行ってアセンブリの conf/ ディレクトリに配置する例です。これは <fileSets> の例とほぼ同じですが、<resourceSets> を使用した場合です。

xml
<resourceSets>
<resourceSet>
<directory>${project.basedir}/src/main/config</directory>
<outputDirectory>conf</outputDirectory>
<includes>
<include>*.properties</include>
</includes>
<filtered>true</filtered> <!-- ここに指定しても、親要素がResourceSetsなら通常有効 -->
</resourceSet>
</resourceSets>

前述の通り、Assembly Pluginでは <fileSets><filtered>true</filtered> オプションを使うのが一般的です。<resourceSets> を使用する特定の利点は少ないため、ここでは簡単な紹介に留めます。

デバッグとトラブルシューティング

Assembly Pluginの設定は複雑になりがちで、期待通りにファイルが配置されないなどの問題が発生することがあります。効果的なデバッグとトラブルシューティングの方法を知っておくことが重要です。

1. デバッグ出力の有効化

Mavenに -X オプションを付けて実行すると、詳細なデバッグログが表示されます。Assembly Pluginがどのファイルを含めようとしているか、どこに配置しようとしているか、なぜ特定のファイルが除外されたかなどの情報がログに出力されるため、問題の原因特定に非常に役立ちます。

bash
mvn clean package -X

-X オプションの出力は膨大になることがあるため、特定のPluginのログだけを絞り込みたい場合は、ログレベルをDEBUGに設定し、Pluginの logger を指定する方法もありますが、-X が最も手軽で一般的です。

2. 一般的なエラーとその原因

  • ファイルまたはディレクトリが見つからない (File or Directory Not Found):
    • 原因: <directory> 要素で指定したパスが存在しないか、間違っています。Mavenプロパティ(${project.basedir}, ${project.build.directory} など)が正しく展開されているか確認してください。
    • 解決策: パスを修正します。mvn help:evaluate -Dexpression=project.basedir のようにしてプロパティの値をMavenに確認することも有効です。
  • ファイルがアセンブリに含まれない (Files Not Included):
    • 原因: <includes> または <excludes> パターンが正しくない、<scope> 設定が意図しないものになっている、<useProjectArtifact> / <useTransitiveDependencies> が期待と異なる設定になっている、など。
    • 解決策: <includes>, <excludes> のパターンを確認します。<scope> を明示的に指定します。-X オプションでデバッグログを確認し、Assembly Pluginがファイルをスキャンしている様子や除外理由を確認します。
  • パーミッションが正しく設定されない (Permissions Not Set Correctly):
    • 原因: <fileMode><directoryMode> が正しく指定されていないか、出力形式(例: ZIP)がファイルパーミッションの設定をサポートしていない。
    • 解決策: パーミッション設定を確認します。TAR系形式(tar, tar.gz, tar.bz2)はパーミッションをサポートしますが、ZIP形式は限定的です。必要な場合は出力形式をTAR系に変更することを検討します。
  • 出力ファイル名が意図と異なる (Output File Names Different from Expected):
    • 原因: <outputFileNameMapping> が設定されているか、デフォルトのファイル名生成ルール(特に依存関係)が期待と異なる。
    • 解決策: <outputFileNameMapping> の設定を確認・修正します。それがなければ、Assembly Pluginのデフォルトのファイル名生成ルールを理解します。
  • jar-with-dependencies で実行可能JARにならない (Not an Executable JAR):
    • 原因: Assembly Pluginの jar フォーマットや jar-with-dependencies Descriptor Refは、依存関係を収集する機能が主であり、実行可能JAR(java -jar myapp.jar で実行できる形式)を作成する機能は持っていません。実行可能にするためには、META-INF/MANIFEST.MFMain-ClassClass-Path エントリを正しく設定する必要があります。Assembly Plugin単体では Class-Path を自動で適切に設定することは難しいため、通常は Maven Shade Plugin を使用して依存関係を単一の「Fat JAR」にバンドルし、Shade Pluginでマニフェストを設定します。
    • 解決策: 依存関係をバンドルして実行可能JARを作成する場合は、Maven Shade Pluginを使用することを検討してください。Assembly Pluginは、依存関係を分離した配布パッケージの作成に適しています。
  • マルチモジュールプロジェクトでモジュールが見つからない (Module Not Found in Multi-Module Project):
    • 原因: <moduleSet><includes>/<excludes> パターンが間違っているか、Pluginが実行されるタイミングで対象モジュールがまだビルドされていない。
    • 解決策: パターンを修正します。また、Pluginの <execution><phase> が、対象モジュールの成果物が生成されるフェーズ以降であることを確認します(通常は package フェーズ)。

3. Assembly Descriptor の検証

XML Descriptorファイルは、定義されたXML Schema (XSD) に従って検証できます。IDEによっては、XSDを指定することで入力補完や検証機能が利用可能です。Assembly Pluginの公式ドキュメントには、使用するPluginバージョンに対応するXSDファイルのURLが記載されています。Descriptorのルート要素である <assembly>xsi:schemaLocation 属性に正しいURLを指定することで、Descriptorの構文エラーを早期に発見できます。

例:
xml
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
<!-- ... -->
</assembly>

この schemaLocation が正しく設定されていれば、IDEがDescriptorの構文や要素名を検証してくれます。

高度なトピック

Assembly Pluginには、さらに柔軟なパッケージングを実現するための高度な機能がいくつかあります。

1. <component> 要素と <assemblies> 要素

複数のAssembly Descriptorで共通する <fileSets>, <dependencySets>, <moduleSets> などの定義がある場合、それらを <component> ファイルとして切り出し、再利用することができます。

<component> ファイルは <component> ルート要素を持ち、その中に <fileSets>, <dependencySets> などを定義します。このファイルを別途保存し(例: src/main/assembly/component/common-files.xml)、メインのAssembly Descriptorから参照します。

また、単一の pom.xml 設定で複数のアセンブリを作成したい場合、Pluginの <configuration> 内に <assemblies> 要素を使用し、その中に複数の <assembly> 定義を直接記述するか、外部のDescriptorファイルを参照します。

通常は、Assembly Descriptorファイルを複数作成し、それぞれをPluginの <configuration><descriptors> 要素を使って参照する方がシンプルで管理しやすいですが、特定のシナリオではこれらの機能が役立つことがあります。

2. 事前定義された Descriptor Ref

Maven Assembly Pluginは、いくつかの一般的なパッケージングパターンに対応する事前定義されたDescriptorを提供しています。これらを使用すると、Descriptorファイルを自分で作成せずに、Pluginの <configuration><descriptorRefs> 要素を使って参照するだけで、標準的なアセンブリを作成できます。

主な事前定義Descriptor Ref:

  • jar-with-dependencies: プロジェクト自身の成果物と、runtime スコープの依存関係をすべて集めたJARを作成します。前述の通り、これは実行可能JARを直接作成するわけではありません。
  • bin: 実行可能なバイナリ配布パッケージを作成します。プロジェクトの成果物、runtime スコープの依存関係、src/main/scripts のスクリプトなどが含まれます。通常、実行可能パーミッションが設定されます。
  • src: プロジェクトのソースコード、リソース、Descriptorファイルなどを集めたソース配布パッケージを作成します。
  • project: プロジェクト全体(ソース、バイナリ、ドキュメントなど)を配布するための包括的なパッケージを作成します。

これらのDescriptor Refを使用する例を次に示します。

xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
<descriptorRef>bin</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>

この設定では、mvn package 実行時に jar-with-dependenciesbin の2種類のアセンブリが作成されます。事前定義されたDescriptor Refは手軽ですが、カスタマイズ性が低いという側面もあります。独自の構造を持つアセンブリを作成する場合は、カスタムDescriptorファイルを作成するのが一般的です。

カスタムDescriptorを使用する場合、<descriptor> 要素と <descriptorRefs> 要素は同時に使用できます。

3. Maven Properties の活用

Assembly Descriptor内では、pom.xml で定義されたすべてのMavenプロパティや、標準のMavenプロパティ(${project.version}, ${project.artifactId}, ${project.build.directory}, ${project.basedir} など)を使用できます。これらを活用することで、Descriptorをより柔軟かつ汎用的に記述できます。

例:
<outputDirectory>${project.artifactId}-${project.version}</outputDirectory>

4. <repository> 要素

<repository> 要素を使用すると、リモートMavenリポジトリから特定のアーティファクトを取得し、アセンブリに含めることができます。これは、プロジェクトの依存関係として定義されていないアーティファクトを含めたい場合や、ローカルに存在しないアーティファクトを含めたい場合に稀に使用されます。しかし、通常はプロジェクトの依存関係として定義し、<dependencySets> で含める方がMavenの依存関係管理の仕組みに則しており、推奨されます。

xml
<assembly>
<!-- ... formats, id ... -->
<repositories>
<repository>
<outputDirectory>repo</outputDirectory> <!-- アセンブリ内の出力先 -->
<includes>
<include>com.example:external-tool:zip:bin:1.0</include> <!-- 特定のアーティファクトを指定 -->
</includes>
<!-- Repository element details (id, url, layout etc.) can be configured here -->
<!-- Or use settings.xml repositories -->
</repository>
</repositories>
<!-- ... fileSets, dependencySets etc. ... -->
</assembly>

この機能は特定の高度なシナリオでのみ使用されます。

実践的なユースケース

Maven Assembly Pluginは非常に柔軟であり、様々な成果物パッケージングのニーズに対応できます。いくつかの一般的なユースケースと、それに対応するAssembly Descriptorの考え方を示します。

1. 実行可能アプリケーション配布用ZIP/TARアーカイブ

この形式のアセンブリは、アプリケーションの実行に必要なすべての要素(実行スクリプト、設定ファイル、ライブラリ一式、プロジェクトの成果物JARなど)を一つのアーカイブにまとめます。ユーザーはこのアーカイブを展開し、スクリプトを実行するだけでアプリケーションを起動できるようになります。

Descriptorの構成例:

“`xml

<id>dist</id>
<formats>
    <format>zip</format>
    <format>tar.gz</format>
</formats>
<includeBaseDirectory>true</includeBaseDirectory> <!-- my-app-1.0.0/ -->

<fileSets>
    <!-- 実行スクリプトを bin/ ディレクトリに配置 -->
    <fileSet>
        <directory>${project.basedir}/src/main/scripts</directory>
        <outputDirectory>bin</outputDirectory>
        <includes>
            <include>run.sh</include>
            <include>run.bat</include>
        </includes>
        <fileMode>0755</fileMode>
    </fileSet>
    <!-- 設定ファイルを conf/ ディレクトリに配置(フィルタリングあり) -->
    <fileSet>
        <directory>${project.basedir}/src/main/resources</directory>
        <outputDirectory>conf</outputDirectory>
        <includes>
            <include>*.properties</include>
            <include>*.xml</include>
        </includes>
        <filtered>true</filtered>
    </fileSet>
    <!-- ルートディレクトリにREADMEなどを配置 -->
    <fileSet>
        <directory>${project.basedir}</directory>
        <outputDirectory>/</outputDirectory>
        <includes>
            <include>README.md</include>
            <include>LICENSE.txt</include>
        </includes>
    </fileSet>
</fileSets>

<dependencySets>
    <!-- プロジェクト自身の成果物JARを lib/ ディレクトリに配置 -->
    <dependencySet>
        <outputDirectory>lib</outputDirectory>
        <useProjectArtifact>true</useProjectArtifact>
        <unpack>false</unpack> <!-- JARは展開しない -->
    </dependencySet>
    <!-- ランタイム依存関係を lib/ ディレクトリに配置 -->
    <dependencySet>
        <outputDirectory>lib</outputDirectory>
        <scope>runtime</scope>
        <unpack>false</unpack>
    </dependencySet>
</dependencySets>


“`

このDescriptorを実行すると、以下のような構造を持つアーカイブが生成されます。

my-app-1.0.0/
├── bin/
│ ├── run.sh
│ └── run.bat
├── conf/
│ ├── application.properties (フィルタリング済み)
│ └── logback.xml (フィルタリング済み)
├── lib/
│ ├── my-app-1.0.0.jar (プロジェクトのJAR)
│ ├── spring-core-6.0.11.jar (依存ライブラリ)
│ └── ...
├── README.md
└── LICENSE.txt

2. サーバーデプロイメントパッケージ

アプリケーションサーバーや特定のランタイム環境にデプロイするための、特定のディレクトリ構造を持つパッケージを作成します。例えば、Tomcatの webapps に配置するWARファイル、あるいはカスタムランタイムの構造に合わせたディレクトリレイアウトなどです。

Descriptorの構成例(カスタムランタイム向け):

“`xml

<id>deploy</id>
<formats>
    <format>zip</format> <!-- あるいは dir -->
</formats>
<includeBaseDirectory>false</includeBaseDirectory> <!-- デプロイターゲットのルートに直接配置 -->

<fileSets>
    <!-- アプリケーションバイナリを app/ ディレクトリに配置 -->
    <fileSet>
        <directory>${project.build.directory}</directory>
        <outputDirectory>app</outputDirectory>
        <includes>
            <include>my-app-${project.version}.jar</include> <!-- プロジェクトの成果物JAR -->
        </includes>
    </fileSet>
    <!-- 設定ファイルを config/ ディレクトリに配置 -->
    <fileSet>
        <directory>${project.basedir}/src/main/config-deploy</directory> <!-- デプロイ環境固有の設定 -->
        <outputDirectory>config</outputDirectory>
        <includes>
            <include>**/*</include>
        </includes>
    </fileSet>
</fileSets>

<dependencySets>
    <!-- ランタイム依存関係を lib/ ディレクトリに配置 -->
    <dependencySet>
        <outputDirectory>lib</outputDirectory>
        <scope>runtime</scope>
    </dependencySet>
</dependencySets>

<moduleSets>
    <!-- もし他のモジュール(例: 共有ライブラリ)を含める必要があれば -->
    <!--
    <moduleSet>
        <includes>
            <include>com.example:shared-library</include>
        </includes>
        <binaries>
            <outputDirectory>lib</outputDirectory>
        </binaries>
    </moduleSet>
    -->
</moduleSets>


“`

この例では、ベースディレクトリを含めずに、出力先ディレクトリをデプロイターゲットの構造に直接マッピングしています。

3. SDK またはライブラリ配布パッケージ

他の開発者がプロジェクトをライブラリとして使用するためのSDKや配布パッケージを作成します。これには通常、ライブラリ本体のJAR、ソースコードJAR、Javadoc JAR、サンプルコード、ドキュメントなどが含まれます。

Descriptorの構成例:

“`xml

<id>sdk</id>
<formats>
    <format>zip</format>
</formats>
<includeBaseDirectory>true</includeBaseDirectory> <!-- my-library-sdk-1.0.0/ -->

<fileSets>
    <!-- サンプルコードを samples/ ディレクトリに配置 -->
    <fileSet>
        <directory>${project.basedir}/src/main/samples</directory>
        <outputDirectory>samples</outputDirectory>
        <includes>
            <include>**/*</include>
        </includes>
    </fileSet>
    <!-- ドキュメントを docs/ ディレクトリに配置 -->
    <fileSet>
        <directory>${project.build.directory}/docs</directory> <!-- Javadoc Pluginなどで生成 -->
        <outputDirectory>docs</outputDirectory>
        <includes>
            <include>**/*</include>
        </includes>
    </fileSet>
    <!-- READMEなどをルートに -->
    <fileSet>
        <directory>${project.basedir}</directory>
        <outputDirectory>/</outputDirectory>
        <includes>
            <include>README.md</include>
        </includes>
    </fileSet>
</fileSets>

<dependencySets>
    <!-- プロジェクト本体のJARを lib/ ディレクトリに配置 -->
    <dependencySet>
        <outputDirectory>lib</outputDirectory>
        <useProjectArtifact>true</useProjectArtifact>
        <includes>
            <include>${project.groupId}:${project.artifactId}:jar</include> <!-- メインJAR -->
        </includes>
    </dependencySet>
    <!-- ソースコードJARを lib/ ディレクトリに配置 -->
    <dependencySet>
        <outputDirectory>lib</outputDirectory>
        <useProjectArtifact>true</useProjectArtifact>
        <includes>
            <include>${project.groupId}:${project.artifactId}:jar:sources</include> <!-- sources分類子のJAR -->
        </includes>
    </dependencySet>
    <!-- Javadoc JARを lib/ ディレクトリに配置 -->
    <dependencySet>
         <outputDirectory>lib</outputDirectory>
         <useProjectArtifact>true</useProjectArtifact>
         <includes>
             <include>${project.groupId}:${project.artifactId}:jar:javadoc</include> <!-- javadoc分類子のJAR -->
         </includes>
     </dependencySet>
     <!-- 依存するライブラリも含める必要があれば -->
     <!--
     <dependencySet>
         <outputDirectory>lib/dependencies</outputDirectory>
         <scope>compile</scope>
     </dependencySet>
     -->
</dependencySets>


“`

この例では、プロジェクトの成果物(メインJAR、ソースJAR、Javadoc JAR)を <dependencySets><useProjectArtifact>true</useProjectArtifact><includes> の分類子指定を組み合わせて含めています。Javadoc JARやソースJARを生成するためには、通常、maven-source-pluginmaven-javadoc-plugin をビルドライフサイクルに組み込む必要があります。

これらのユースケースはあくまで例であり、Assembly Pluginの柔軟性をもってすれば、さらに多岐にわたる独自のパッケージング要件に対応可能です。重要なのは、Assembly Descriptor内で <fileSets>, <dependencySets>, <moduleSets> を適切に組み合わせ、目的とするファイル構造を定義することです。

ベストプラクティス

Assembly Pluginを効果的に使用するためのいくつかのベストプラクティスを挙げます。

  1. Assembly Descriptor はシンプルに保つ: 一つのDescriptorファイルにすべてのパッケージング要件を詰め込むのではなく、目的別に複数のDescriptorファイル(例: distribution.xml, sdk.xml, deploy.xml)を作成し、それぞれを特定のビルドプロファイルや実行に紐づけることを検討します。
  2. カスタム Descriptor は src/main/assembly に配置する: これはMavenの慣習であり、Descriptorファイルの発見容易性とプロジェクト構造の標準化に役立ちます。
  3. 出力ディレクトリ構造を明確にする: <outputDirectory> を適切に設定し、アセンブリ内のディレクトリ構造を分かりやすく整理します。特にライブラリ(lib/)、設定ファイル(conf/)、実行スクリプト(bin/)などの標準的なディレクトリ構造を採用すると良いでしょう。
  4. パーミッション設定に注意する: 実行可能なスクリプトなどには必ず適切な <fileMode> (例: 0755) を設定します。Windows環境ではパーミッションは無視されますが、Unix/Linux環境での配布を考慮する場合は重要です。
  5. 依存関係の管理: <dependencySets> を使用する際は、意図しない依存関係(特に推移的な依存関係や競合するバージョンの依存関係)が含まれないように、<scope>, <includes>, <excludes> を適切に設定します。Maven Dependency Pluginの mvn dependency:tree ゴールなどで依存関係ツリーを確認し、問題がないか検証することが推奨されます。
  6. Assembly Plugin と他の Plugin との使い分け:
    • Maven Shade Plugin: 依存関係を単一のJARにバンドルする「Fat JAR」や実行可能JARを作成したい場合は、通常Assembly PluginではなくShade Pluginを使用します。Assembly Pluginは、依存関係を個別のJARファイルとして特定のディレクトリに集める場合に適しています。
    • Maven Dependency Plugin: 依存関係のコピー、解析、リスト表示など、より低レベルな依存関係操作を行いたい場合はDependency Pluginを使用します。Assembly Pluginは、それらの依存関係を他のファイルと組み合わせてパッケージングする高レベルな機能を提供します。
    • Maven Resources Plugin: リソースファイルのフィルタリングはResource Pluginでも行えますが、Assembly Plugin内で <fileSets><filtered>true</filtered> を使うことで、Assembly Pluginの実行の一部としてリソース処理を完結できます。どちらを使うかはプロジェクト構造や好みに依存します。

まとめ

Maven Assembly Pluginは、Mavenプロジェクトのビルド成果物を柔軟かつ自動的にパッケージングするための強力なツールです。Assembly Descriptorを適切に定義することで、プロジェクトのファイル、依存関係、他のモジュールの成果物を組み合わせて、カスタムのディレクトリ構造を持つZIP, TAR, JARなどのアーカイブを作成できます。

本記事では、Assembly Pluginの基本的なセットアップから、Assembly Descriptorの構造、主要な設定要素である <fileSets>, <moduleSets>, <dependencySets> の詳細な使い方と設定例、デバッグ方法、高度な機能、そしていくつかの実践的なユースケースとベストプラクティスについて解説しました。

Maven Assembly Pluginを使いこなすことで、手作業で行っていた煩雑な成果物パッケージング作業を自動化し、ビルドプロセスを標準化できます。これにより、開発効率の向上、エラーの削減、そして安定したデプロイメントプロセスの実現に貢献するでしょう。

最初はDescriptorの書き方に戸惑うかもしれませんが、豊富な設定例を参考にしながら、試行錯誤を重ねてください。Mavenのデバッグオプション(-X)やDependency Pluginなどを活用することで、問題解決の糸口が見つかりやすくなります。

より複雑な要件や特定のPluginの挙動については、公式ドキュメントを参照することも重要です。本記事が、あなたがMaven Assembly Pluginを使いこなし、より洗練されたビルドプロセスを構築するための一助となれば幸いです。


コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

上部へスクロール