2013-06-26 14 views
8

Supponiamo che nella mia JVM sia presente una classe caricata Class<C> myClass. Esiste un modo affidabile per chiedere alla JVM il codice di bytecode di .class? Cioè qualcosa di simile:Ottieni bytecode dalla classe caricata

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

(ovviamente un InputStream sarebbe buono come il byte[]). So che posso usare myClass.getResource() (e gli amici) per recuperare il file di classe, ma martellando sul nome della classe per ottenere un URL da inviare a getResource è sbagliato. Inoltre, non sono sicuro di come si comporterebbe nel caso in cui sia stato generato dinamicamente C (ad esempio utilizzando javax.tools.JavaCompiler).

Qualche idea (migliore)?

nota: l'obiettivo è quello di essere in grado di spingere il bytecode classi per una JVM diversa e utilizzare un programma di caricamento classe personalizzata per caricare loro ci

+0

si prega di dare un'occhiata a: http://commons.apache.org/proper/commons-bcel/ – ogzd

+1

http://stackoverflow.com/questions/4130903/java-getting-bytecode-of-class -at-runtime-from-the-same-jvm e http://stackoverflow.com/questions/2737285/is-there-a---to-obtain-the-bytecode-for-a-class-at -runtime – assylias

risposta

5

nota: l'obiettivo è quello di essere in grado di caricare il bytecode utilizzando un classloader personalizzato su una JVM diversa

Un classloader doesn't just load bytecode. Pertanto, se l'utente fosse in grado di estrarre il bytecode dalla memoria JVM (che è teoricamente possibile se si scrive un sacco di codice nativo specifico per l'implementazione), sarebbe inutile per il classloader remoto. Devi dargli un vero e proprio file .class.

E Class.getResource() è il modo migliore per eseguire questa attività. Dal momento che appare nello stesso pacchetto della classe invocante, tutto quello che devi fare è prendere il semplice nome della classe, aggiungere ".class" e il gioco è fatto.

Diventa un po 'più difficile se si dispone di classi interne o nidificate, ma questo è un dettaglio di implementazione che dovrete affrontare indipendentemente (se si spinge la classe iniziale, sarà comunque necessario tirare qualsiasi dipendente classi).

+0

scusate, il mio male: con "bytecode" intendevo davvero "il contenuto del file .class" – CAFxX

2

È possibile utilizzare la libreria ASM per ottenere il codice byte dettagliato di una classe. Un codice di esempio è sotto.

 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); 
    } 
} 
Problemi correlati