JavaCompiler de JDK 1.6: comment écrire des octets de classe tableau directement à l'octet []?

StackOverflow https://stackoverflow.com/questions/2130039

Question

Je viens d'apprendre la nouvelle JavaCompiler API disponible dans JDK 1.6. Cela rend très simple à compiler un String dans un fichier .class directement à partir du code en cours d'exécution:

String className = "Foo";
String sourceCode = "...";

JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

List<JavaSourceFromString> unitsToCompile = new ArrayList<JavaSourceFromString>() 
    {{ 
         add(new JavaSourceFromString(className, sourceCode)); 
    }};

StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
compiler.getTask(null, fileManager, null, null, null, unitsToCompile).call();
fileManager.close();    

ByteArrayOutputStream bos = new ByteArrayOutputStream();
FileInputStream fis = new FileInputStream(className + ".class");
IOUtils.copyStream(fis, bos);

return bos.toByteArray();

Vous pouvez saisir la source à JavaSourceFromString de la Javadoc.

compilera très haut la main sourceCode à Foo.class dans le répertoire de travail courant.

Ma question est : est-il possible de compiler directement à un tableau de byte[] et éviter le désordre de traiter File E / S tout à fait

Était-ce utile?

La solution

Peut-être que vous pouvez créer votre propre classe de mise en œuvre javax.tools.JavaFileManager où vous reviendriez votre propre implémentation de javax.tools.FileObject qui serait alors l'écrire à la mémoire à la place sur le disque. Donc, pour votre sous-classe de la méthode javax.tools.FileObject de Writer openWriter() throws IOException vous renvoyer un java.io.StringWriter. Toutes les méthodes doivent être converties à leurs homologues String.

Autres conseils

La raison pour laquelle il n'y a pas d'API standard pour écrire bytecode à un tableau d'octets est que la compilation d'un fichier source Java unique peut entraîner plusieurs fichiers bytecode. Par exemple, un fichier source avec des classes imbriquées / intérieur / anonymes entraînera plusieurs fichiers bytecode.

Si vous roulez votre propre JavaFileManager, vous aurez besoin de faire face à cette situation.

L'application de démonstration fourni avec l'API JSR 199 avait une en mémoire par exemple la compilation de chaîne (qui est en fait en utilisant un MemoryFileManager). Peut-être un coup d'oeil ici ou Comment compiler à la volée? article sur Java.net.

PS: Je ne regarde pas tous les détails, mais je suis ne pense pas qu'il gère les cas mentionnés par Stephen C .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top