JavaCompiler da JDK 1.6: come scrivere direttamente byte classe a byte array []?
-
22-09-2019 - |
Domanda
Così ho recentemente appreso della nuova JavaCompiler API disponibile in JDK 1.6. Questo lo rende molto semplice da compilare un String
a un file .class
direttamente da eseguire codice:
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();
È possibile afferrare la fonte per JavaSourceFromString
dal Javadoc .
Questo sarà molto comodamente compilare sourceCode
al Foo.class
nella directory di lavoro corrente.
La mia domanda è :? È possibile compilare direttamente a una matrice byte[]
, ed evitare la confusione di trattare con File
I / O del tutto
Soluzione
Forse si potrebbe creare la propria classe che implementa javax.tools.JavaFileManager
dove si vuole restituire la propria implementazione di javax.tools.FileObject
che sarebbe poi scriverlo fuori a memoria invece su disco. Quindi per la vostra sottoclasse di metodo javax.tools.FileObject
Writer openWriter() throws IOException
si sarebbe restituire un java.io.StringWriter
. Tutti i metodi devono essere convertiti alle loro controparti String
.
Altri suggerimenti
Il motivo per cui non v'è alcuna API standard di scrivere bytecode ad un array di byte è che la compilazione di un singolo file sorgente Java può causare più file bytecode. Per esempio, qualsiasi file sorgente con le classi nidificate / interno / anonimi si tradurrà in più file bytecode.
Se si tira il proprio JavaFileManager, è necessario affrontare questa situazione.
L'applicazione demo fornito con il JSR 199 API aveva una lista in memoria compilazione da corde (che è infatti utilizza un MemoryFileManager
). Forse dare un'occhiata a esso qui o qui (questi campioni sono un po 'obsolete, però, avranno bisogno di lievi modifiche). Forse anche controllare la Come compilare al volo? articolo su Java.net.
PS: non ho guardato tutti i dettagli, ma sono non credo che gestisce i casi menzionati dalla Stephen C .