2016-07-23 24 views
0

Ich möchte eine Java-Datei kompilieren und exec seine Klasse in einer anderen Klasse (← Diese Klasse ist ein @ Dienst eines Spring MVC-Projekts).ProcessBuilder & Runtime exec konnte keine Hauptklasse in Spring finden oder laden Projekt

Der Servicecode ist:

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

Wenn dieser Dienst aufgerufen wird, habe ich immer eine Fehlermeldung: Konnte nicht Hauptklasse finden oder laden: P [id]

I cd theFilePath, die P [ID] .class-Datei ist vorhanden. Und ich kann Java P [id] erfolgreich in theFilePath ausführen.

Und ich versuche Process mit Runtime zu ersetzen, wie:

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

ich die gleichen Fehler wieder T^T

IDE sts-Bündel, Server ist tomcat8

Antwort

1

Ich weiß, was ist hier falsch.

pb.start(); bedeutet nicht, dass der Befehl von pb sofort ausgeführt wird.

Also, wenn ich pb des Befehls javac hallo.java; set epb des Befehls java Hallo

Und ich rufe pb.start(); epb.start(); fortlaufend, bekomme ich einen Fehler: konnte Hauptklasse nicht finden oder laden: Hallo, denn wenn ich epb.start(); Der vorherige Befehl (pb.start) wurde möglicherweise nicht ausgeführt!

bekam ich 2 Lösung:

Erstens: set a schließlich Feld und exec epb.start() in diesem Bereich, wie:

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

Zweitens: ein Trick von 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 
} 

Ich benutze die zweite.