JavaCompiler от JDK 1.6: как записать байты класса непосредственно в байт [] массив?

Таким образом, я недавно узнал о новом JavaCompiler API, доступном в JDK 1.6. Это делает очень простым скомпилировать a String к a .class зарегистрируйте непосредственно из под управлением кода:

String className = "Foo";
String sourceCode = "...";

JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

List unitsToCompile = new ArrayList() 
    {{ 
         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();

Можно захватить источник к JavaSourceFromString от Javadoc.

Это очень ловко скомпилирует sourceCode кому: Foo.class в текущем рабочем каталоге.

Мой вопрос: действительно ли возможно скомпилировать прямо в a byte[] массив, и избегает беспорядка контакта с File Ввод-вывод в целом?

8
задан Pascal Thivent 25 January 2010 в 05:28
поделиться

3 ответа

Может быть, вы могли бы создать свой собственный javax.tools.javafilemanager Учебный класс, в котором вы вернете свою собственную реализацию javax.tools.fileobject , которые будут включены в память вместо на диск. Таким образом, для вашего подкласса javax.tools.fileobject писатель OpenWriteriater () метод racks arexception Вы вернете Java.io.stringwriter . Все методы должны быть преобразованы в их строку аналоги.

3
ответ дан 5 December 2019 в 20:16
поделиться

Если вы указываете размеры шрифтов на EM, ваши коды будут более гибкими и проще, чтобы поддерживать, когда вы хотите изменить размер шрифта позже. Кроме того, как сказал Дан Макг, не все браузеры масштабируют в пикселях.

-121--5044670-

Демо-приложение, поставляемое с API JSR 199, имела пример с компиляцией в памяти (который действительно использует MemoryFileManager ). Может быть, посмотрите на это здесь или здесь (эти образцы немного устарели, хотя они потребуют небольших изменений). Также, возможно, проверьте Как скомпилировать на лету? статья на Java.net.

PS: Я не смотрел на все детали, но я не думаю, что это обрабатывает случаи, упомянутые Stephen C .

2
ответ дан 5 December 2019 в 20:16
поделиться

Причина того, что нет стандартных API для записи байтододов в байтовый массив, это то, что компиляция одного исходного файла Java может привести к нескольким файлам Bytecode. Например, любой исходный файл со вложенным / внутренним / анонимным классам приведет к нескольким файлам Bytecode.

Если вы катите свой собственный Javafilemanager, вам нужно будет иметь дело с этой ситуацией.

3
ответ дан 5 December 2019 в 20:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: