17

First, a little explanation of why I'm asking this question in the first place: I'm writing a python program (with a wxPython gui) that needs to call a Java AWT program from python and extract data from it. I have an in-process working solution on Windows. I also have an in-process solution on OSX so long as I run the Java app headless. Unfortunately there is no reasonable solution that I have found for running both GUIs within the same process on OSX because both AWT and WX both want the first thread and cannot share the wx message loop.

What I would like to do is to launch a Java program in a separate process from my Python program and establish a pipe or queue or something for passing data (specifically byte arrays) back and forth.

I'd greatly appreciate any suggestions, or even a nudge in the right direction as I have very little experience with IPC.

Adam Fraser
  • 5,910
  • 8
  • 40
  • 53

6 Answers6

4

I attempted to code a solution using pipes but it seems that they just aren't well suited to sending multiple messages back and forth with potentially large data attached. Rather, they seem ideal for opening a "worker" style program that runs, responds, and dies.

Looking into socket programming, I found a fantastic resource here: https://web.archive.org/web/20080913064702/http://www.prasannatech.net/2008/07/socket-programming-tutorial.html

The tutorial presents TCP and UDP variants of a simple chat program written in 4 languages. I ended up using and modifying the TCP Java client and Python server.

Gamebuster19901
  • 144
  • 1
  • 8
Adam Fraser
  • 5,910
  • 8
  • 40
  • 53
3

This is the opensource solution Google uses to do IPC between Java and Python. https://code.google.com/p/protobuf/

Recommended.

Kenn
  • 2,329
  • 2
  • 29
  • 36
  • this is great. It's heavily relied on O-O model though, so it might not be possible for C like languages. But it answers this question + using sockets to send message. – ArmenB Apr 01 '15 at 01:30
3

Named pipes could be the answer for you. See: Create a temporary FIFO (named pipe) in Python?

Community
  • 1
  • 1
Jeremy Brown
  • 17,004
  • 3
  • 33
  • 27
  • Hrm, this seems easy from the Python angle, but from what I'm reading Java will only be able to treat the FIFOs as files and won't be able to create them in an OS-independent way. This should be fine for sending images to Java, but I'm not sure if it will suffice for getting them back. – Adam Fraser Aug 02 '10 at 16:04
  • FIFOs are platform-dependent and they are in fact used via file interfaces in UNIX (http://en.wikipedia.org/wiki/Named_pipe). If you're uncomfortable with that (or prefer something supported by standard libraries), you could just use a socket. – Jeremy Brown Aug 02 '10 at 20:17
1

Use subprocess.Popen to start the Java process and establish pipes to communicate with it. For serializing and deserializing data efficiently in a language-neutral, platform-neutral, extensible way, take a look at Protocol Buffers (contributed to by Jon Skeet!).

Community
  • 1
  • 1
Vebjorn Ljosa
  • 16,560
  • 13
  • 68
  • 82
1

IPC using subprocess from in python

IPC.java file here java code will receive number and send square of it.

import java.util.Scanner;

public class IPC {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String data="";
        while(scanner.hasNext()){
            // Receive data from Python code 
            data = scanner.nextLine();

            // Process data (calculate square)
            int x = Integer.parseInt(data);
            int square = x*x;


            // Send data to python code
            System.out.println(square);
        }
        scanner.close();
    }
}

IPC.py file

import subprocess
subprocess.run(["javac", "IPC.java"])
proc = subprocess.Popen(["java", "IPC"], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
for i in range(10):
    # Send to java code
    proc.stdin.write(b'%d\n' % i)
    proc.stdin.flush()
    proc.stdout.flush()

    # Receive data from java code
    output = proc.stdout.readline()
    print (output.rstrip())
proc.communicate()
Mr. A
  • 1,219
  • 18
  • 26
0

I had a similar situation where I had to communicate between a Java process and a Linux process. I used named pipes.

Try mkfifo() implementation in python.

wandermonk
  • 5,910
  • 4
  • 34
  • 84