JDK 1.6 の JavaCompiler:クラスのバイトを byte[] 配列に直接書き込むにはどうすればよいですか?

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

質問

それで最近新しいことを知りました 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.

これは非常に簡単にコンパイルされます sourceCodeFoo.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.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top