【问题标题】:ProcessBuilder&Runtime exec could not find or load main class in Spring ProjectProcessBuilder&Runtime exec 在 Spring Project 中找不到或加载主类
【发布时间】:2016-11-27 05:55:19
【问题描述】:

我想编译一个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]

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

我尝试将 ProcessBuilder 替换为 Runtime,例如:

@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

【问题讨论】:

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


    【解决方案1】:

    我知道这里出了什么问题。

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

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

    然后我调用 pb.start(); epb.start();连续,我会得到一个错误:找不到或加载主类:你好,因为当我执行 epb.start();之前的命令(pb.start)可能还没有执行!

    我有 2 个解决方案:

    首先:设置一个finally字段并在该字段中执行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
    }
    

    我用的是第二个。

    【讨论】:

      猜你喜欢
      • 2020-10-10
      • 1970-01-01
      • 2018-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多