2010-01-25 9 views
7

Así que recientemente me enteré de la nueva JavaCompiler API disponible en JDK 1.6. Esto hace que sea muy sencillo para compilar un archivo String a un .class directamente de código que se ejecuta:JavaCompiler de JDK 1.6: ¿cómo escribir bytes de clase directamente en 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(); 

Usted puede agarrar la fuente de JavaSourceFromString del Javadoc.

Esto compilará muy a mano sourceCode a Foo.class en el directorio de trabajo actual.

Mi pregunta es: ¿es posible compilar directamente a una matriz byte[], y evitar el desorden de tratar con File de E/S en total?

Respuesta

2

Tal vez podría crear su propia clase de implementación javax.tools.JavaFileManager donde devolvería su propia implementación de javax.tools.FileObject que luego la escribiría en la memoria en lugar del disco. Por lo tanto, para su subclase del método javax.tools.FileObjectWriter openWriter() throws IOException, devolverá un java.io.StringWriter. Todos los métodos deben convertirse a sus contrapartes String.

2

La razón por la que no existe una API estándar para escribir códigos byte en una matriz de bytes es que la compilación de un único archivo fuente Java puede dar como resultado múltiples archivos de código de bytes. Por ejemplo, cualquier archivo fuente con clases anidadas/internas/anónimas resultará en múltiples archivos de código de bytes.

Si ejecuta su propio JavaFileManager, tendrá que lidiar con esta situación.

2

La aplicación de demostración que se envió con la API JSR 199 tenía un ejemplo de compilación desde la memoria en la memoria (que de hecho está utilizando un MemoryFileManager). Tal vez echarle un vistazo here o here (estas muestras son un poco obsoletas, requerirán ligeros cambios). También puede consultar el artículo How to compile on the fly? en Java.net.

PD: No miré todos los detalles, pero no creo que maneje los casos mencionados por Stephen C.