Java10上でEclipseLinkを動かすと、
Weaver encountered an exception while trying to weave class foo/bar/Baz. The exception was: null
という警告が出ることがあります。nullってなんだよおい。
調べた所、EclipseLinkが内部に保持しているASMのバージョンがJava10に対応していないために起きているようです。
masterブランチでは既にパッチが取り込まれた模様ですが、
これがリリースされるまでの凌ぎとして、おなじみのJavassistで無理やり解決してみました。
やったこと
まず、対象となるクラスは org.eclipse.persistence.internal.libraries.asm.ClassReader です。
該当箇所はここです。
public ClassReader(final byte[] b, final int off, final int len) { this.b = b; // checks the class version if (readShort(off + 6) > Opcodes.V9) { // ←コレ!!! throw new IllegalArgumentException(); } // parses the constant pool items = new int[readUnsignedShort(off + 8)]; int n = items.length; strings = new String[n]; int max = 0; ... }
確かにJava9までしか対応してませんね。(OpCodes.V9がJava9を表している)
というわけでJavassistでthrow new IllegalArgumentException()
を消せば…
と思ったらどうやら、Javassistはthrow文の置き換えに対応していないようです。ナンテコッタイ。
そこで、引数のbyte[] b
の中身を改変することにしました。だいたい次のような感じ。
CtClass ctc = ClassPool.getDefault().get(ClassReader.class.getName()); ctc.getDeclaredConstructors()[1].inserBeforeBody("{ " // // 中身を改変するので念のためコピーする + "$1 = (byte[]) $1.clone();" // // readShortで2バイト分見ている。先頭バイトは常にゼロなので2バイト目がバージョンを表す // 53はJava9のバージョン + "$1[$2 + 6 + 1] = (byte) 53;" // + "}");
これで例の警告は出ないようになりました。
2018-07-24追記
この問題はEclipseLink-2.7.2で解消されました。