JDK 21とmockitoとbyte-buddyの警告とsbtとjavaagent (original) (raw)

JDK 21以降、mockito使うとなんか怒られますが、それのsbtでの対策や解決方法を簡単に書きます

怒られるというのは以下。

openjdk.org

javaにはagentという、実行時だったり起動時にclassをゴニョゴニョする仕組みがあります。

起動時とかにやるのに、明示的に引数指定する場合もあります

(本来の用途あまり説明してないが、以下に以前書いた)

xuwei-k.hatenablog.com

そして、なんと引数で指定がなくても動的にやる仕組みが存在します、すごいですね(?)

詳細に興味がある人はたとえば以下を読んでみましょう。

https://www.oracle.com/webfolder/technetwork/jp/javamagazine/Java-ND15-ByteBuddy.pdf

しかし、おそらくJDK 21からそれは流石にやばいだろ!(超雑な要約)、みたいなお気持ちにより、非推奨にしていくか、というのが上記のJEP 451です。

さて、mockitoはたとえばfinal classを無理やりmockするためとかその他色々により、この動的なjava agent有効化を使っていたので、JEP 451にモロに影響を受けます。 それで警告が出ます。

JDK 21時点ではまだ警告なので、放置しても動くには動きますが、将来のことを考えると今のうちから直した方がいいでしょう。

それで、直し方の方針として、自分が思いついてるのは主に2つで

のどちらかです。ここから先はsbt前提の設定例の話をします。

無理やり除く方ですがたとえば

libraryDependencies += "org.mockito" % "mockito-subclass" % "5.14.1" % Test exclude ("net.bytebuddy", "byte-buddy-agent")

というイメージです。ただし、これはあくまで動的なjava agentの有効化の機能を使ってない場合の話だし、mockitoの種類(coreかsubclassか?)やversionによっては、急に壊れる可能性もあります。

次に明示的に引数として指定する場合ですが、独自に頑張ってもいいですが、これはsbt plugin使ってしまった方が一応楽でしょう。

project/plugins.sbt

addSbtPlugin("com.github.sbt" % "sbt-javaagent" % "0.1.8")

build.sbt

val mockito = "org.mockito" % "mockito-core" % "5.14.1" % Test

enablePlugins(JavaAgent)

javaAgents += mockito

libraryDependencies += mockito

少し前のversionまでは、実際にjava agentとして動作するのはmockito自体ではなくそれが依存しているbyte-buddyだったのですが、それを指定するのは不便ということで、 このblog書いてる時点でつい最近出たversion 5.14.0から、mockito自身もjavaagentとして動作する(byte-buddyにdelegateする?)変更が入ったようです。

github.com