理系学生日記

おまえはいつまで学生気分なのか

Maven Assembly Pluginで実行可能jarをつくる

maven assembly plugin

maven 力も Java 力も貧弱なのだけれど、依存性を 1 つにまとめた実行可能 jar を作る必要性に駆られたので、ちょっと調べてた。 maven の plugin で実行可能 jar を作ろうとすると、以下の 2 つがメジャー。

  1. Maven Assembly Plugin
  2. Maven Shade Plugin

両方ともに、いわゆる uber-jar とか Fat Jar とか言われている、依存関係をすべて 1 つにまとめた Jar を作成することはできるのだけれど、それを主目的と考えると後者の Maven Shade Plugin の方が合致する。これは主に以下のような機能によるものらしいが、bytecode を置き換えるとかいうヤバげな文字も見えたので、そっ閉じした。

というわけで、Maven Assembly Plugin をまずは使いましょう。

assembly とは何か

Maven Assembly Plugin の言う "assembly" というのは、ファイルやディレクトリ、モジュールが依存している jar などを含めたアーカイブのことで、これを作り出すことが maven assembly plugin の目的。

"assembly" の形式

plugin に予め定義されている assembly の形式としては以下のような 4 つがあって、maven の descriptorRef で記述することができる。

  • bin
    • mvn package で作成される jar ファイルと、README、LICENSE、NOTICE といったファイルをアーカイブしてくれる。フォーマットとしては、tar.gztar.bz2zip が選択できる。 もうちょっと具体的に言うと、${project.basedir} 配下の README*LICENSE*NOTICE* と、${project.build.directory} 配下の jar ファイルがアーカイブされる。
  • jar-with-dependencies
    • 依存している jar ファイルを含めた "uber-jar" を作成してくれる。uber-jar については後述するけど、いわゆる fat jar のこと。
  • src
    • こっちはその名の通り、pom のプロジェクトのソースファイル群をアーカイブしてくれる。 もうちょっと具体的に言うと、${project.basedir} 配下の README*LICENSE*NOTICE*pom.xml${project.basedir}/src 配下のファイルが格納される。
  • project
    • pom で管理しているプロジェクトをそのまま assembly にする。
    <configuration>
      <descriptorRefs>
        <descriptorRef>jar-with-dependencies</descriptorRef>
      </descriptorRefs>
    </configuration>

もちろん、今回の目的に叶うのは jar-with-dependencies ではあるのだけれど、この「予め定義されている」descriptor だと今後の細かなカスタマイズができない。 そういう場合は、Assembly Descriptor を自作すれば良い。

依存関係をすべて含めた Assembly Descriptor

Assembly Descriptor はその名前のとおりで "Assembly" がどういうものかを記述するもので、基本的には「どのファイルを」「どこに配置する」Assembly なのかを記述していけば良い。 ぼくの用途はいまのところ jar-with-dependencies とほとんど変わらず、

  1. runtime スコープにある依存 jar をすべて含む

ということくらいしかやることないので、以下のようなファイルをつくって、vault-assembly.xml とかで保存して src/assembly 配下に保存してやった。

<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">
    <id>vault</id>
    <formats>
        <format>jar</format>
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>
    <dependencySets>
        <dependencySet>
            <outputDirectory>/</outputDirectory>
            <useProjectArtifact>true</useProjectArtifact>
            <unpack>true</unpack>
            <scope>runtime</scope>
        </dependencySet>
    </dependencySets>
</assembly>

Manifest ファイル

実行可能 jar をつくるためには Manifest ファイルの Main-Class エントリを作成する必要があるけど、Maven Assembly Plugin には archive の設定でこれを記述することができる。

なので、Assembly Descriptor を含め pom.xml に指定してやれば良い。

<configuration>
    <finalName>vault-${project.version}</finalName>
    <appendAssemblyId>false</appendAssemblyId>
    <descriptors>
        <descriptor>src/assembly/vault-assembly.xml</descriptor>
    </descriptors>
    <archive>
        <manifest>
            <mainClass>com.kiririmode.vault.util.Main</mainClass>
        </manifest>
    </archive>
</configuration>
<executions>
    <execution>
        <id>make-assembly</id>
        <phase>package</phase>
        <goals>
            <goal>single</goal>
        </goals>
    </execution>
</executions>

#

参考文献