Pergunta

Então eu aprendi recentemente sobre o novo Javacompiler API Disponível no JDK 1.6. Isso torna muito simples compilar um String para um .class Arquivo diretamente do código em execução:

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

Você pode pegar a fonte para JavaSourceFromString de Javadoc.

Isso vai compilar muito com facilidade sourceCode para Foo.class no diretório de trabalho atual.

Minha pergunta é: é possível compilar diretamente a um byte[] matriz e evitar a confusão de lidar com File E/S completamente?

Foi útil?

Solução

Talvez você possa criar o seu próprio javax.tools.JavaFileManager implementando a classe onde você retornaria sua própria implementação de javax.tools.FileObject o que então o escreveria na memória em vez de disco. Então, para sua subclasse de javax.tools.FileObject Writer openWriter() throws IOException Método você retornaria um java.io.StringWriter. Todos os métodos devem ser convertidos para seus String homólogos.

Outras dicas

A razão pela qual não há API padrão para escrever bytecodes em uma matriz de bytes é que a compilação de um único arquivo de origem Java pode resultar em vários arquivos bytecode. Por exemplo, qualquer arquivo de origem com classes aninhadas / internas / anônimas resultará em vários arquivos ByteCode.

Se você rolar seu próprio Javafilemanager, precisará lidar com essa situação.

O aplicativo de demonstração que enviou com a API JSR 199 teve um exemplo de compilação de string na memória (que está realmente usando um MemoryFileManager). Talvez dê uma olhada nisso aqui ou aqui (Essas amostras estão um pouco desatualizadas, elas exigirão pequenas alterações). Também talvez verifique o Como compilar em tempo real? Artigo em java.net.

PS: Eu não olhei para todos os detalhes, mas não acho que isso lida com os casos mencionados por Stephen c.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top