views:

247

answers:

2

I have a class that manages the creation of RTF documents and a method in that class that calls the RTF editor with a xml file for display.

All but one user can access this editor without any issues. This one user consistently runs into an issue where their application just hangs. There are no errors in any logs. Normally this kind of problem is easily identified, reproduced and corrected, however, I can't for the life of my reproduce it so my attempts at debugging are failing.

Basically the code is as follows:

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

The last output is the first System.out. When I take the xml file and execute this on any other PC it executes without issue. I see no useful info in proc.getErrorStream() or proc.getOutputStream().

The JDK's Javadoc documentation on this problem (exec hanging): Because some native platforms only provide limited buffer size for standard input and output streams, failure to promptly write the input stream or read the output stream of the subprocess may cause the subprocess to block, and even deadlock.

I try exhausting that stream before waiting for the process to exit and that does not seem to help as it never seems to get to that point (the second System.out is not displayed)

Have I implemented this incorrectly? Am I missing something important? Any ideas on how to get more info out of the process would be great.

I am stuck....

+2  A: 

Runtime.exec() is a deceptively nasty little spud to work with. I found this article (old, but still relevant) to be quite helpful. You can always skip to Page 4 for some highly gankable sample code. :-)

At a glance, your code needs to handle both proc.getOutputStream() and proc.getErrorStream(), which is a good reason to handle those streams in separate threads.

BlairHippo
+1 for the link. This is a great link and I have read it twice from front to back already. It was useful but didn't quite help. I did add the proc.getOutputStream() as well but still no luck.
northpole
See my edited answer; you also need to hit proc.getErrorStream(). Preferably in their own individual threads.
BlairHippo
A: 

I wanted to update this because the change went into Production today and worked. Based off of BlairHippo's suggestions I got it to work with an anonymous inner class to create a separate thread to exhaust both the Error and Input streams.

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();
northpole