我想编译一个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]
我cdFilePath,P [id] .class文件存在。 我可以在文件路径中成功运行java P [id]。
我尝试用Runtime替换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是sts-bundle,服务器是tomcat8
答案 0 :(得分:1)
我知道这里有什么问题。
pb.start();并不意味着pb的命令会立即执行。
所以如果我设置pb命令javac hello.java;设置命令java hello的epb
我打电话给pb.start(); epb.start();不断,我会得到一个错误:无法找到或加载主类:你好,因为当我执行epb.start();前一个命令(pb.start)可能尚未执行!
我得到了2个解决方案:
首先:在此字段中设置finally字段和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
}
第二: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
}
我使用第二个。