2016-07-23 3 views
0

Javaファイルをコンパイルし、そのクラスを別のクラスでexecしたい(←このクラスはSpring MVCプロジェクトの@serviceです)。ProcessBuilder&Runtime execがSpringプロジェクトでメインクラスを見つけられない、またはロードできない

サービスコードは次のとおりです。

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

I CD theFilePath、P [id] .classファイルは存在します。 そして、私はtheFilePathでjava P [id]を正常に実行できます。

そして、私は次のように、ランタイムでProcessBuilderをを交換してみてください。再びT^T

IDEは、STS-バンドルされ、サーバは私が知っている

答えて

1

tomcat8である私は同じエラーを取得し

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

何がここで間違っている。

pb.start(); pbのコマンドがすぐに実行されることを意味しません。

したがって、コマンドjavac hello.javaのpbを設定した場合、コマンドのepbを設定するhello

そして、私はpb.start()を呼び出します。 epb.start();継続的に、私はエラーが発生します:メインクラスを見つけることができませんでした:hello、exec epb.start();以前のコマンド(pb.start)が実行されていない可能性があります。

は、私が2溶液を得た:

まず:

@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 
} 
のように、最終的には、フィールドとexec epb.start()このフィールドに設定

私は2番目を使用します。

関連する問題