1

ユーザーが.javaファイルを作成し、それをコンパイルして実行できるようにするインターフェースを備えたJavaプログラムを作成しようとしています(本質的に非常に単純化されたIDE)。私はGUIにJavaスイングを使用しており、これまでのところ、インターフェース内から.javaファイルを.classファイルにコンパイルできました。Javaコード内から.classファイルを実行する方法を研究してきましたが、うまくいかなかった幅広い答えを見つけました。コンパイルに関連するコードは次のとおりです。

File javaFile = new File( "test1.java" );
String code = entry.getText(); // get text entered by user in GUI
try{
  PrintWriter writer = new PrintWriter( javaFile );  // write text to .java file  
  writer.print( code );
  writer.close();
}
catch( FileNotFoundException e ){
  System.err.println( e );
}
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
List<File> sourceFileList = new ArrayList<File>();
sourceFileList.add( javaFile );
StandardJavaFileManager fileManager = compiler.getStandardFileManager( null, null, null );
Iterable<? extends JavaFileObject> javaSource = fileManager.getJavaFileObjectsFromFiles( sourceFileList );
CompilationTask task = compiler.getTask(null, fileManager, null, null, null, javaSource);
task.call(); // compile .java file into .class file

コンパイルされた .class ファイルを実行し、コード内でその出力をキャプチャするにはどうすればよいですか?

4

1 に答える 1

2

コンパイルしたら、Classオブジェクトをロードしてからメソッドを呼び出す必要がありますmain(String[])。stdout をキャプチャするには、System.setOut.

private String invokeClass(String className) throws URISyntaxException, IOException, ReflectiveOperationException {
    Class<?> clazz = Class.forName(className);
    // Alternatively, you can load the new class with a new Classloader, if you don't want to pollute the current Classloader
    // Class<?> clazz = new URLClassLoader(new URL[]{getClass().getClassLoader().getResource("").toURI().toURL()}, getClass().getClassLoader()).loadClass(className);
    Method main = clazz.getDeclaredMethod("main", String[].class);
    try ( ByteArrayOutputStream out = new ByteArrayOutputStream();
          PrintStream ps = new PrintStream(out)) {
        System.setOut(ps);
        main.invoke(main, new Object[]{new String[0]});
        return out.toString();
    }
    finally {
        // Reset to the console
        System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out)));
    }
}
于 2015-05-25T07:12:27.013 に答える