In practice, more and more use cases are emerging where both languages are combined to produce better results. For example, in a microservices architecture:
All services operate independently, allowing both languages to be used in parallel without issues and interruptions.
The following table provides a brief overview of when and how Java should be combined with Python.
situation | recommendation |
---|---|
A lot of data |
✅ Python + Java |
Performance |
✅ Java as the base |
KI/ML |
✅ Python for models |
Architecture |
✅ Microservices |
Here are some practical examples for combining Python and Java:
- Data analysis and machine learning: Libraries like NumPy, Pandas, TensorFlow, or Scikit-Learn are leading in Python.
- Rapid prototyping: Python enables faster development of prototypes, which can later be integrated into Java.
- Reusing existing codebases: Companies often use existing Python modules integrated into new Java applications.
Approaches to Integrating Python Into JavaÂ
Jython
Jython is an implementation of Python that runs on the Java Virtual Machine (JVM). This allows Python modules to be used directly in Java.
Advantages of Jython:
- Seamless integration with the JVM
- Direct access to Java classes from Python and vice versa
Disadvantages of Jython:
- Supports only Python 2.x (no support for Python 3.x)
- Many modern libraries do not work because they require Python 3.x
ProcessBuilder (External Script Execution)
A simple, yet effective way to use Python libraries in Java is by running Python scripts as external processes.
Advantages of ProcessBuilder:
- Full support for all Python versions and libraries
- There are no dependencies on bridges or special APIs
Disadvantages of ProcessBuilder:
- Performance overhead due to process start
- Error handling is more complex
Py4J
Py4J is another bridge between Python and Java. Originally developed for Apache Spark, it allows Python to manipulate Java objects and execute Java methods.
Advantages of Py4J:
- Lightweight and easy to integrate
- Supports bidirectional communication
Disadvantages of Py4J:
- There is more overhead during setup
- Better suited for scenarios where Python is the driver
Alternatives: Java Libraries as Replacements for PythonÂ
If the integration is too complicated, many powerful Java libraries offer similar functionalities to Python libraries:
Python Library | Java Alternative | Use case |
---|---|---|
NumPy | ND4J, Apache Commons Math | Calculation |
Pandas | Tablesaw, Apache Arrow | Data analysis |
Scikit-Learn | Weka, Deeplearning4j | MML |
TensorFlow | TensorFlow for Java, DL4J | Deep Learning |
Matplotlib/Seaborn | JFreeChart, XChart | Data visualization |
Jython Examples for a Maven ProjectÂ
You need to include the Jython dependency in your pom.xml
to use Jython in a Maven project. The latest version of Jython can be downloaded from https://www.jython.org/download and included as a JAR file. Alternatively, the library can be integrated via dependency management. To do this, the project’s POM file must be extended as follows, using version 2.7.2:Â
org.python
jython-standalone
2.7.2
We will create a simple example where a Python script performs a calculation, and the result is processed further in Java.
Python code (inline within Java code):
import org.python.util.PythonInterpreter;
import org.python.core.PyObject;
public class JythonExample {
public static void main(String[] args) {
PythonInterpreter interpreter = new PythonInterpreter();
interpreter.exec(
"def add_numbers(a, b):\n" +
" return a + b\n" +
"\n" +
"result = add_numbers(10, 20)"
);
PyObject result = interpreter.get("result");
int sum = result.asInt();
System.out.println("Result: " + sum);
}
}
In this example, the Python interpreter is first initialized: Â
PythonInterpreter interpreter = new PythonInterpreter();
And then the Python code is executed directly executed within the Java class:
interpreter.exec(
"def add_numbers(a, b):\n" +
" return a + b\n" +
"\n" +
"result = add_numbers(10, 20)"
    );
Here, a simple Python function add_numbers
is defined, which adds two numbers. The function is called with the values 10 and 20, and the result is stored in the variable result
.
The result is retrieved with the following command:
PyObject result = interpreter.get("result");
int sum = result.asInt();
With interpreter.get("result")
, the result from the Python script is retrieved and converted into a Java variable (int).
The result can, for example, be output as follows:
System.out.println("Result: " + sum);
Java variables can also be passed to the Python script. Here is an extended example:
import org.python.util.PythonInterpreter;
import org.python.core.PyInteger;
public class JythonExampleWithInput {
public static void main(String[] args) {
PythonInterpreter interpreter = new PythonInterpreter();
int a = 15;
int b = 25;
interpreter.set("a", new PyInteger(a));
interpreter.set("b", new PyInteger(b));
interpreter.exec(
"def multiply_numbers(x, y):\n" +
" return x * y\n" +
"\n" +
"result = multiply_numbers(a, b)"
);
int result = interpreter.get("result").asInt();
System.out.println("Result: " + result);
}
}
In the next example, an external Python file named script.py
is placed in the src/main/resources
directory of the Maven project.
my-maven-project/
│
├── pom.xml
│
├── src
│ ├── main
│ │ ├── java
│ │ │ └── your/package/main.java
│ │ └── resources
│ └── script.py
│
└── target/
Why src/main/resources
?
- Everything in the
src/main/resources
directory is copied to thetarget/classes
folder when the project is built - You can load these files at runtime using the ClassLoader
This is a Maven convention commonly used in Java projects to store non-Java resources like configuration files, properties, XML, JSON, or other static data needed at runtime.
The script is defined as follows:
def add_numbers(a, b):
return a + b
result = add_numbers(5, 15)
print("Result: {}".format(result))
The corresponding Java class is defined as follows:
import org.python.util.PythonInterpreter;
import java.io.FileReader;
import java.io.IOException;
public class JythonExternalScriptExample {
public static void main(String[] args) {
PythonInterpreter interpreter = new PythonInterpreter();
try {
FileReader pythonScript = new FileReader("script.py");
interpreter.execfile(pythonScript);
pythonScript.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Initialization of the interpreter:
PythonInterpreter interpreter = new PythonInterpreter();
Loading the external script:
FileReader pythonScript = new FileReader("script.py");
Executing the script: Â
interpreter.execfile(pythonScript);
Closing the FileReader: Â
ConclusionÂ
With Jython, you can easily execute external Python scripts from Java. The integration works well for simple scripts, especially when passing parameters from Java to Python. However, for more complex Python 3 libraries, you should consider alternatives like Py4J or directly executing Python processes using ProcessBuilder.
Jython offers a simple but outdated solution, while Py4J and JPype create more flexible bridges between the two languages. However, executing external Python scripts is the simplest method in many cases.
For long-term projects or when performance is a major concern, it may be worth looking for Java alternatives that offer native support and can be more easily integrated into existing Java projects.