如何从java代码本身运行已编译的代码(.class
)java?
我正在做一种提供服务,比如在服务器端编译和运行java代码并向最终用户提供输出。
有人能建议一种可以实现这一目标的方法吗?
import java.io.*;
public class demo {
public static void main(String args[]) throws IOException, InterruptedException {
int result;
try {
System.out.println("command output:");
Process proc = Runtime.getRuntime().exec("java -cp . demoh");
InputStream in = proc.getInputStream();
result = proc.waitFor();
BufferedInputStream buffer = new BufferedInputStream(proc.getInputStream());
BufferedReader commandOutput = new BufferedReader(new InputStreamReader(buffer));
System.out.print(commandOutput);
String line = null;
try {
while ((line = commandOutput.readLine()) != null) {
System.out.print(line);
System.out.println("command output: " + line);
}//end while
commandOutput.close();
} catch (IOException e) {
//log and/or handle it
}
} catch (IOException e) {
System.err.println("IOException raised: " + e.getMessage());
}
}
}
答案 0 :(得分:1)
如果你在磁盘上的某个地方有.class
文件,只需生成一个新进程并像在命令行中那样运行java命令:
Process p = Runtime.getRuntime().exec("java <java class file>");
经过一些测试后,以下代码对我有用:
public static void main(String args[]) throws IOException, InterruptedException {
int result;
try {
System.out.println("command output:");
Process proc = Runtime.getRuntime().exec("java -cp . Test");
InputStream errin = proc.getErrorStream();
InputStream in = proc.getInputStream();
BufferedReader errorOutput = new BufferedReader(new InputStreamReader(errin));
BufferedReader output = new BufferedReader(new InputStreamReader(in));
String line1 = null;
String line2 = null;
try {
while ((line1 = errorOutput.readLine()) != null ||
(line2 = output.readLine()) != null) {
if(line1 != null) System.out.print(line1);
if(line2 != null) System.out.print(line2);
}//end while
errorOutput.close();
output.close();
} catch (IOException e) {
e.printStackTrace();
}//end catc
result = proc.waitFor();
} catch (IOException e) {
System.err.println("IOException raised: " + e.getMessage());
}
}
请注意以下两点:
答案 1 :(得分:0)
创建.jar文件并将该文件添加到构建路径
答案 2 :(得分:0)
尝试
Process process = Runtime.getRuntime().exec("java " + filePath); // without .class
Scanner output = new Scanner(process.getInputStream());
while (output.hasNext) {
String token = output.next();
...
}
答案 3 :(得分:0)
还有很多构建/编译工具,即Ant或Maven,您可以在编写自己的工具之前进行检查。
答案 4 :(得分:0)
其中一个选项是使用类加载器创建类的实例。类加载器可以将您的类作为字节数组,然后您可以创建它的实例并运行它。请参阅JDK文档中的this method。
答案 5 :(得分:0)
这是一个示例应用程序,它将编译Java源文件,加载类,实例化实例,并打印出类HelloWorld的toString()。我相信你在classpath上需要tools.jar。示例代码需要src文件夹中的源文件。类路径上需要src文件夹,因为默认情况下会生成.class文件。
要更好地控制Java编译器,请阅读javax.tools包。
package sourcerunner;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
public class SourceRunner {
public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
compiler.run(System.in, System.out, System.err, "src/sourcerunner/HelloWorld.java");
TimeUnit.SECONDS.sleep(1L);
Class<?> cls = Class.forName("sourcerunner.HelloWorld");
Object instance = cls.newInstance();
System.out.println(instance);
}
}
这是HelloWorld类:
package sourcerunner;
public class HelloWorld {
@Override
public String toString() {
return "Hello Java Compiler World.";
}
}
以上代码非常不安全。一旦理解了代码,就修改它以使用新的ClassLoader来加载和实例化类。确保ClassLoader具有最小权限。