コンテキスト: 実行時に、Barという新しいクラスがJVMに注入されます。このクラスはcom.fooというパッケージに属します。 このクラスへの参照は、同じパッケージに属する別のクラスに注入されます。 新しいクラスは読み込まれるたびに別の名前を持つ可能性があります。したがって、これは設定ファイルの一部として指定することはできません。 jarファイルの一部としてbuild.xmlに指定することはできません。新しく挿入されたクラスのクラスパスを設定する
問題: クラスロード時に、jvmがエラーをスローします - java結果1.根本的な原因を突き止めることはできませんが、新しく挿入されたクラスがクラスローダーによって見つからないようです。 サーバーは冗長モードで実行され、JVMによってロードされたクラスのリストが表示され、この新しく挿入されたクラスがロードされたと見なされます。
質問: 新しく注入されたクラスは既にクラスパスにありますか?それを設定する方法でない場合は?
[編集] - 質問にいくつかのコードを追加します。
コードセグメント - 1:このコードセグメントは、PreMainメソッドから呼び出されます。 - Premainメソッドは、JVMエージェントによって呼び出され、実行時に計測リファレンスを注入します。 Premainメソッドは、1つの新しいクラス(Bar)と既存のクラス(ExistingClass)のreturnsABool()から、この新しいクラスへの参照を1つ注入します。
public static void premain(String agentArgs, Instrumentation inst) {
// 1. Create and load the new class - Bar
String className = "Bar";
byte [] b = getBytesForNewClass();
//override classDefine (as it is protected) and define the class.
Class clazz = null;
try {
ClassLoader loader = ClassLoader.getSystemClassLoader();
Class cls = Class.forName("java.lang.ClassLoader");
java.lang.reflect.Method method =
cls.getDeclaredMethod("defineClass", new Class[] { String.class, byte[].class, int.class, int.class });
// protected method invocation
method.setAccessible(true);
try {
Object[] args = new Object[] { className, b, new Integer(0), new Integer(b.length)};
clazz = (Class) method.invoke(loader, args);
} finally {
method.setAccessible(false);
}
} catch (Exception e) {
System.err.println(
"AllocationInstrumenter was unable to create new class" + e.getMessage());
e.printStackTrace();
}
// 2. Inject some lines of code into the returnsABool method in ExistingClass class that references Bar
inst.addTransformer(new CustomInstrumenter(), true);
// end of premain method
}
コードsement 2:方法returnsABool()は以下に示すコメント 線とバイト注入する必要があります。これをバイトインジェクトするコードは、PreMainメソッドからも呼び出されます。 ExistingClassため
public class ExistingClass{
public static boolean returnsABool() {
// Code within comments is byte-injected, again as part of the pre-main method
/*
String str = Bar.get();
if (str != "someValue") {
return true;
}
*/
return false;
}
}
バイト・コードインジェクション - 私はあなたがあなたのバイトコード生成と間違って何かを持っている疑いがあるでしょうASMライブラリに
{
MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions);
mv.visitCode();
Label l0 = new Label();
mv.visitLabel(l0);
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "com/Bar", "get", "()Ljava/lang/String;");
mv.visitLdcInsn("some constant here");
Label l1 = new Label();
mv.visitJumpInsn(Opcodes.IF_ACMPNE, l1);
mv.visitInsn(Opcodes.ICONST_0); Label l2 = new Label();
mv.visitJumpInsn(Opcodes.GOTO, l2);
mv.visitLabel(l1);
mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
mv.visitInsn(Opcodes.ICONST_1);
mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {Opcodes.INTEGER});
mv.visitInsn(Opcodes.IRETURN);
mv.visitMaxs(2, 0);
mv.visitEnd();
}
どのように具体的には、クラスは "注射"されていますか?それは動的に作成され、クラスローダーによって読み込まれますか? –
いくつかのJavaコードが役に立ちます。そうでなければ、あなたを助けることは非常に困難です。また、おそらくこの質問は役に立ちます:http://stackoverflow.com/q/4210346/74694 –
あなたが持っている問題を示す最小限の例を示してください。 –