0

I have a Java code calling Python through an asynchronous process, and I want the Python process to listen to stdout from Java until something printed.

Following is the java code:

import java.io.*;

public class host {
    public static void main(String[] args) throws Exception{
        System.out.println("java starts at " + System.currentTimeMillis() + " ms");
        ProcessBuilder pb = new ProcessBuilder("python","a.py");
        Process tr = pb.start();
        System.out.println("First msg");
        System.out.println("Second msg");
        Thread.sleep(3000);
        System.out.println("x");
        System.out.println("java ends at " + System.currentTimeMillis() + " ms");
    }
}

and following is the python code:

import sys
import time
if __name__=="__main__":
    fo=open("a.txt","w")
    fo.write('python starts at: %.0f\n'%(time.time()*1000))
    line = sys.stdout.readline()
    while(line != "x\n"):
        fo.write(line+"\n")
        line = sys.stdout.readline()
    fo.write('python ends at: %.0f\n'%(time.time()*1000))
    fo.close()

However, the Python process seemed not be able to capture the stdout from Java. Since I am new to Java, I am not sure whether there is something fundamentally wrong or not, and whether the above model provides an effective way between Java and Python communication.

EDIT (UPDATE)

Based on the answers/comments, I modified my Java code as follows:

import java.io.*;

public class host {
    public static void main(String[] args) throws Exception{
        System.out.println("java starts at " + System.currentTimeMillis() + " ms");
        ProcessBuilder pb = new ProcessBuilder("python","a.py");
        Process tr = pb.start();
        PrintStream ps = new PrintStream(tr.getOutputStream());
        ps.println("First msg"); ps.flush();
        ps.println("Second msg"); ps.flush();
        Thread.sleep(3000);
        ps.println("x"); ps.flush();
        System.out.println("java ends at " + System.currentTimeMillis() + " ms");
    }
}

and changed python script as follows:

import sys
import time
if __name__=="__main__":
    fo=open("a.txt","w")
    fo.write('python starts at: %.0f\n'%(time.time()*1000))
    line = sys.stdin.readline()
    while(line != "x\n"):
        fo.write(line+"\n")
        line = sys.stdin.readline()
    fo.write('python ends at: %.0f\n'%(time.time()*1000))
    fo.close()

And following is the output:

python starts at: 1453263858103
First msg

First msg

Second msg

python ends at: 1453263863103
7
  • Have you tinkered with redirect? docs.oracle.com/javase/7/docs/api/java/lang/… Commented Jan 19, 2016 at 22:25
  • Your ProcessBuilder and the new runtime environment it creates when starting python has its own in, out and err streams. They are different from the Syste.in/out/err. Use the ProcessBuilder.redirectInput(). Commented Jan 19, 2016 at 22:26
  • @ JayC667 That's what I thought also, but how do I pass Java stdout to python? Commented Jan 19, 2016 at 22:27
  • See stackoverflow.com/questions/14165517/… as a simple example Commented Jan 19, 2016 at 22:29
  • you can't read from stdout. you read from stdin. Commented Jan 19, 2016 at 22:44

2 Answers 2

2

The receiving process should listen to stdin, not stdout.

Then pipe the output from java to python:

java -jar myjava.jar | python mylistener

Sign up to request clarification or add additional context in comments.

Comments

1

In java, write to the process you created:

ProcessBuilder pb = new ProcessBuilder("python","a.py");
Process tr = pb.start();
tr.getOutputStream().println("First msg");

In python, read from stdin:

line = sys.stdin.readline()

6 Comments

I edit my script as you suggestions with minor modifications, but still have problem (see the question)
there isn't even the first and last lines? ("python starts/ends"?)
Sorry I missed that: what do you mean by "python starts/ends"?
those lines you write at the begining and the end of your file?
I had to kill python before the output text file is getting really huge.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.