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

StackOverflow https://stackoverflow.com/questions/2130039

Вопрос

Итак, недавно я узнал о новом По API JavaCompiler доступно в JDK 1.6.Это очень упрощает компиляцию String к a .class файл непосредственно из запущенного кода:

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

Вы можете воспользоваться источником, чтобы JavaSourceFromString из Javadoc.

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

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

Это было полезно?

Решение

Может быть, вы могли бы создать свой собственный javax.tools.JavaFileManager реализующий класс, в котором вы бы вернули свою собственную реализацию javax.tools.FileObject который затем запишет его в память, а не на диск.Итак, для вашего подкласса javax.tools.FileObject Writer openWriter() throws IOException метод, который вы бы вернули java.io.StringWriter.Все методы должны быть преобразованы в их String аналоги.

Другие советы

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

Если вы создадите свой собственный JavaFileManager, вам нужно будет разобраться с этой ситуацией.

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top