Mavenで配布用zipファイルを作成する

mavenで依存ライブラリや設定用ファイル、バッチファイルなどを含んだ配布用zipファイルを作る方法をメモしておく。

配布物のディレクトリ構成

以下のような構成の配布物を作成します。


    +bin/
        +sample.bat          <----起動用バッチファイル(windows用)
        +sample              <----起動用バッチファイル(unix用)
    +config/
        +config.xml          <----設定ファイル
        +config.xsd
        +backlog.xml         <----backlogの設定ファイル
    +lib/
        +sample-0.0.1.jar    <----実行対象のjar
        +依存しているjar

実行方法のバリエーションについて

jarに格納されたクラスを実行するには、以下のようなバリエーションがあります。

  • 依存ライブラリを統合した実行可能なjarを作成し、-jarオプションの引数に指定して起動する。
  • 依存ライブラリを分離した実行可能なjarを作成し、-jarオプションの引数に指定して起動する。
  • バッチファイルでクラスパスを設定し、mainメソッドを持つクラスを指定して起動する。

このメモでは全てのパターンについて例を示します。

実行可能Jarを使う際、気をつけなければならないのは、-jarオプションを使って起動した場合は、-classpath引数やCLASSPATH環境変数が無視される事です。詳細は2006-09-08を参照してください。

依存ライブラリを統合した実行可能なjarを作成する

maven-assembly-pluginを使って作成します。
maven側で用意しているassembly descriptor「jar-with-dependencies」を使って、少し設定を追加するだけです。

以下の設定例では、

  • マニフェストファイルのMain-Classに「sample.Main」クラスを指定
  • マニフェストファイルのClass-Pathに「../config/」を指定
    • 個々で指定するClass-Pathはjarからの相対パスになります。
  • packegeフェーズにmaven-assembly-pluginのsingleゴールを実行
    • コマンドラインで「mvn package」と入力すれば、依存ライブラリを統合した実行可能なjarが作成されます。

という設定しています。

この例のパッケージ作成例は示しませんが、libフォルダに依存ライブラリを統合した「sample-0.0.1-jar-with-dependencies.jar」ファイルをおいて実行するような設定にしています。

<build>
    <plugins>
         ....
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <archive>
                        <manifest>
                            <mainClass>sample.Main</mainClass>
                        </manifest>
                        <manifestEntries>
                            <Class-Path>../config/</Class-Path>
                        </manifestEntries>
                    </archive>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
         ....
    </plugins>
</build>

依存ライブラリを分離した実行可能なjarを作成する

maven-jar-pluginを使って実行可能Jarを作成します。
実行可能Jarにするために、マニフェストファイルの設定を追加する必要があり、これは配布する際のフォルダ構成に合せる必要があります。

また、この設定は普通に生成されるjarにだけ適用され、jar-with-dependenciesで生成されるjarファイルには適用されません。

この設定で作成されるファイルには、依存ライブラリが含まれないため、実行するためには依存ライブラリを含めた配布パッケージの作成が必要です。

addClassPathの指定が追加されているだけで、「依存ライブラリを統合した実行可能なjarを作成する」との違いはありません。

<build>
    <plugins>
        ....
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>2.3</version>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <mainClass>sample.Main</mainClass>
                        </manifest>
                        <manifestEntries>
                            <Class-Path>../config/</Class-Path>
                        </manifestEntries>
                    </archive>
                </configuration>
            </plugin>
         ....
    </plugins>
</build>

実行用バッチファイルを作る

実行用バッチファイルを作るには、appassembler-maven-pluginを使います。

特にJavaVMの最大ヒープメモリ容量を増やしたいとか、そういったJavaVMオプションを指定したい場合に便利です。

まずはcodehausプラグインレポジトリをpom.xmlに追加します。

    <pluginRepositories>
        <pluginRepository>
            <id>Codehaus repository</id>
            <url>http://repository.codehaus.org/</url>
        </pluginRepository>
    </pluginRepositories>

次にappassembler-maven-pluginの設定を示します。
例では次のような設定をしています。

  • バッチファイルのみつかうため、generateRepositoryをfalseにして依存ライブラリの格納を無効にしています。
    • trueにすれば、依存ライブラリをtarget/appassembler/lib以下に格納します。
  • packegeフェーズにappassembler-maven-pluginのassembleゴールを実行
  • 生成されたバッチファイルは、target/appassembler/bin以下に配置されます。
<build>
    <plugins>
        ....
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>appassembler-maven-plugin</artifactId>
                <version>1.0</version>
                <configuration>
                    <repositoryLayout>flat</repositoryLayout>
                    <repositoryName>lib</repositoryName>
                    <configurationDirectory>config</configurationDirectory>
                    <generateRepository>false</generateRepository>
                    <installArtifacts>false</installArtifacts>
                    <extraJvmArguments>-Xmx512m</extraJvmArguments>
                    <programs>
                        <program>
                            <mainClass>sample.Main</mainClass>
                            <name>sample</name>
                        </program>
                    </programs>
                </configuration>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>assemble</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
        ....
    </plugins>
</build>

配布用パッケージを作る

maven-jar-pluginを使います。個別にassembly-descriptorを作る必要があります。

次の例は、「依存ライブラリを統合した実行可能なjarを作成する」の例にassembly-descriptorの設定を追加しただけです。

<build>
    <plugins>
         ....
           <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <descriptors>
                        <descriptor>src/main/assembly/descriptor-bin.xml</descriptor>
                    </descriptors>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <archive>
                        <manifest>
                            <mainClass>sample.Main</mainClass>
                        </manifest>
                        <manifestEntries>
                            <Class-Path>config/</Class-Path>
                        </manifestEntries>
                    </archive>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
         ....
    </plugins>
</build>

次にassembly-descriptorの例を示します。
以下のような設定をしています。

  • maven-appassembler-pluginが生成したバッチファイルを、配布物のbinディレクトリにコピーするようにしています。
  • プロジェクトのconfigディレクトリから、xml,xsd,propertiesの拡張子を持つファイルを、配布物のconfigディレクトリにコピーするようにしています。
  • 依存しているライブラリを、配布物のlibディレクトリにコピーするようにしています。
    • maven-appassembler-pluginが生成する依存ライブラリではなく、assembly-descriptorの依存ライブラリを使う設定にしています。
<?xml version="1.0" encoding="UTF-8"?>
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
    <id>bin</id>
    <formats>
        <format>zip</format>
    </formats>
    <fileSets>
        <fileSet>
            <directory>target/appassembler/bin</directory>
            <outputDirectory>bin</outputDirectory>
        </fileSet>
        <fileSet>
            <directory>config</directory>
            <outputDirectory>config</outputDirectory>
            <includes>
                <include>*.xml</include>
                <include>*.xsd</include>
                <include>*.properties</include>
            </includes>
        </fileSet>
    </fileSets>
    <dependencySets>
        <dependencySet>
            <outputDirectory>lib</outputDirectory>
        </dependencySet>
    </dependencySets>
</assembly>