1

I know similar questions have been asked but after trying multiple different configurations I still have not quite found the solution I'm looking for. When I run my python file from java it prints all generated lines at once rather than printing as they execute.

I have a java program which displays a simple UI, once the user inputs all the arguments needed, I pass this information along to a working set of python scripts. Because the python program is quite extensive and takes a while to run there is a series of updated status messages which will print to the command prompt. In order to test running a process in Java I set up two simple test files.

My test java is as follows

Runtime rt = Runtime.getRuntime();
Process proc = rt.exec("python -u Test.py");
BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line = "";
while((line = b2.readLine()) != null){
    System.out.println(line);
}

My Test.py file looks like (edit) I added the Unbuffered class as shown in the linked example and still no luck.

class Unbuffered(object):
    def __init__(self,stream):
        self.stream = stream
    def write(self, data):
        self.stream.write(data)
        self.stream.flush()
    def __getattr__(self.stream, attr):
        return getattr(self.stream, attr)

sys.stdout = Unbuffered(sys.stdout)

print "Hello World"
time.sleep(5)
print "Hello again!"

When I run my java file, it waits 5 seconds before displaying both print lines from the python file. But I want it to not block the process and print out each line as its reached in the python file. Any help would be appreciated.

EDIT: (SOLVED)

My problem was I had to thread the new process outside of my main program. I ended up with something like

public class MyRunnable implements Runnable{
    public void run(){
        Runtime rt = Runtime.getRuntime();
        Process proc = rt.exec("python Test.py");
        StreamGobbler errGobbler = new StreamGobbler(proc.getErrorStream(), "Error");
        StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(), "Output");
        errGobbler.start();
        outputGobbler.start()
    }

public static void main(String[] args){
   MyRunnable myRun = new MyRunnable();
   Thread myThread = new Thread(myRun);
   myThread.start();
}
user2860682
  • 89
  • 2
  • 7
  • you need to use separate thread to read console output while main java thread is blocked – Iłya Bursov Jul 22 '14 at 15:32
  • I attempted to use the StreamGobbler method of threading the output and error streams with the given code here http://www.javaworld.com/article/2071275/core-java/when-runtime-exec---won-t.html?page=2 but it still only prints out as one lump output rather than as each print statement is reached. – user2860682 Jul 22 '14 at 15:52
  • The problem is the Python script. It needs to use unbuffered output, otherwise the two print statements are buffered and actually sent only when the Python program ends. See http://stackoverflow.com/q/107705/18157 – Jim Garrison Jul 22 '14 at 16:04
  • I added the what was suggested in your link and tried to run the program again and I am still running into the same issue. – user2860682 Jul 22 '14 at 16:34

0 Answers0