JDK 1.6 の JavaCompiler:クラスのバイトを byte[] 配列に直接書き込むにはどうすればよいですか?
-
22-09-2019 - |
質問
それで最近新しいことを知りました JavaコンパイラAPI JDK 1.6 で利用可能です。これにより、コンパイルが非常に簡単になります。 String
に .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
I/O 全部?
解決
たぶんあなたは、代わりに、ディスクにそれをメモリに書き出しますjavax.tools.JavaFileManager
の独自の実装を返す独自のjavax.tools.FileObject
実装するクラスを作成することができます。だから、javax.tools.FileObject
Writer openWriter() throws IOException
方法のサブクラスのためにあなたはjava.io.StringWriter
を返します。すべてのメソッドは、そのString
の対応に変換する必要があります。
他のヒント
バイト配列への書き込みバイトコードへの標準APIが存在しないことの理由は、単一のJavaソースファイルをコンパイルすると、複数のバイトコードファイルをもたらすことができるということです。たとえば、ネストされた/インナー/匿名クラスを持つすべてのソースファイルには、複数のバイトコードファイルになります。
あなたがあなた自身のJavaFileManagerをロールした場合、あなたはこのような状況に対処する必要があります。
JSR 199 API に同梱されているデモ アプリケーションには、メモリ内に文字列からコンパイルするサンプルが含まれていました (実際には、 MemoryFileManager
)。たぶんそれを見てください ここ または ここ (ただし、これらのサンプルは少し古いため、若干の変更が必要になります)。また、多分チェックしてください オンザフライでコンパイルするにはどうすればよいですか? Java.net の記事。
追伸:すべての詳細を確認したわけではありませんが、で言及されているケースには対応していないと思います。 スティーブン・C.