1

由于我的项目的某些原因,我需要在 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)可以执行此代码?

4

1 回答 1

2

首先,使用 runtime.exe 生成进程违反了 EJB 规范,原因有很多。因此,正如他们所说,您一只手拿着枪,另一只手拿着子弹,如果您不了解这样做的含义,您很容易射中自己的脚。

您可以将此代码移动到 Servlet(仍部署到您选择的 JavaEE 容器中)以更加符合规范,但您仍然需要了解如果您的应用程序曾经在集群环境中运行,它将如何在集群环境中发挥作用。如果您需要该流程在数据库事务范围内进行交互,那么您会遇到更多问题,但假设这不是您的要求之一。

排除这些警告后,您当前的方法有一个重大缺陷,将导致不分青红皂白的线程死锁。当您启动一个进程时,您必须在它们自己的线程中管理 STDOUT/STDERR 流,以便缓冲区将耗尽而不会在两者之间出现死锁。您在这里没有这样做,您只是从您开始进程的同一线程中读取 InputStream。当你说“什么都没有发生”时,这很可能就是这里发生的事情。您是否对服务器进程进行了线程转储?

为了避免这种死锁,相信我,它们会在某个时候发生,使用类似于这里概述的模式:为什么 runtime.exec() 挂起

于 2013-04-23T17:01:26.307 回答