java - 自定义类加载器和 Java 代理

标签 java jvm javaagents

我想修改正在运行的应用程序中的类。所以我使用java代理来做到这一点。我的java代码是这样的:

    /**
 * 
 * @param args
 * @param inst
 */
public static void agentmain(String args, Instrumentation inst) {
    try {
        inst.addTransformer(new GameClassFileTransformer(), true);
        parseFiles();
        List<Class<?>> retransformClasses = new ArrayList<>();
        for (JarClassInfo jarClassInfo : GameAgentMain.bugFiles.values()) {
            retransformClasses.add(Class.forName(jarClassInfo.getClassName()));
        }
        Class<?>[] classes = new Class[retransformClasses.size()];
        retransformClasses.toArray(classes);
        inst.retransformClasses(classes);
    } catch (Exception e) {
        LogUtil.error(e);
    }
}

JarClassInfo是一个关于我要重新加载的类的类。JarClassInfo中有两个字段,第一个是className,第二个是字节码(java类型是byte[]),类名是要重新加载的类。但是该类是通过

加载的

custom classLoad

.当应用程序运行于:

retransformClasses.add(Class.forName(jarClassInfo.getClassName()));

这是一个抛出的异常:

  Exception in thread "Attach Listener" java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:382)
        at sun.instrument.InstrumentationImpl.loadClassAndCallAgentmain(InstrumentationImpl.java:407)
Caused by: java.lang.ClassFormatError: Incompatible magic value 2329931675 in class file com/jingqi/game/module/chat/command/SendChatMsgCMD
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
        at java.net.URLClassLoader.access$1(URLClassLoader.java:409)
        at java.net.URLClassLoader$2.run(URLClassLoader.java:361)
        at java.net.URLClassLoader$2.run(URLClassLoader.java:1)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:190)
        at com.jingqi.game.agent.GameAgentMain.agentmain(GameAgentMain.java:60)
        ... 6 more

我的自定义类加载器(EncrypClassLoader)用于解码我的类。 所以方法调用堆栈指示 sun.misc.Launcher$AppClassLoader 加载 SendChatMsgCMD 。 SendChatMsgCMD 不是一个普通的类文件(因为我加密了这个类文件)。

那么,有什么方法可以解决。

最佳答案

您的自定义类加载器没有执行其应该执行的操作:解密类。
这就是为什么您会收到关于无效魔法值的java.lang.ClassFormatError

编辑:您还需要意识到Class.forName()将使用当前类的类加载器加载由classname参数引用的类。

关于java - 自定义类加载器和 Java 代理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31758029/

相关文章:

java - JBossWS 与 JAX-WS

java - 在 AWS EMR 上运行 Java 1.8 时不支持 major.minor 版本 52.0

java - 显示当前在 JVM 中运行的所有线程组和线程

java - Java 中的 file.encoding 系统属性在不同的 JVM 实例中给出不同的结果

Java代理忽略应用程序类路径

java - 如何将 javaagent 附加到所有 java 小程序

javascript - 服务器发送事件 : JavaScript events not working

java - 在 Java 中使用 POI 框架读取 xlsm 文件时出错

java - 如何查看我的 Scala 应用程序加载的 JAR 列表

java - 应用程序退出时优雅地关闭 javaagent