Introduction

jpy is a bi-directional Python-Java bridge which you can use to embed Java code in Python programs or the other way round. It has been designed particularly with regard to maximum data transfer speed between the two languages. It comes with a number of outstanding features:

  • Fully translates Java class hierarchies to Python
  • Transparently handles Java method overloading
  • Support of Java multi-threading
  • Fast and memory-efficient support of primitive Java array parameters via Python buffers (e.g. numpy arrays)
  • Support of Java methods that modify primitive Java array parameters (mutable parameters)
  • Java arrays translate into Python sequence objects
  • Java API for accessing Python objects (jpy.jar)

jpy has been tested with Python 2.7 and 3.3 and an Oracle Java 7 JDK. It will presumably also work with Python 2.6 or 3.2 and a Java 6 JDK.

The initial development of jpy has been driven by the need to write Python extensions to an established scientific imaging application programmed in Java, namely the BEAM toolbox funded by the European Space Agency (ESA). Writing such Python plug-ins for a Java application usually requires a bi-directional communication between Python and Java since the Python extension code must be able to call back into the Java APIs.

How it works

The jpy Python module is entirely written in the C programming language. The same resulting shared library is used as a Python jpy module and also as native library for the Java library (jpy.jar).

Python programs that import the jpy module can load Java classes, access Java class fields, and call class constructors and methods.

Java programs with jpy.jar on the classpath can import Python modules, access module attributes such as class types and variables, and call any callable objects such as module-level functions, class constructors, as well as static and instance class methods.

Calling Java from Python

Instantiate Python objects from Java classes and call their public methods and fields:

import jpy

File = jpy.get_type('java.io.File')

file = File('test/it')
name = file.getName()

Calling Python from Java

Access Python attributes and call Python functions from Java:

PyModule sys = PyModule.importModule("sys");
PyObject path = sys.getAttribute("path");
path.call("append", "/usr/home/norman/");
String value = path.getStringValue();

Implementing Java interfaces using Python

With jpy you can implement Java interfaces using Python. We instantiating Java (proxy) objects from Python modules or classes. If you call methods of the resulting Java object, jpy will delegate the calls to the matching Python module functions or class methods. Here is how this works.

Assuming we have a Java interface PlugIn.java

public interface PlugIn {
    String[] process(String arg);
}

and a Python implementation bibo_plugin.py

class BiboPlugIn:
    def process(self, arg):
        return arg.split();

then we can call the Python code from Java as follows

// Import the Python module
PyModule plugInModule = PyLib.importModule("bibo_plugin");

// Get the Python class
PyObject plugInClass = plugInModule.getAttribute("BiboPlugIn");

// Call the Python class to instantiate an object
PyObject plugInObj = plugInClass.call();

// Create a Java proxy object for the Python object
PlugIn plugIn = plugInObj.createProxy(PlugIn.class);

String[] result = plugIn.process('Abcdefghi jkl mnopqr stuv wxy z');

Current limitations

  • Java non-final, static class fields are currently not supported: The reason is that Java classes are represented in jpy’s Python API as dynamically allocated, built-in extension types. Built-in extension types cannot have (as of Python 3.3) static, computed attributes which we would need for getting/setting Java static class fields.
  • Public final static fields are represented as normal (non-computed) type attributes: Their values are Python representations of the final Java values. The limitation here is, that they can be overwritten from Python, because Python does not know final/constant attributes. This could only be achieved with computed attributes, but as said before, they are not supported for built-in extension types.
  • It is currently not possible to shutdown the Java VM from Python and then restart it.

Other projects with similar aims

  • JPype - allow python programs full access to java class libraries
  • Jython - Python for the Java Platform
  • JyNI - Jython Native Interface
  • Jynx - improve integration of Java with Python