2010-01-25 10 views
7

Niedawno dowiedziałem się o nowej wersji JavaCompiler API dostępnej w JDK 1.6. To sprawia, że ​​bardzo łatwo sporządzić String się do .class plik bezpośrednio z kodu działa:JavaCompiler z JDK 1.6: jak pisać bajty klas bezpośrednio do tablicy bajtów []?

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

Można pobrać źródła do JavaSourceFromString z Javadoc.

To bardzo wygodnie skompiluje sourceCode do Foo.class w bieżącym katalogu roboczym.

Moje pytanie brzmi:: czy jest to możliwe do kompilacji prosto do byte[] tablicy i uniknąć niechlujstwo radzenia sobie z File I/O w ogóle?

Odpowiedz

2

Może mógłbyś stworzyć własną implementującą klasę javax.tools.JavaFileManager, w której chciałbyś zwrócić własną implementację javax.tools.FileObject, która następnie zapisałaby ją w pamięci zamiast na dysku. Tak więc dla twojej podklasy metody javax.tools.FileObjectWriter openWriter() throws IOException możesz zwrócić wartość java.io.StringWriter. Wszystkie metody powinny zostać przekonwertowane na ich odpowiedniki w wersji String.

2

Powodem, dla którego nie istnieje standardowy interfejs API do zapisywania bajtów do tablicy bajtów, jest to, że kompilowanie pojedynczego pliku źródłowego Java może skutkować powstaniem wielu plików kodu bajtowego. Na przykład dowolny plik źródłowy z klasami zagnieżdżonymi/wewnętrznymi/anonimowymi spowoduje powstanie wielu plików kodu bajtowego.

Jeśli przetasujesz własny program JavaFileManager, musisz uporać się z tą sytuacją.

2

Aplikacja demonstracyjna dostarczana z interfejsem API JSR 199 zawierała przykład kompilacji z łańcucha (który jest rzeczywiście używany jako MemoryFileManager). Może spojrzeć na to here lub here (te próbki są nieco przestarzałe, ale będą wymagały niewielkich zmian). Może również sprawdź artykuł How to compile on the fly? na Java.net.

PS: Nie przyjrzałem się szczegółom, ale nie sądzę, że obsługuje przypadki wymienione przez Stephen C.

Powiązane problemy