2010-01-25 2 views
7

So habe ich kürzlich von der neuen JavaCompiler API in JDK 1.6. Dies macht es sehr einfach, eine String zu einem .class Datei direkt aus laufenden Code zu kompilieren:JavaCompiler von JDK 1.6: Wie schreibe ich Klasse Bytes direkt in Byte [] Array?

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(); 

Sie die Quelle JavaSourceFromString vom Javadoc greifen können.

Dies wird sourceCode zu Foo.class im aktuellen Arbeitsverzeichnis sehr handlich kompilieren.

Meine Frage ist: ist es möglich, direkt auf eine byte[] Array zu kompilieren, und vermeiden Sie die Unsauberkeit mit File I/O ganz im Umgang?

Antwort

2

Vielleicht könnten Sie Ihre eigene javax.tools.JavaFileManager Implementierungsklasse erstellen, in der Sie Ihre eigene Implementierung von javax.tools.FileObject zurückgeben würden, die sie dann in den Speicher statt auf die Festplatte schreiben würde. Also für Ihre Unterklasse von javax.tools.FileObjectWriter openWriter() throws IOException Methode würden Sie eine java.io.StringWriter zurückgeben. Alle Methoden sollten in ihre String Gegenstücke konvertiert werden.

2

Der Grund dafür, dass es keine Standard-API zum Schreiben von Bytecodes in ein Byte-Array gibt, besteht darin, dass das Kompilieren einer einzelnen Java-Quelldatei zu mehreren Bytecode-Dateien führen kann. Zum Beispiel führt jede Quelldatei mit verschachtelten/inneren/anonymen Klassen zu mehreren Bytecode-Dateien.

Wenn Sie Ihren eigenen JavaFileManager rollen, müssen Sie mit dieser Situation umgehen.

2

Die Demo-Anwendung, die mit der JSR 199-API geliefert wurde, hatte ein In-Memory-Compile-from-String-Beispiel (das tatsächlich eine MemoryFileManager verwendet). Vielleicht sehen Sie es sich here oder here (diese Proben sind ein wenig veraltet, aber sie erfordern geringfügige Änderungen). Überprüfen Sie auch den How to compile on the fly? Artikel auf Java.net.

PS: Ich habe nicht alle Details betrachtet, aber ich glaube nicht, dass es die Fälle behandelt, die von Stephen C erwähnt werden.

Verwandte Themen