【问题标题】:javassist loading a class file in the pre-main method (java instrumentation)javassist 在 pre-main 方法中加载类文件(java 检测)
【发布时间】:2014-11-03 09:43:14
【问题描述】:

我正在尝试使用 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)

【问题讨论】:

    标签: java instrumentation javassist


    【解决方案1】:

    您的方法没有返回值,因此无法编译。但是,我仍然可以告诉您出了什么问题:您没有设置正确的搜索路径。从您的堆栈跟踪来看,您似乎正在运行一个受特定ClassLoader 屏蔽的小程序。在当前版本中,Javassist 看不到此类加载器。

    通过使用ClassPool.getDefault(),您就是looking up information from the system class path。对于您的小程序,您可能需要 add the class loader 将其作为参数传递给 transformatio 方法。

    您可以通过

    将类加载器附加到 Javassist 的搜索路径中
    ClassPool classPool = ClassPool.getDefault();
    classPool.appendClassPath(new LoaderClassPath(classLoader));
    

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

    【讨论】:

    • 首先,我需要非常感谢您的专家回答,这是我大约三周的主要问题,我们如何加载该类,最后通过您的出色回答解决了,关于方法,我只是试图澄清我的主要观点,但它肯定有一个返回值......非常感谢您再次提供帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-07
    • 1970-01-01
    • 1970-01-01
    • 2011-12-16
    相关资源
    最近更新 更多