jarを一本化するonejar-maven-pluginを使ってみた

javaプロジェクトを簡単に単一jarファイルで配布する - lime55の日記」から
One-JARでアプリケーションの配布を単純化」経由で
Google Code Archive - Long-term storage for Google Code Project Hosting.」を見つけたので試してみる。

One-Jarの仕組みをごくおおざっぱに説明すると、

  1. Jarの中にJarが入れ子で入っている。
  2. 外側のJarのMainクラス=外側のJarに含まれる特別なクラスローダが起動される
  3. 入れ子になっている内側のJarをロードする
  4. 入れ子のMainクラスを起動する

という感じ。

これまで、「Mavenで配布用zipファイルを作成する - Sacrificed & Exploited」でいろいろな配布パッケージを作る方法を試したけど、jar一個ですむならそっちの方が楽だし。

onejar-maven-pluginの使い方

onejar-maven-pluginの使い方はここにある。

パターンAとパターンBの2つの方法があるみたい。

  • パターンAは、maven-jar-pluginでmainクラスを指定する。
  • パターンBは、onejar-maven-pluginでmainクラスを指定する。

という違いくらい。


以下のpom.xmlはパターンBの例で、「example.onejarexample.SearchFrame」をmainclassに指定している。

<project>
    ....
    <build>
        <plugins>
         ....
            <plugin>
                <groupId>org.dstovall</groupId>
                <artifactId>onejar-maven-plugin</artifactId>
                <version>1.4.1</version>
                <executions>
                    <execution>
                        <configuration>
                            <mainClass>example.onejarexample.SearchFrame</mainClass>
                            <!-- Optional -->
                            <onejarVersion>0.96</onejarVersion>
                            <!-- Optional, default is false -->
                            <attachToBuild>true</attachToBuild>
                            <!-- Optional, default is "onejar" -->
                            <classifier>onejar</classifier>
                        </configuration>
                        <goals>
                            <goal>one-jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
         ....
        </plugins>
    </build>

    <pluginRepositories>
        <pluginRepository>
            <id>onejar-maven-plugin.googlecode.com</id>
            <url>http://onejar-maven-plugin.googlecode.com/svn/mavenrepo</url>
        </pluginRepository>
    </pluginRepositories>
    ....
</project>

設定ファイルが読み込めない場合がある

プロパティファイルやXMLファイルの読み込み方法によって、onejar化した場合に設定ファイルを読み込めない場合がある。
クラスローダ経由(ClassLoader.getResource())でクラスパス上の設定ファイルを読み込んでいる場合は、外部ファイルのファイルをクラスローダの検索範囲に入れることが出来ないため、設定ファイルを読み込むことができない。

ファイルとして設定ファイルを直接オープンしている分には問題ない。

内側のjarに記述したManifestファイルが読み込まれないので、そこにClass-Pathの設定を記述しても無視されてしまうためらしい。入れ子になっているjar内に配置するとクラスパスに入るけど、これじゃあ設定ファイルの意味ないし....

まとめ

個人的にはちょっと使いどころの難しいプラグインだと思う。
設定ファイルも含めて配布するような場合、maven-jar-pluginとmaven-assembly-pluginを組み合わせた方が無難かなと。

  • メリット
    • jar-with-dependenciesのようにjarを分解せずに一つに出来る。
    • 実行可能JARとして作成できる。
  • デメリット
    • jarをダブルクリックで起動した場合、起動段階でエラーになっても気づかない。
    • コンソールアプリの場合、バッチファイルが別途必要になる。
    • 設定ファイルの読み込み方によっては、onejar化に向かない場合がある。