ProcessBuilder& Runtime exec无法在Spring Project中找到或加载主类

时间:2016-07-23 11:54:34

标签: spring-mvc java-8 processbuilder runtime.exec

我想编译一个java文件并在另一个类中执行它的类(←这个类是Spring MVC项目的@service)。

服务代码是:

@Service
public class MRServiceImp implements MRService {
    @Override
    public String submitMR(int id, String fd) {
        try {
            // compile the java file
            String[] cmd = {"javac", "P" + id + ".java"};
            ProcessBuilder pb = new ProcessBuilder(cmd);
            pb.directory(new File(fd));
            Process p = pb.start();

            // exec the class file
            String[] execmd = {"java", "P" + pz_id};
            ProcessBuilder epb = new ProcessBuilder(execmd);
            epb.directory(new File(fd));
            p = epb.start();

            // get normal output
            BufferedReader pin = new BufferedReader(new InputStreamReader(p.getInputStream()));
            String ptmp = pin.readLine();
            while (ptmp != null) {
                pout = pout == null ? ptmp + '\n' : pout + ptmp + '\n';
                ptmp = pin.readLine();
            }

            // get error output
            pin = new BufferedReader(new InputStreamReader(p.getErrorStream()));
            String wout = null;
            ptmp = pin.readLine();
            while (ptmp != null) {
                wout = wout == null ? ptmp + '\n' : wout + ptmp + '\n';
                ptmp = pin.readLine();
            }

            // print output
            System.out.println(pout);
            System.out.println(wout);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null; // for test
    }

调用此服务时,我总是收到错误:无法找到或加载主类:P [id]

我cdFilePath,P [id] .class文件存在。 我可以在文件路径中成功运行java P [id]。

我尝试用Runtime替换ProcessBuilder,如:

@Service
public class MRServiceImp implements MRService {
    @Override
    public String submitMR(int id, String fd) {
        try {
            // compile the java file
            String[] cmd = {"javac", "P" + id + ".java"};
            ProcessBuilder pb = new ProcessBuilder(cmd);
            pb.directory(new File(fd));
            Process p = pb.start();

            // exec the class file
            String execmd = "java", fd + "/P" + pz_id;
            p = Runtime.getRuntime().exec(execmd);

            // get normal output
            BufferedReader pin = new BufferedReader(new InputStreamReader(p.getInputStream()));
            String ptmp = pin.readLine();
            while (ptmp != null) {
                pout = pout == null ? ptmp + '\n' : pout + ptmp + '\n';
                ptmp = pin.readLine();
            }

            // get error output
            pin = new BufferedReader(new InputStreamReader(p.getErrorStream()));
            String wout = null;
            ptmp = pin.readLine();
            while (ptmp != null) {
                wout = wout == null ? ptmp + '\n' : wout + ptmp + '\n';
                ptmp = pin.readLine();
            }

            // print output
            System.out.println(pout);
            System.out.println(wout);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null; // for test
    }

我再次得到相同的错误T ^ T

IDE是sts-bundle,服务器是tomcat8

1 个答案:

答案 0 :(得分:1)

我知道这里有什么问题。

pb.start();并不意味着pb的命令会立即执行。

所以如果我设置pb命令javac hello.java;设置命令java hello的epb

我打电话给pb.start(); epb.start();不断,我会得到一个错误:无法找到或加载主类:你好,因为当我执行epb.start();前一个命令(pb.start)可能尚未执行!

我得到了2个解决方案:

首先:在此字段中设置finally字段和exec epb.start(),如:

@Service
public class MRServiceImp implements MRService {
@Override
public String submitMR(int id, String fd) {
    try {
        // compile the java file
        String[] cmd = {"javac", "P" + id + ".java"};
        ProcessBuilder pb = new ProcessBuilder(cmd);
        pb.directory(new File(fd));
        Process p = pb.start();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } finally {
        // exec the class file
        String[] execmd = {"java", "P" + pz_id};
        ProcessBuilder epb = new ProcessBuilder(execmd);
        epb.directory(new File(fd));
        Process p = epb.start();
    }
    return null; // for test
}

第二:bash的伎俩

@Service
public class MRServiceImp implements MRService {
@Override
public String submitMR(int id, String fd) {
    try {
        // compile & exec the java file
        String[] cmd = {"/bin/bash"};
        ProcessBuilder pb = new ProcessBuilder(cmd);
        pb.directory(new File(fd));
        Process p = pb.start();
        BufferedWriter pbw = new BufferedWriter(new OutputStreamWriter(p.getOutputStream()));
        pbw.write("javac *.java;java P" + pz_id+";exit;");
        pbw.newLine();
        pbw.flush();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return null; // for test
}

我使用第二个。