我有一个用于管理RTF文档创建的类,以及该类中的一个方法,该方法使用XML文件调用RTF编辑器进行显示。

除一个用户外,所有用户都可以毫无问题地访问此编辑器。这个用户一直遇到他们的应用程序挂起的问题。任何日志都没有错误。通常情况下,这种问题很容易被识别,复制和纠正,但是,我无法复制它,所以我的调试尝试都失败了。

基本上代码如下:

int exitVal = CUBSRTFEditor.runRTFEditor("c:\\tmp\\control"+ap_doc_id+".xml", xml,"I:\\AppealsLetters.exe /process \"c:\\tmp\\control"+ap_doc_id+".xml\"");

public static int runRTFEditor(String xmlLocation, String xmlContent, String executePath)
{
    int exitVal = 0;
    createLocalFile(xmlLocation, xmlContent);

    try
    {
        System.out.println("executePath must = "+executePath);
        Runtime rt = Runtime.getRuntime();
        Process proc = rt.exec(executePath);
        System.out.println("after executePath runs");

        //exhaust that stream before waiting for the process to exit
        InputStream inputstream = proc.getInputStream();
        InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
        BufferedReader bufferedreader = new BufferedReader(inputstreamreader);
        // read the ls output
        String line;
        while ((line = bufferedreader.readLine())!= null)
        {
            System.out.println(line);
        }
        exitVal = proc.waitFor();
    }
    catch (Throwable t)
    {
        t.printStackTrace();
    }

    CUBSRTFEditor.deleteTempFile(xmlLocation);

    return exitVal;
}

最后一个输出是第一个System.out。当我获取xml文件并在任何其他PC上执行它时,它会毫无问题地执行。我在proc.getErrorStream()或proc.getOutputStream()中看不到有用的信息。

关于这个问题的JDK的Javadoc文档(exec挂起): 由于某些本机平台仅为标准输入和输出流提供有限的缓冲区大小,因此无法及时写入输入流或读取子进程的输出流可能导致子进程阻塞,甚至死锁。

我尝试在等待进程退出之前耗尽该流,这似乎没有帮助,因为它似乎永远不会到达那一点(第二个System.out没有显示)

我是否错误地实施了这个?我错过了重要的事吗?关于如何从过程中获取更多信息的任何想法都会很棒。

我被困了......

有帮助吗?

解决方案

Runtime.exec()是一个看似令人讨厌的小问题。我找到了这篇文章(旧的,但是仍然相关)非常有帮助。您可以随时跳过第4页,了解一些高度可用的示例代码。 : - )

乍一看,您的代码需要同时处理proc.getOutputStream()和proc.getErrorStream(),这是在单独的线程中处理这些流的一个很好的理由。

其他提示

我想更新此内容,因为今天的更改已投入生产并正常运行。根据BlairHippo的建议,我得到它与匿名内部类一起使用来创建一个单独的线程来消耗错误和输入流。

new Thread(new Runnable(){
    public void run()
    {
        try
        {
            BufferedReader br = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
            String line;
            while ((line = br.readLine())!= null)
            {
                System.out.println(line);
            }
        }
        catch (Throwable t)
        {
            t.printStackTrace();
        }
    }
}).start();
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top