从java代码运行.class文件

问题描述 投票:0回答:6

如何从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());
        }
    }
}
java jvm
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. 您必须在进程运行时读取流。在读取流之前等待进程完成会导致死锁,因为进程输出缓冲区已满并且正在等待父进程读取数据,而父进程正在等待子进程完成!

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


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


0
投票
尝试

Process process = Runtime.getRuntime().exec("java " + filePath); // without .class Scanner output = new Scanner(process.getInputStream()); while (output.hasNext) { String token = output.next(); ... }
    

0
投票
其中一个选项是使用类加载器创建类的实例。类加载器可以将您的类作为字节数组,然后您可以创建它的实例并运行它。请参阅 JDK 文档中的

此方法


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 来加载并实例化该类。确保类加载器具有最小权限。

© www.soinside.com 2019 - 2024. All rights reserved.