Posts for: #Maven

maven で executable jar を作る

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>

maven のバージョンチェック処理の振る舞い

23時に寝て1時に起きてまた寝て6時半に起きた。変なライフサイクルになってきた。

maven のアップデートポリシー

maven が依存解決するとき、例えばバージョンの範囲を指定して最新バージョンを取得するといった設定ができる。実行していると、新しいバージョンをチェックしにいくときとそうじゃないときがあって、どういう仕組みで動いているのかよくわからなかったのでデバッグした。言うても DEBUG ログを出力させて、ログの内容をソースで grep しながら関連するところを読んだだけ。

DefaultUpdateCheckManager.isUpdateRequired の中でポリシーが最終チェック日付を確認していいる。ここから辿っていくと ArtifactRepositoryPolicy という仕組みがある。

return ( lastCheckDate == null ) || policy.checkOutOfDate( lastCheckDate );

ドキュメントでそれっぽい内容を調べると updatePolicy を設定できるようになっている。デフォルトは daily なので日次でチェックしにいくような振る舞いをする。バージョンチェックするときとしないときの何が違うのか、よくわかっていなかった振る舞いを理解できた。これはビルドキャッシュの有無に関係ないのでキャッシュがあるからバージョンチェック処理をスキップできるわけではない。もちろん、更新をチェックさせたくないのであれば never に設定してもいいのかもしれない。

updatePolicy

The frequency for downloading updates - can be “always”, “daily” (default), “interval:XXX” (in minutes) or “never” (only if it doesn’t exist locally).

https://maven.apache.org/ref/3.6.3/maven-settings/settings.html