Inter-Process Communication between Python and Java
Implementing a self-contained, System independent JRE in the Python application
In order to make the Python application independent of the system as a whole, a JRE must be created inside the Python application. This must be done if it is desired that the application must not depend on the system and everything must be self-contained within the application. This is helpful if the application as a whole must be ready to run on any user's machine without any additional resources and procedures upon each installation.
Go to https://learn.microsoft.com/en-us/java/openjdk/download, download the JDK for your desired hardware architecture and OS, and load it inside the Python application's environment. Afterwards put the Java application project as a whole or a .jar
file made from the Java application within the Python application's directory.
You can then launch the Java application within the Python application as a sub-process.
Inter-Process communication methods
Real-time Inter-Process Communication using stdin, stout and stderr
The stdin
,stdout
, and stderr
streams are the main I/O systems that the OS kernel is using for applications and processes. By modifying the flow of these streams from child process to OS, to child process to parent process, these streams will be bypassed through the parent process and the parent process will have the ability to perform input and output operations directly with the child process
[ Java Code ]
public class Main {
public static void main(String[] args)
{
// Send input over the "stdout" stream to the Python parent process
System.out.println("Message from Java application");
System.out.flush();
// Read input over the "stdin" stream from the Python parent process
Scanner s = new Scanner(System.in);
String input = s.nextLine();
s.close();
// Send input over the "stdout" stream to the Python parent process
System.out.println(input);
System.out.flush();
}
}
[ Python Code ]
import subprocess
# Path to java.exe, in case the application contains a self-contained java environment, else just the "java" command
path_to_java_exe = "C:\\Users\\Teodor Mihail\\PycharmProjects\\Python_IPC\\jre\\bin\\java.exe"
# Command line argument that specifies the compiler what it should compile, in this case is a ".jar" file
java_exe_arguments = "-jar"
# The path to the file that the compiler will run and the runtime will execute, in this case it is the whole program compiled as a ".jar" file
java_jar_file_path = "C:\\Users\\Teodor Mihail\\PycharmProjects\\Python_IPC\\Java_I.P.C.jar"
# Global variable that holds the sub-process
process = None
def subprocess_startup():
# Specify that the "process" variable is a reference to the global variable "process"
global process
# Open the process and redirect the "stdin", "stdout", and "stderr" streams from the sub-process to the OS to the Python process
process = subprocess.Popen([path_to_java_exe, java_exe_arguments, java_jar_file_path], stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
def subprocess_read_stdout():
# Read the output sent by the Java application sub-process over the "stdout" stream
received = process.stdout.readline()
print(received)
def subprocess_write_stdin(data):
# Write input to the Java application over the "stdin" stream
process.stdin.write(data.encode("utf-8"))
process.stdin.flush()
def main():
subprocess_startup()
# A loop can be implemented here for continuous read and write operations.
# Both the read and write operation methods can be open on different threads
# to perform continuous read and write operations executed in parallel
subprocess_read_stdout()
# Data to be written on the stdin stream must end in "\n" otherwise the Java
# Scanner will lock. This will happen because the Scanner in Java is
# scanning until a "\n" is found, otherwise it will wait indefinitely
# until it will find a "\n" within the input stream.
subprocess_write_stdin("Message from Python application\n")
subprocess_read_stdout()
if __name__ == '__main__':
main()
At each process.stdin.write
method call, the data sent to the child process must be terminated with a newline character ("\n
"). This must be done because the Java scanner will scan the stdin
stream looking for a newline character, and because the stream is buffered, this will result into a lock on the thread on which this operation is performed.