由于某些原因我的项目需要在Java EE服务器上运行此命令“gcc file.c -o file.exe”,我使用了这个java代码
try {
Runtime runtime = Runtime.getRuntime();
String[] cmd={"cmd.exe","/C gcc " + a +".c" + " -o "+b};
Process p = runtime.exec(cmd,null,null );
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getErrorStream()));
String line = null;
try {
while((line = reader.readLine()) != null) {
System.out.println(line);
}
} finally {
reader.close();
}
} catch(IOException ioe) {
ioe.printStackTrace();
}
}
catch (Exception e) {System.out.println("erreur d'execution"); }
}
该命令在cmd上完美运行,并且此代码在Java应用程序上完美运行,我得到输出(.exe)和我的错误。
稍后我尝试在服务器上部署它(使用JBoss服务器)时没有发生任何事情。我后来尝试从服务器执行cmd也没发生任何事情。所以它是一种Java EE服务器问题。
我该如何解决?是否有其他服务器如Tomcat可以执行此代码?
答案 0 :(得分:0)
首先,由于多种原因,使用runtime.exe生成进程违反了EJB规范。因此,如果你不理解这样做的含义,你只能用一只手拿着枪,而另一只手拿着子弹,如果你不明白这样做的话,你可以很容易地用脚射击自己。
您可以将此代码移动到Servlet(仍然部署到您选择的JavaEE容器中)以更符合规范,但是如果您的应用程序在这样的应用程序中运行,您仍然需要了解它将如何在集群环境中发挥作用。如果您需要进程在数据库事务范围内进行交互,那么您会遇到更多问题,但我们假设这不是您的要求之一。
有了这些警告,你当前的方法有一个主要的缺陷,将导致不分青红皂白的线程死锁。当你启动一个进程时,你必须在它们自己的线程中管理STDOUT / STDERR流,这样缓冲区就会消耗掉,而不会在两者之间出现死锁。你不是在这里做的,你只是从你开始进程的同一个线程中读取InputStream。当你说 - “没有任何反应”时,这很可能就是这里发生的事情。您是否对服务器进程进行了线程转储?
为了避免这种死锁,并且它们会在某些时候发生信任我,请使用类似于此处概述的模式:Why runtime.exec() hangs