0

I am unable to read the complete output of the program and sometimes it hangs the interface and does not compiles completely. In the output console of the netbeans it displays complete output but not in jtextarea.

Help me out to first execute command in cmd(command prompt) and then read output to textarea from cmd.

In cmd the command executes quickly with complete results. But I have no idea how to get results from cmd.

Here is my code:

String line;
String [] cmds={"xyz.exe","--version"};
try{
 Process p =Runtime.getRuntime().exec(cmds);                   
     p.waitFor();
     int val=p.exitValue();
     if(val==0)
     {
         b1.setForeground(Color.green);                              
         InputStream ins = p.getInputStream();
         InputStreamReader insr = new InputStreamReader(ins);
         BufferedReader br = new BufferedReader(insr);
         while ((line = br.readLine()) != null) {
           System.out.println( line);
           t1.setText( line);
         } 
     } else if(val==1)
     {
         b1.setForeground(Color.red);
         InputStream error = p.getErrorStream();
         InputStreamReader isrerror = new InputStreamReader(error);
         BufferedReader bre = new BufferedReader(isrerror);
         while ((line = bre.readLine()) != null) {
           t1.setText(line);

         }
     }
    } catch(IOException e){
        System.out.println("error");
        e.printStackTrace();
      } catch (InterruptedException ex) {
          Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex);
        }
CRABOLO
  • 8,605
  • 39
  • 41
  • 68
Azeem Aslam
  • 554
  • 5
  • 19
  • Yours is a thread problem where your long-running process is blocking the Swing event thread. Search on Swing and threading. This is a common problem and the results you find will be directly applicable to your problem. – Hovercraft Full Of Eels Dec 18 '13 at 02:42
  • Would you please suggest me some related reading or the problem in this code this . – Azeem Aslam Dec 18 '13 at 02:45
  • If I am understanding this question properly, it is much like mine found in this thread: http://stackoverflow.com/questions/20600721/display-indeterminate-jprogressbar-while-batch-file-runs Trashgod has offered an excellent example of how to do this properly. Again, this is assuming I'm understanding your question correctly – DerStrom8 Dec 18 '13 at 03:04

1 Answers1

0

The problem I see is this. You are trying to execute a program but you are not reading from the outputstream (ie. getInputStream() of Process) of the program until it has finished executing. So if your subProcess happens to have a lot of output and it exhausts the buffers, then the subProcess will be blocked.

So to solve your problem, you need to be absolutely reading the inputstream and errorstream while the subprocess is still executing to avoid the subprocess being blocked. You can either use blocking IO which means you need separate threads to service outputstream and errorstream or non blocking IO which you can use 1 thread that continually monitor outputstream & errorstream for data to be read.

Java Docs on java.lang.Process says

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.

import java.io.*;
import java.nio.channels.*;
import java.nio.*;

public static void nioExecute() throws Exception {
    Process p = Runtime.getRuntime().exec("javac");
    ReadableByteChannel stdoutChannel = Channels.newChannel(p.getInputStream());
    ReadableByteChannel stderrChannel = Channels.newChannel(p.getErrorStream());
    ByteBuffer buffer = ByteBuffer.allocate(1000);

    StringBuilder stdOut = new StringBuilder();
    StringBuilder stdErr = new StringBuilder();

    while(stdoutChannel.isOpen() || stderrChannel.isOpen()) {
        buffer.clear();
        if(stderrChannel.isOpen()) {
            int bytesRead = stderrChannel.read(buffer);
            if(bytesRead>0) stdErr.append(new String(buffer.array(),0,bytesRead));
            if(bytesRead==-1) stderrChannel.close();
        }
        buffer.clear();
        if(stdoutChannel.isOpen()) {
            int bytesRead = stdoutChannel.read(buffer);
            if(bytesRead>0) stdOut.append(new String(buffer.array(),0,bytesRead));
            if(bytesRead==-1) stdoutChannel.close();
        }
        Thread.sleep(100);
    }

    if(stdOut.length()>0) System.out.println("STDOUT: " + stdOut);
    if(stdErr.length()>0) System.out.println("STDERR: " + stdErr);
}
anonymous
  • 1,317
  • 8
  • 7
  • I did a quick test code for your reference. I chose Nonblocking IO (NIO) so you can do the entire thing in existing thread (may not be the best option either :-)). This code shows how you can read off the input and error stream into a buffer and then printout the entire thing. – anonymous Dec 19 '13 at 02:24
  • it is working fine for small output but still for a big output the program is not working. The output is of around 1000 words. – Azeem Aslam Dec 19 '13 at 23:45
  • I have edited the test program to read in data faster by sleeping 100ms rather than 1000 ms. I have also used buffer.clear() rather than buffer.rewind(). – anonymous Dec 20 '13 at 00:16
  • http://stackoverflow.com/questions/20600721/display-indeterminate-jprogressbar-while-batch-file-runs ---Answer to this Question is working fine but i am trying to marge it with my program in netbeans jform file against a button event. :/ – Azeem Aslam Dec 20 '13 at 01:00