从加载的类中获取字节码

假设在我的JVM中我有一个加载的类Class myClass 。 是否有一种可靠的方式向JVM询问 字节码 .class的内容? 就是这样的:

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

(显然, InputStreambyte[]一样好)。 我知道我可以使用myClass.getResource() (和朋友)来获取类文件,但是为了获取一个输入getResource的URL感觉错误而攻击类名。 另外,我不确定在动态生成C情况下这会如何表现(例如使用javax.tools.JavaCompiler )。

任何(更好)的想法?

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

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

类加载器不只是加载字节码 。 因此,如果您能够从JVM内存中获取字节码(理论上如果您编写了许多特定于实现的本机代码,则可能),这对您的远程类加载器来说是无用的。 你需要给它一个实际的.class文件。

而Class.getResource()是完成此任务的最佳方法。 因为它与调用类看起来在同一个包中,所以你需要做的就是使用类的简单名称,追加“.class”,你就完成了。

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

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