Call Java class from CPython (Py4J)

There are the following methods to call and use Java libraries from Python.

Jython

http://www.jython.org/

The interpreter itself is implemented in Java, so in a Python script You can use Java classes and standard libraries as they are. It's the quickest, but compatibility with CPython matters. (Some CPython standard libraries do not support it, etc.)

Learn how to call a jar in Jython http://qiita.com/mojaie/items/9add34871a43c4181af7

JPype

http://jpype.sourceforge.net/

Call Java classes from Python via JNI, which integrates C and Java. You can call Java smoothly from CPython, but the installation process is very troublesome. (It may not even be possible to install depending on the compatibility of dependent modules such as C compiler)

Py4J

http://py4j.sourceforge.net/

Start the server on the Java virtual machine and link CPython and Java with socket communication. It's slower than the method above, but because Java and Python are completely independent, The environment can be built relatively easily and packaging is easy.

This time, I will introduce how to call a jar file using Py4J.

Installation

pip install py4j

If you have not installed python or java, please install it. Since the installation folder (share folder?) Contains a file called py4j0.7.jar, Copy it to a suitable location and put it in Java's CLASSPATH.

Creating a Java server program

First, create a server class to call the existing java class. Below is a method for calling a method called getString in a class called JClass. This is an example of the JClassEntryPoint class.

JClassEntryPoint.java



import py4j.GatewayServer;

public class JClassEntryPoint {

	private JClass jclass = null;

	public JClassEntryPoint() {
		this.jclass = new JClass();
	}
	
	public String getString(String str) {
		return jclass.getString();
	}

	public static void main(String[] args) {
		GatewayServer gatewayServer = new GatewayServer(new JClassEntryPoint());
		gatewayServer.start();
	}
}

class JClass {

	private String str = "hogehoge";

	public String getString(String str) {
		return this.str;
	}
}

Make JClassEntryPoint.java an executable jar file.

Creating a calling Python script

First, use subprocess to execute the above jar file. The server will start and you will be able to load Java classes via Java Gateway. Also, by using atexit.register (), at the end of the Python script You can shut down the server automatically. time.sleep (2) prevents Java Gateway from trying to communicate with the server before it starts. It is a painstaking measure to prevent it. I think there is a better way.

jclassclient.py



import atexit
import subprocess
import time
from py4j.java_gateway import JavaGateway


class JClassClient(object):

    def __init__(self):
        self._gateway = None
        self._process = None
        cmd = ["java", "-jar", "/path/to/jarfile/JClassEntryPoint.jar", "JClassEntryPoint"]
        self._process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
        print "jvmprocess started: " + str(self._process.pid)
        atexit.register(self._process.kill)
        time.sleep(2)
        self._gateway = JavaGateway()

    def getString(self):
        return self._gateway.entry_point.getString()


def main():
    client = JClassClient()
    print client.getString()

if __name__ == "__main__":
    main()

Recommended Posts

Call Java class from CPython (Py4J)
An easy way to call Java from Python
Call CPLEX from Python (DO cplex)