【问题标题】:Get bytecode from loaded class从加载的类中获取字节码
【发布时间】:2013-06-26 13:13:10
【问题描述】:

假设在我的 JVM 中有一个已加载的类 Class<C> myClass。是否有一种可靠 的方式向 JVM 询问 .class 的 bytecode 内容? IE。像这样:

<C> byte[] getClassBytecode(Class<C> myClass) {
    return /* the contents of the .class resource where C was loaded from */;
}

(显然InputStreambyte[] 一样好)。我知道我可以使用myClass.getResource()(和朋友)来获取类文件,但是敲敲类名来获取一个 URL 来提供给 getResource 感觉不对。此外,如果动态生成 C(例如使用 javax.tools.JavaCompiler),我不确定这会如何表现。

有什么(更好的)想法吗?

注意:目标是能够将 bytecode 类推送到不同的 JVM 并使用自定义类加载器将它们加载到那里

【问题讨论】:

标签: java class classloader


【解决方案1】:

注意:目标是能够在不同的 JVM 上使用自定义类加载器加载字节码

类加载器doesn't just load bytecode。因此,如果您能够从 JVM 内存中获取字节码(理论上,如果您编写大量特定于实现的本机代码,这在理论上是可能的),那么它对您的远程类加载器将毫无用处。你需要给它一个实际的.class 文件。

Class.getResource() 是完成这项任务的最佳方式。由于它与调用类在同一个包中,因此您只需取类的简单名称,附加“.class”即可。

如果你有内部类或嵌套类,这确实会变得有点困难,但这是一个你必须处理的实现细节(如果你推送初始类,你仍然需要拉取任何依赖类)。

【讨论】:

  • 对不起,我的错:“字节码”的真正意思是“.class 文件的内容”
【解决方案2】:

您可以使用 ASM 库来获取类的详细字节码。示例代码如下。

     public class AAA extends ClassLoader{
       public static void main(){
        String resource = caller.replace('.', '/')+".class";
        InputStream is = getResourceAsStream(resource);
        ClassReader cr = new ClassReader(is);
        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);

        ClassVisitor visitor = new BCMerge(Opcodes.ASM5, cw, callee);
        cr.accept(visitor, 0);
    }
  }
  class BCMerge extends ClassVisitor{
         public MethodVisitor visitMethod(int access, String name, String desc,String signature, String[] exceptions) {
        System.out.println(name);
        if (cv != null) {
            return new MyMethodVisit(cv.visitMethod(access, name, desc, signature, exceptions));
        }
        return null;
    }
   }

public class MyMethodVisit extends MethodVisitor{
    @Override
    public void visitMethodInsn(int opcode, String owner, String name,
            String desc, boolean itf) {
            System.out.println("opcode:" + opcode + " owner:" + owner + " name:"+ name + " desc:" + desc);
            return super.visitMethodInsn(opcode, owner, name, desc, itf);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-22
    • 2011-05-07
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    相关资源
    最近更新 更多