ひだまりソケットは壊れない

ソフトウェア開発に関する話を書きます。 最近は主に Android アプリ、Windows アプリ (UWP アプリ)、Java 関係です。

まじめなことを書くつもりでやっています。 適当なことは 「一角獣は夜に啼く」 に書いています。

MockK と JMockit の組み合わせで AttachNotSupportedException 例外が発生することがあるっぽい

Kotlin で Mockito を使うのが辛くなってきた *1 ので、「よーしパパ MockK 入れちゃうぞー」 と言って MockK 1.8.12 を導入したのだけど、その結果テストを実行すると以下のような初期化エラーが発生するようになってしまった。

java.lang.ExceptionInInitializerError
	at MyTest.<init>(MyTest.kt:101)
Caused by: java.lang.IllegalStateException: Error during attachment using: net.bytebuddy.agent.ByteBuddyAgent$AttachmentProvider$Compound@718207
	at net.bytebuddy.agent.ByteBuddyAgent.install(ByteBuddyAgent.java:384)
	at net.bytebuddy.agent.ByteBuddyAgent.install(ByteBuddyAgent.java:358)
	at net.bytebuddy.agent.ByteBuddyAgent.install(ByteBuddyAgent.java:326)
	at net.bytebuddy.agent.ByteBuddyAgent.install(ByteBuddyAgent.java:312)
	at io.mockk.proxy.jvm.JvmMockKAgentFactory.initInstrumentation(JvmMockKAgentFactory.kt:122)
	at io.mockk.proxy.jvm.JvmMockKAgentFactory.init(JvmMockKAgentFactory.kt:31)
	at io.mockk.impl.JvmMockKGateway.<init>(JvmMockKGateway.kt:45)
	at io.mockk.impl.JvmMockKGateway.<clinit>(JvmMockKGateway.kt:163)
	... 22 more
Caused by: java.lang.reflect.InvocationTargetException
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at net.bytebuddy.agent.Attacher.install(Attacher.java:84)
	at net.bytebuddy.agent.ByteBuddyAgent.install(ByteBuddyAgent.java:379)
	... 29 more
Caused by: com.sun.tools.attach.AttachNotSupportedException: no providers installed
	at com.sun.tools.attach.VirtualMachine.attach(VirtualMachine.java:208)
	... 35 more

スタックトレースの一番下を見ると com.sun.tools.attach.VirtualMachine なので、JDK の内部でなんかなってるのかなー、と最初は思っていたのだけど、IDE で辿っていくと VirtualMachine クラスは JMockit に含まれているものだということがわかった。 使っていた JMockit が 1.22 と少し古いものだったので、最新の 1.43 を使うようにしたら無事エラーは発生しなくなった。

Mockito でも同様のエラーが発生することがある模様。

ちなみに com.sun.tools.attach.VirtualMachine は、JVM にアタッチするための API に含まれるものらしい。