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

È stato utile?

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 .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top