从java代码中运行编译的java.class文件并捕获输出

从java代码中运行编译的java.class文件并捕获输出,java,classloader,javacompiler,Java,Classloader,Javacompiler,我正在尝试编写一个java程序,该程序的接口允许用户创建.java文件并编译和运行它(本质上是一个非常简单的IDE)。我正在为gui使用JavaSwing,到目前为止,我已经能够将接口中的.java文件编译成.class文件。我一直在研究如何从java代码中运行.class文件,但找到了一系列我无法找到的答案。以下是相关的编译代码: File javaFile = new File( "test1.java" ); String code = entry.getText(); // get te

我正在尝试编写一个java程序,该程序的接口允许用户创建.java文件并编译和运行它(本质上是一个非常简单的IDE)。我正在为gui使用JavaSwing,到目前为止,我已经能够将接口中的.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
File javaFile=新文件(“test1.java”);
字符串代码=entry.getText();//获取用户在GUI中输入的文本
试一试{
PrintWriter=新的PrintWriter(javaFile);//将文本写入.java文件
编写器、打印(代码);
writer.close();
}
catch(filenotfounde异常){
系统错误println(e);
}
JavaCompiler=ToolProvider.getSystemJavaCompiler();
List sourceFileList=new ArrayList();
添加(javaFile);
StandardJavaFileManager fileManager=compiler.getStandardFileManager(null,null,null);

Iterable编译后,您需要加载
对象,然后调用
main(String[])
方法。要捕获标准输出,您需要使用
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)));
    }
}
private String invokeClass(字符串类名称)抛出URISyntaxException、IOException、ReflectiveOperationException{
Class clazz=Class.forName(className);
//或者,如果不想污染当前的类加载器,可以使用新的类加载器加载新类
//Class clazz=新的URLClassLoader(新的URL[]{getClass().getClassLoader().getResource(“”.toURI().toURL()},getClass().getClassLoader()).loadClass(类名);
方法main=clazz.getDeclaredMethod(“main”,String[].class);
try(ByteArrayOutputStream out=newbytearrayoutputstream();
打印流ps=新打印流(输出)){
系统放样(ps);
调用(main,新对象[]{newstring[0]});
return out.toString();
}
最后{
//重置到控制台
系统设置(新的PrintStream(新的FileOutputStream(FileDescriptor.out));
}
}

这里有一个建议与您的实际问题无关:不要太宽泛!不要问一般性的建议,问一个我们可以回答的特定问题:比如“我如何运行编译后的文件并捕获输出?”(顺便说一句,我想这里已经讨论过了)总之,您可能会发现一些相关(但不是重复)的有用信息:,以及。