1

如何.class从 java 代码本身运行已编译的代码 () 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());
        }
    }
}
4

6 回答 6

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. java进程给出的运行时错误被发送到错误流,而不是输入流,所以你必须阅读它们!
  2. 您必须在进程运行时读取流。在读取流之前等待进程完成会导致死锁,因为进程输出缓冲区已满,正在等待父进程读取数据,而父进程正在等待子进程完成!
于 2012-04-20T16:09:31.203 回答
0

一种选择是使用类加载器创建类的实例。类加载器可以将你的类作为一个字节数组,然后你可以创建它的一个实例并运行它。请参阅JDK 文档中的此方法

于 2012-04-20T16:20:31.877 回答
0

这是一个示例应用程序,它将编译 Java 源文件、加载类、实例化一个实例并打印出 HelloWorld 类的 toString()。我相信您需要在类路径中使用 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 具有最小权限。

于 2013-08-27T17:08:44.150 回答
0

创建 .jar 文件并将该文件添加到构建路径

于 2012-04-20T16:08:02.313 回答
0

尝试

Process process = Runtime.getRuntime().exec("java " + filePath); // without .class
Scanner output = new Scanner(process.getInputStream());
while (output.hasNext) {
   String token = output.next();
   ...
}
于 2012-04-20T16:09:50.800 回答
0

还有很多构建/编译工具,即 Ant 或 Maven,您可以在编写自己的之前检查一下。

于 2012-04-20T16:10:04.083 回答