私はasmライブラリを使用して、いくつかのJavaバイトコードの変更を実行しています。具体的には、クラスを変更して新しいインタフェースと関連メソッドを実装することです。私の現在のアプローチは、javaagentを介してコアのasm APIを使用しています。私は静的に.classファイルを変更するのではなく、この動的なアプローチを維持したいと思います。Asmコード内からInstrumentation.retransformClasses()を正しく使用するにはどうすればよいですか?
私の問題は、Bから拡張されたクラスAを変更する場合、Bも変更する必要があるということです。(クラスがJVMでどのようにロードされるのか理解しているので、 Bは常にクラスAの前にトランスフォーマーに渡されます(私が間違っていれば私を修正してください)。その前提を前提に、私は戻って行く必要があると考えています。retransform B.私のアプローチはこのコードのビット:
public byte[] transform(ClassLoader l, String name, Class<?> clazz, ProtectionDomain d, byte[] b) {
throws IllegalClassFormatException {
// **1**
System.out.println("--->>> " + name);
if (interestingClass(name)) {
try {
ClassReader cr = new ClassReader(b);
ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
PyClassVisitorAdapter pv = new PyClassVisitorAdapter(cw, name);
cr.accept(pv, 0);
// **2** Retrieve the superclass and try to transform that
if (! "Ljava/lang/Object;".equals(pv.getSuperName())) {
String cName = classJvmToCanonical(pv.getSuperName());
Class[] classes = inst.getAllLoadedClasses();
for (Class c : classes) {
if (c.getName().equals(cName)) {
inst.retransformClasses(c);
break;
}
}
}
// Dump the transformed class
ClassReader cr2 = new ClassReader(cw.toByteArray());
ClassWriter cw2 = new ClassWriter(cr2, 0);
TraceClassVisitor tcv = new TraceClassVisitor(cw2, new PrintWriter(System.out));
cr2.accept(tcv, 0);
return cw2.toByteArray();
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
} else {
return b;
}
}
(
inst
は、コンストラクタに渡されます
Instrumentation
へのハンドルです)
私は苦労している部分は、コメントに**2**
とマークされたブロックです。 AがBを拡張し、Aを変換するのに興味があるとしましょう。私が期待しているのは、**1**
にスーパークラス(B)の名前が印刷されているのがわかります。私が**2**
になったら、AのスーパークラスがBであることを発見すると、私はBを再変換しようとしているはずです。この時点で、このメソッドは(inst.retransformClasses()
を介して)もう一度呼び出されることを期待しています。私はBが**1**
に印刷されるのを見るだろう。しかし、私はしません。 (私は印刷ステートメントを追加して、再変換呼び出しに到達していることを確認しました。また、Instrumentation.isRetransformClassesSupported()
とInstrumentation.isModifiableClass(c)
の両方がtrueを返すことも確認しました)。
私はエージェントを正しくセットアップしたと信じています。マニフェストでCan-Retransform-ClassesとCan-Redefine-Classesを両方ともtrueに設定します。私はここで間違ってやっているものになどの任意の洞察力
public static void premain(String agentArgs, Instrumentation inst) {
inst.addTransformer(new PyClassFileTransformer(inst), true);
}
:私はエージェントのpremain
方法で計測する変圧器を追加するときも、私はこれを行いますか?ありがとう。
あなたは問題を解決しましたか? @Jens私はいくつかのアドバイスを与えるために[ここ](http://stackoverflow.com/questions/18657095/got-unsupportedoperationexception-when-try-to-retransformclasses)行くことができますか? –