从加载的类中获取字节码

14

假设在我的JVM中我已经加载了一个类Class<C> myClass。有没有一种可靠的方法来询问JVM获取该.class文件的字节码内容?就像这样:

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

(显然,一个InputStream和一个byte[]一样好用)。我知道我可以使用myClass.getResource()(以及相关方法)来获取类文件,但是通过类名获取URL并提供给getResource感觉不太对。此外,我不确定如果C是动态生成的(例如使用javax.tools.JavaCompiler),这会产生什么影响。

有更好的想法吗?

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


请查看:http://commons.apache.org/proper/commons-bcel/ - ogzd
1
请提供在Java JVM中获取类字节码的运行时代码和在运行时获取类的字节码的方法。 - assylias
2个回答

11
注:目标是能够使用自定义类加载器在不同的JVM上加载字节码。
类加载器不仅仅是加载字节码。因此,如果您能够将字节码从JVM内存中提取出来(如果您编写了大量特定于实现的本机代码,这在理论上是可能的),它对于远程类加载器将是无用的。你需要给它一个真正的.class文件。
Class.getResource()是完成此任务的最佳方法。由于它查找调用类所在的同一包,所以你只需要取出类的简单名称,附加“.class”即可。
如果您有内部或嵌套类,那么这会变得更加困难,但这是一个实现细节,您必须无论如何处理它(如果您推送初始类,则仍然需要拉取任何依赖类)。

抱歉,我的错误:我真正想表达的是“.class”文件的内容,而非“字节码”。 - CAFxX

4
您可以使用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);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接