GroovyでMavenで単一の配布可能なjar作成 (4)

  技術情報

これまでは依存したすべてのjarを一つにまとめた fat-jar を作成する方向性でした。そのため、配布された側は自分でjavaコマンドを実行する必要がありました。

windows向けバッチやunix向けスクリプトを生成してくれるプラグインがあることを知ったので、それを適用してみることにしました。

ツールを利用する側はjarの実行の仕方なんか興味ないわけで、やはり即実行可能なバッチやスクリプトの形であるに越したことないですもんね。

Maven でアプリケーション実行用バッチファイルを作る – A Memorandum

https://blog1.mammb.com/entry/20101206/1291619754

まず、fat-jarが不要になるので、project>build>plugins内のmaven-assembly-pluginの定義は削除します。

<!-- fat-jarが不要になるので、maven-assembly-pluginの定義は削除
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-assembly-plugin</artifactId>
        <executions>
            <execution>
                <phase>package</phase>
                <goals>
                    <goal>single</goal>
                </goals>
            </execution>
        </executions>
        <configuration>
            <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
            </descriptorRefs>
            <archive>
                <manifest>
                    <mainClass>MediaRqstGetter</mainClass>
                </manifest>
            </archive>
        </configuration>
    </plugin>
-->

代わりに project>dependencies内にappassembler-maven-pluginの依存定義に追加します。

<!-- dependencies -->
        <!-- https://mvnrepository.com/artifact/org.codehaus.mojo/appassembler-maven-plugin -->
        <dependency>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>appassembler-maven-plugin</artifactId>
            <version>2.1.0</version>
        </dependency>

次に project>build>plugins配下に appassembler-maven-pluginの処理の定義を記述します。
シンプルな実行スクリプトの他に、デーモン(Javaで作ったサービス)のラッパーやなんかもサポートしているみたいですが、今回は単純な方で。

    <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>appassembler-maven-plugin</artifactId>
        <configuration>
            <programs>
                <program>
                    <mainClass>info.komina.MyApp</mainClass>
                    <id>runapp</id>
                </program>
            </programs>
            <binFileExtensions>
                <unix>.sh</unix>
                <windows>.cmd</windows>
            </binFileExtensions>
            <repositoryName>lib</repositoryName>
            <repositoryLayout>flat</repositoryLayout>
            <useWildcardClassPath>true</useWildcardClassPath>
            <environmentSetupFileName>setenv</environmentSetupFileName>
            <includeConfigurationDirectoryInClasspath>false</includeConfigurationDirectoryInClasspath>
        </configuration>
        <executions>
            <execution>
                <goals>
                    <goal>assemble</goal>
                </goals>
                <phase>package</phase>
            </execution>
        </executions>
    </plugin>
configulationタグ説明
programs>program>mainClass実行クラスを完全修飾で指定
programs>program>idスクリプトの名前になります
binFileExtensions任意。生成するスクリプトの拡張子をプラットフォーム毎に指定します。デフォルトでunixは無し、windowsはbatです。
repositoryName任意。依存するjarを配置するフォルダ名です。デフォルトは/repoです。
repositoryLayout任意。依存するjarの置き方です。デフォルトは階層構造です。ここでは階層構造だとクラスパスの文字列長が長くなり問題が起きるので、useWildcardClassPathのtrue設定と合わせてflat指定しています。
useWildcardClassPath任意。クラスパスでワイルドカードを使用するかの設定。デフォルトはfalseです。
environmentSetupFileName任意。環境設定用スクリプトの名前です。生成されるスクリプトを実行する際にファイルが存在すれば呼び出されます。
includeConfigurationDirectoryInClasspath任意。コンフィグファイル用のディレクトリをクラスパスに含める機能がありますが今回は不要なのでfalseにしています。

ここで環境設定用スクリプトという言葉が出てきますが、これは生成されるスクリプトを実行時に呼び出されるユーザ定義のスクリプトのことです。

細かい制御をしたいとき、追加で環境変数を設定したいとき、などに利用できます。もちろんunix/windows必要なスクリプトを自分で用意しなければなりません。

環境設定用スクリプトは生成されるスクリプトと同じフォルダに置かれている必要がありますが、mavenの出力先はcleanなどの実行でしょっちゅう削除される場所ですので、別の場所からビルドのたびにコピーを行います。

ファイルのコピーはantプラグインにやらせるのが簡単ですので、maven-antrun-plugin定義に下記処理を追加します。

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-antrun-plugin</artifactId>
        <executions>
            :
            <execution>
                <goals>
                    <goal>run</goal>
                </goals>
                <phase>package</phase>
                <configuration>
                    <tasks>
                        <echo message="copy files for appassembler"/>
                        <copy toDir="${build.directory}/appassembler/bin" overwrite="yes">
                            <fileset dir="${basedir}/resources-appassembler" />
                        </copy>
                    </tasks>
                </configuration>
            </execution>
        </executions>
    </plugin>

これでpackage処理の際に/resources-appassembler配下に置いたファイルが /target/appassembler/bin 配下にコピーされるようになります。

/target/appassembler配下のファイルをまとめて配布することで、javaやgroovyで作ったプログラムを簡単に実行できる形で提供できます。

あ、unixのスクリプトについてはchmodで実行属性を付けるのを忘れずに。(環境設定用スクリプトの方は付けなくても大丈夫でした)

以上です。

参考

Appassembler :: Maven Plug-In – appassembler:assemble
(設定についての説明)

https://www.mojohaus.org/appassembler/appassembler-maven-plugin/assemble-mojo.html

Mavenのappassembler-maven-pluginでJAVA_HOMEを設定する方法 – Qiita

https://qiita.com/Rozsa777/items/a44b88a6daf8e1fc98e7

Re: [mojo-user] Appassembler-maven-plugin JAVA_HOME question

https://www.mail-archive.com/user@mojo.codehaus.org/msg03990.html

LEAVE A COMMENT