javassist 在 pre-main 方法中加载类文件(java instrumentation)

2022-09-03 14:48:17

我正在尝试使用javassist加载一个特定的类,我在pre-main方法中执行此操作,如下所示:

public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
                        ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException 
{
   byte[] byteCode = classfileBuffer;

   if(className.toLowerCase().endsWith("class1"))
   {
       ClassPool classPool = ClassPool.getDefault();
       CtClass ctClass = classPool.get("com.class2");
   }
}

但不幸的是,我得到了一个NotFoundException....

com.class2 是一个类,在装入 class1 后将由类装入器装入,但是我为 class1 添加了一个新方法,该方法的返回类型为 com.class2

我尝试了 stackoverflow.com 中的所有解决方案,但没有任何结果.....

最后,class1 和 class2 都在同一个包中,并且在同一个 JAR 文件中,class1 有一个 class2 类型的成员,但我不知道为什么这个 classpool 不能加载第二个。

此处的堆栈跟踪:

Exception: javassist.NotFoundException: com.Class2
 javassist.NotFoundException: com.Class2
at javassist.ClassPool.get(ClassPool.java:439)
at javassist.ClassPool.getCtClass(ClassPool.java:504)
at com.stuff.MainAppletTransformer.transform(MainAppletTransformer.java:69)
at sun.instrument.TransformerManager.transform(Unknown Source)
at sun.instrument.InstrumentationImpl.transform(Unknown Source)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader.defineClassHelper(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader.access$100(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader$2.run(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader$2.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.plugin2.applet.Plugin2ClassLoader.findClassHelper(Unknown Source)
at sun.plugin2.applet.Applet2ClassLoader.findClass(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader.loadClass0(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader.loadClass(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader.loadCode(Unknown Source)
at sun.plugin2.applet.Plugin2Manager.initAppletAdapter(Unknown Source)
at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

答案 1

您的方法没有返回值,因此不会编译。但是,我仍然可以判断出了什么问题:您没有设置正确的搜索路径。从您的堆栈跟踪中,您似乎正在运行一个由特定.在当前版本中,此类装入器对 Javassist 不可见。ClassLoader

通过使用,您可以从系统类路径中查找信息。对于您的小程序,您可能需要添加由 transformatio 方法移交的类装入器作为参数。ClassPool.getDefault()

您可以将类装入器附加到 Javassist 的搜索路径,方法是

ClassPool classPool = ClassPool.getDefault();
classPool.appendClassPath(new LoaderClassPath(classLoader));

追加此路径后,您的示例应该可以正常工作。


答案 2

推荐