Why not use Jython? The only downside I can immediately think of is if your library uses CPython native extensions.

EDIT: If you can use Jython now but think you may have problems with a later version of the library, I suggest you try to isolate the library from your app (e.g. some sort of adapter interface). Go with the simplest thing that works for the moment, then consider JNI/CPython/etc if and when you ever need to. There's little to be gained by going the (painful) JNI route unless you really have to.

Answer from Jon Skeet on Stack Overflow
Top answer
1 of 12
38

Why not use Jython? The only downside I can immediately think of is if your library uses CPython native extensions.

EDIT: If you can use Jython now but think you may have problems with a later version of the library, I suggest you try to isolate the library from your app (e.g. some sort of adapter interface). Go with the simplest thing that works for the moment, then consider JNI/CPython/etc if and when you ever need to. There's little to be gained by going the (painful) JNI route unless you really have to.

2 of 12
21

Frankly most ways to somehow run Python directly from within JVM don't work. They are either not-quite-compatible (new release of your third party library can use python 2.6 features and will not work with Jython 2.5) or hacky (it will break with cryptic JVM stacktrace not really leading to solution).

My preferred way to integrate the two would use RPC. XML RPC is not a bad choice here, if you have moderate amounts of data. It is pretty well supported — Python has it in its standard library. Java libraries are also easy to find. Now depending on your setup either Java or Python part would be a server accepting connection from other language.

A less popular but worth considering alternative way to do RPCs is Google protobuffers, which have 2/3 of support for nice rpc. You just need to provide your transport layer. Not that much work and the convenience of writing is reasonable.

Another option is to write a C wrapper around that pieces of Python functionality that you need to expose to Java and use it via JVM native plugins. You can ease the pain by going with SWIG SWIG.

Essentially in your case it works like that:

  1. Create a SWIG interface for all method calls from Java to C++.
  2. Create C/C++ code that will receive your calls and internally call python interpreter with right params.
  3. Convert response you get from python and send it via swig back to your Java code.

This solution is fairly complex, a bit of an overkill in most cases. Still it is worth doing if you (for some reason) cannot afford RPCs. RPC still would be my preferred choice, though.

🌐
GitHub
github.com › madhawav › J2PBind
GitHub - madhawav/J2PBind: Java to Python Bindings
Generates Intellisense friendly Python bindings on Java Classes.
Author   madhawav
🌐
Py4j
py4j.org
Welcome to Py4J — Py4J
Py4J also enables Java programs to call back Python objects.

Why not use Jython? The only downside I can immediately think of is if your library uses CPython native extensions.

EDIT: If you can use Jython now but think you may have problems with a later version of the library, I suggest you try to isolate the library from your app (e.g. some sort of adapter interface). Go with the simplest thing that works for the moment, then consider JNI/CPython/etc if and when you ever need to. There's little to be gained by going the (painful) JNI route unless you really have to.

Answer from Jon Skeet on Stack Overflow
🌐
Python
wiki.python.org › moin › IntegratingPythonWithOtherLanguages
IntegratingPythonWithOtherLanguages
July 29, 2020 - Tools to make C/C++ functions/methods accessible from Python by generating binding (Python extension or module) from header files.
🌐
Jython
jython.org
Home | Jython
The Jython project provides implementations of Python in Java, providing to Python the benefits of running on the JVM and access to classes written in Java. The current release (a Jython 2.7.x) only supports Python 2 (sorry).
🌐
Baeldung
baeldung.com › home › java › how to call python from java
How to Call Python From Java | Baeldung
August 27, 2025 - As previously mentioned, we’ve made the assumption that the python command is available via the PATH variable. JSR-223, which was first introduced in Java 6, defines a set of scripting APIs that provide basic scripting functionality. These methods provide mechanisms for executing scripts and for sharing values between Java and a scripting language.
🌐
Wikipedia
en.wikipedia.org › wiki › Language_binding
Language binding - Wikipedia
October 29, 2025 - In the context of software libraries, bindings are wrapper libraries that bridge two programming languages, so that a library written for one language can be used in another language. Many software libraries are written in system programming languages such as C or C++. To use such libraries ...
Find elsewhere
🌐
Reddit
reddit.com › r/java › best way to combine python and java?
r/java on Reddit: Best way to combine Python and Java?
October 29, 2022 -

My project uses some packages that are available only in Python and heavily rely on C libraries. The project also greatly benefits from Java libraries and the JVM. What's the optimal way to call Python functions from Java?

I tried:

  1. Small web-services: overhead to serialize data, start and stop the services. Also debugging is harder and implementing each new function is now double the effort.

  2. Jpy: a library that runs an interpreter in the JVM. Spare the service start/stop, but: isn't really feasible for more than a single-liner, data translation between Java and Python is cumbersome, and I also encountered runtime segmentation fault errors.

Any other options?

The project is in the machine-learning domain, so involves exchanging large numeric arrays and text. In some cases the execution switches back and forth between the platforms.

🌐
SourceForge
jpype.sourceforge.net
JPype - Java to Python integration
Links: Python Java Jython/JPython · Similar Projects : JEP JPE
🌐
Medium
medium.com › @shmulikamar › https-medium-com-shmulikamar-connecting-python-and-java-with-rust-11c256a1dfb0
Connecting Python and Java with Rust | by Shmuel Amar | Medium
June 10, 2019 - There are some projects to import Java from Python (which seem less production ready). Taking a look at how PySpark solved it gives us a glance on the complexity of this issue. Rust comes to the rescue — as the shared library with bindings for both languages (link to the full project on github).
🌐
Oracle
docs.oracle.com › en › java › javase › 21 › core › call-native-functions-jextract.html
Calling Native Functions with jextract - Java
October 20, 2025 - The Python script prints the length of a Java string. Run the following command to generate Java bindings for Python.h:
🌐
GitHub
github.com › jpype-project › jpype › discussions › 1071
How can we make Python's C-API more friendly for Java bindings? · jpype-project/jpype · Discussion #1071
The solution that I was forced to go to as Python does not support multiple true multiple inheritance was to borrow the same system as used by weak_ref system. I created a custom allocator which added an extra set of bytes to the end of the class and then inserted my slot space after the regular space. Obviously this only supports one extra slot but as objects from a language binding only need one language (you won't have a type which is both Java and C# wrapper at the same time), this isn't a big restriction.
Author   jpype-project
🌐
Devmio
devm.io › python › integrating-python-with-java-170663
Integrating Python with Java
April 21, 2020 - Python is an object-oriented scripting language, which automatically makes it a good pair for Java. But when combined with a Python interpreter written entirely in Java, like Jython, you could do things like write entire applets in Python.
🌐
GitHub
github.com › ValveSoftware › GameNetworkingSockets › issues › 8
Java / Python bindings · Issue #8 · ValveSoftware/GameNetworkingSockets
March 31, 2018 - First of all, thank you for releasing the library as open source! Are there any plans implementing Java and/or Python bindings?
🌐
GNU
gnu.org › software › libextractor › manual › html_node › Language-bindings.html
Language bindings - The GNU libextractor Reference Manual
GNU libextractor works immediately with C and C++ code. Bindings for Java, Mono, Ruby, Perl, PHP and Python are available for download from the main GNU libextractor website. Documentation for these bindings (if available) is part of the downloads for the respective binding.
🌐
GitHub
github.com › bcdev › jpy
GitHub - bcdev/jpy: A bi-directional Python-Java bridge used to embed Java in CPython or the other way round. · GitHub
August 5, 2021 - A bi-directional Python-Java bridge used to embed Java in CPython or the other way round. - bcdev/jpy
Starred by 188 users
Forked by 37 users
Languages   C 54.6% | Java 25.9% | Python 18.7%
Top answer
1 of 6
14

Interpreters Written in C89 with Reflection, Who Knew?


I have a feeling you are looking for an explanation of the mechanism and not a link to the API or instructions on how to code it. So, as I understand it . . .

The main interpreter is typically written in C and is dynamically linked. In a dynamically linked environment, even C89 has a certain amount of reflective behavior. In particular, the dlopen(3) and dlsym(3) calls will load a dynamic (typically ELF) library and look up the address of a symbol named by a string. Give that address, the interpreter can call a function. Even if statically linked, the interpreter can know the address of C functions whose names are compiled into it.

So then, it's just a simple matter of having the interpreted code tell the interpreter to call a particular native function in a particular native library.

The mechanism can be modular. An extension library for the interpreter, written in the script, can itself invoke the bare hooks for dlopen(3) and dlsym(3) and hook up to a new library that the interpreter never knew about.

For passing simple objects by value, a few prototype functions will typically allow various calls. But for structured data objects (imagine stat(2)) the wrapper module needs to know the layout of the data. At some point, either when packaging the extension module or when installing it, a C interface module includes the appropriate header files and in conjunction with handwritten code constructs an interface object. This is why you may need to install something like libsqlite3-dev even if you already had sqlite3 on your system; only the -dev package has the .h files needed to recompile the linkage code.

I suppose we could sum this up by saying: "it's done with brute force and ignorance". :-)

2 of 6
7

The main general concept is known as FFI, "Foreign Function Interface" -- for Java it's JNI, for Python it's the "Python C API", for Perl it's XS, etc, etc, but I think it's important to give you the general term of art to help you research it more thoroughly.

Given a FFI, you can write (e.g.) C programs that respect it directly, and/or you can have code generators that produce such C code from metainformation they receive and/or introspect from code written in other languages (often with some help, e.g., to drive the SWIG code generator you typically decorate the info that's in a .h C header file with extra info that's SWIG-specific to get a better wrapper).

There are also special languages such as Cython, an "extended subset" of Python that's geared towards easy generation of FFI code while matching much of Python's syntax and semantics -- may often be the easiest way for mostly-Python programmers to write a Python extension module that compiles down to speedy machine code and maybe uses some existing C-callable libraries.

The ctypes approach is different from the traditional FFI approaches, though it self-describes as a "foreign function library for Python" -- it relies on the foreign code being available in a DLL (or equivalent, such as an .so dynamic library in Linux), and generates and executes code at run-time to reach into such dynamically loaded C code (typically all done via explicit programming in Python -- I don't know of ctypes wrappers based on introspection and ctypes-code generation, yet). Handy to avoid having to install anything special for simple tasks of accessing existing DLLs with Python, but I think it doesn't scale up as well as the FFI "linker-based" approaches (as it requires more runtime exertion, etc, etc). I don't know of any other implementation of such an approach, targeting other languages, beyond ctypes for Python (I imagine some do exist, given today's prevalence of DLL and .so packaging, and would be curious to learn about them).

🌐
LinkedIn
linkedin.com › pulse › integrating-python-java-guide-developers-myexamcloud-7g5bc
Integrating Python and Java: A Guide for Developers
December 26, 2023 - JPype is a Python module that enables integration with Java code via Java Virtual Machine (JVM). It provides an easy-to-use interface to call Java functions and libraries from within a Python program.
🌐
pytz
pythonhosted.org › javabridge › java2python.html
Calling Python from Java — python-javabridge 1.0.12 documentation
The Javabridge loads a Java class, ... it can be used within Java to run Python embedded in Java. ... The CPython class binds the Python interpreter to the JVM and provides the ability to execute Python scripts....