4時に寝て7時に起きた。

maven での executable jar の作り方

gradle では作ったことがあったけど、maven では初めてなので要領がわかっていない。

これらの記事を読むと、maven-assembly-plugin を使えばいいのかな?とまずはこのプラグインで検証を始めた。古くからあるプラグインなので実績は十分なのだけど、もうあまり保守されていないのか、他プラグインから jar のマニフェストに書き込んで git のリビジョン番号が連携できてなかったり、通常の jar の生成処理を置き換えられなかったりと、あまり使い勝手のよいものではなかった。あと log4j2 と相性が悪くて意図したように設定ファイルを読み込んで初期化ができない。

main ERROR Error processing element EcsLayout: CLASS_NOT_FOUND
main ERROR Unable to locate plugin type for EcsLayout
main ERROR Unable to locate plugin for EcsLayout
main ERROR Could not create plugin of type class org.apache.logging.log4j.core.appender.ConsoleAppender for element Console:
  java.lang.NullPointerException: Cannot invoke "org.apache.logging.log4j.core.config.plugins.util.PluginType.getElementName()"
  because "childType" is null java.lang.NullPointerException:
    Cannot invoke "org.apache.logging.log4j.core.config.plugins.util.PluginType.getElementName()" because "childType" is null

この厄介な問題をデバッグするよりも、すでにうまくいくことがわかっている spring-boot-maven-plugin を使った方が簡単そうだったのでそうすることにした。不要な spring boot 関連の jar なども executable jar や docker イメージに含まれてしまうことだけがデメリット。そこだけ目を瞑れば log4j2 の初期化エラーも起きず、正常に動作した。やっぱり最近のアプリケーションで使われているプラグインはちゃんとしてるねみたいな話しにしておく。次の設定だけでうまくいった。

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <mainClass>com.example.myapp.Main</mainClass>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>repackage</goal>
            </goals>
        </execution>
    </executions>
</plugin>