2016-07-23 3 views
0

Je veux compiler un fichier java et exec sa classe dans une autre classe (← Cette classe est un @service d'un projet Spring MVC).ProcessBuilder & Runtime exec n'a pas pu trouver ou charger la classe principale dans Spring Project

Le code de service est:

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

Lorsque ce service est appelé, je reçois toujours une erreur: Impossible de trouver ou charger la classe principale: P [id]

I cd theFilePath, P Le fichier [id] .class existe déjà. Et je peux lancer java P [id] avec succès dans theFilePath.

Et j'essaie de remplacer ProcessBuilder avec Runtime, comme:

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

Je reçois la même erreur T^T

IDE est m-paquet, le serveur est tomcat8

Répondre

1

Je sais qu'est-ce qui ne va pas ici?

pb.start(); ne signifie pas que la commande de pb sera exécutée immédiatement. Donc, si je mets pb de commande javac hello.java; set epb de commande java bonjour

Et j'appelle pb.start(); epb.start(); en continu, j'obtiendrai une erreur: impossible de trouver ou de charger la classe principale: bonjour, car quand j'exécute epb.start(); L'ancienne commande (pb.start) n'a peut-être pas été exécutée!

J'ai eu 2 solution:

Première: définir un champ et enfin exec epb.start() dans ce domaine, comme:

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

Second: un tour de 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 
} 

J'utilise le second.