2016-07-23 3 views
0

Я хочу скомпилировать java-файл и выполнить его класс в другом классе (← Этот класс является @service проекта Spring MVC).ProcessBuilder & Runtime exec не смог найти или загрузить основной класс в Spring Project

Код услуга:

@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]

я кд theFilePath, Р Файл [id] .class существует. И я могу запустить java P [id] успешно в FilePath.

И я пытаюсь заменить 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 является ВТР-расслоением, сервер tomcat8

ответ

1

Я знаю, что здесь не так.

pb.start(); не означает, что команда pb будет выполнена немедленно.

Так что если я установил pb команды javac hello.java; set epb команды java hello

И я вызываю pb.start(); epb.start(); непрерывно, я получу ошибку: не смог найти или загрузить основной класс: привет, потому что когда я выполняю epb.start(); Бывшая команда (pb.start), возможно, не была выполнена!

Я получил 2 решения:

Во-первых: установить финально поле и 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 
} 

Второе: трюк Баш

@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 
} 

Я использую второй.