2016-10-16 3 views
1

Je crée une classe dynamiquement - en construisant le bytecode et en le chargeant avec un chargeur de classe. Plus tard, je dois obtenir InputStream de cette classe. Avec la classe commune, j'obtiens ceci en obtenant la ressource URL pour cette classe et en ouvrant alors le flux (url.openStream()). Évidemment, ici je ne peux pas faire cela, car la classe chargée dynamiquement n'a pas l'URL.Obtenir InputStream d'une classe créée dynamiquement (en utilisant le bytecode)?

Comment puis-je obtenir InputStream de classe créée dynamiquement?

La seule solution que je peux penser à atm est de sauvegarder les bytecodes dans un certain fichier/mémoire temporaire et d'en fournir InputStream.

EDIT

J'ai besoin InputStream de faire un autre changement bytecode au-dessus d'exister.

+0

Si vous avez le bytecode comme 'byte []' alors vous pouvez construire un 'ByteArrayInputStream'. –

+0

Je l'ai, mais il est généré à différents endroits de l'application et à différents moments. Si je commence à collecter tous les 'byte []' pour chaque classe de proxy, cela va être trop long. Quoi qu'il en soit, j'explore cette option. – igr

+0

Puisque vous n'indiquez pas explicitement ce que vous devez faire avec l'InputStream, je peux seulement deviner, mais ObjectInputStream peut être utile? ref: [javadoc pour ObjectInputStream] (https://docs.oracle.com/javase/7/docs/api/java/io/ObjectInputStream.html) – mangotang

Répondre

1

Si le chargeur de classe ne fournit pas un code d'octets de classe soit par getResource ou getResourceAsStream, vous pouvez toujours u se a Java agent pour demander la machine virtuelle (ce qui est légal, le contrat de chargeur de classe ne précise pas une telle chose) pour créer l'octet code pour vous.

Par exemple, vous pouvez enregistrer le transformateur suivant:

instrumentation.addTransformer(new ClassFileTransformer() { 
    @Override 
    public byte[] transform(ClassLoader loader, 
          String name, 
          Class<?> classBeingRedefined, 
          ProtectionDomain pd, 
          byte[] classFileBuffer) { 
    doSomethingWith(classFileBuffer); 
    return null; 
    } 
}, true); 

Après avoir fixé un agent Java, vous pouvez appeler: instrumentation.retransform(someGeneratedClass) pour déclencher le transformateur de fichier de classe ci-dessus qui contiendra le fichier de classe du type généré même si elle n'est pas disponible depuis son chargeur de classe.

+0

Heya Rafael! Merci pour la réponse; juste l'agent n'est pas toujours disponible en option. J'ai résolu mon problème d'une autre manière, mais je pourrais quand même collecter le bytecode généré dans certains fichiers temporaires (à moins qu'ils ne soient créés à chaque utilisation) – igr