Interprocess communication between Python and Java

For my Research work I need to communicate between Python and Java/Scala application.

The first idea was to use WebSockets. It is universal and flexible. Additionally communication is easy. There are many ways to implement it:

Implementation would be easy, but we are using customized version of Python, which is included in GNAT Programming Studio. Some libraries (required for WebSockets) are excluded (because of legal reasons) and we wouldn’t be able to redistribute it along with missing packages. Thus, we decide to implement interprocess communication through pipes.

From Python to Java

The communication is one direction: from Python app to Java app. Every message is one line of text (ultimately: json format). E.g.: “text\r\n”. To close communication, we send message: “x\r\n”.

This is sample Java app, which write received messages to file result.txt:

import java.io.*;

public class MyClass {
	public static void main(String[] args) {
		try {
			BufferedReader bufferRead = new BufferedReader(new InputStreamReader(System.in));
			PrintWriter writer = new PrintWriter("result.txt", "UTF-8");
			String s = bufferRead.readLine();
			while(s.equals("x")==false) {
				writer.println(s);
				s = bufferRead.readLine();
			}
			writer.close();
		} catch(IOException e) {
			e.printStackTrace();
		}
	}
}

And here is sample Python app, which sends messages to Java app:

#!/usr/bin/python

import subprocess

p = subprocess.Popen(["java", "MyClass"], stdin=subprocess.PIPE)
p.stdin.write("First line\r\n")
p.stdin.write("Second line\r\n")
p.stdin.write("x\r\n") # this line will not be printed into the file

From Java to Python

We can also communicate in opposite direction: from Java app to Python app. To do that we just need to change reading to writing in Java app and writing to reading in Python app.

Change in Java app is simple: we just write to standard output.

import java.io.*;

public class MyClass2 {
	public static void main(String[] args) throws InterruptedException{
		System.out.println("First msg");
		System.out.println("Second msg");
		System.out.println("x");
	}
}

In Python app we need to create stdout pipe and read instead of write:

#!/usr/bin/python

import subprocess

p = subprocess.Popen(["java", "MyClass2"], stdout=subprocess.PIPE)
line = p.stdout.readline()
while(line != "x\n"):
	print line
	line = p.stdout.readline()

In this scenario, both processes are managed by Python app. You can also do it in opposite direction and invoke Python app from Java app.