Install & Compatibility
Where this runs
tested against v0.10.9.9 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.95 runs
installs and imports cleanly · install 0.0s · import 0.158s · 18.6MB
glibcpy 3.10–3.95 runs
installs and imports cleanly · install 1.8s · import 0.136s · 19MB
17MB installed
● package 17MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
JavaGateway
✓ from py4j.java_gateway import JavaGateway
GatewayParameters
✓ from py4j.java_gateway import GatewayParameters
This quickstart demonstrates how to connect a Python client to a Java Gateway Server, access an entry point object, and call Java methods. It includes a simplified Python-driven setup for the Java server (which usually runs independently). The example performs basic addition via a custom Java class and interacts with a standard Java `ArrayList`. Users *must* replace `/path/to/py4j<version>.jar` with the actual path to their Py4J JAR file for the Java compilation and execution to succeed.
import os
from py4j.java_gateway import JavaGateway, GatewayParameters
import subprocess
import time
# --- Java Gateway Server Setup (for demonstration) ---
# In a real application, the Java Gateway Server would be started separately.
# For this example, we'll try to start a minimal one programmatically.
# This assumes 'py4j<version>.jar' is in the classpath. For simplicity,
# we'll use a placeholder for py4j.jar path. Users need to replace it.
# Usually, py4j.jar is found in your Python environment's site-packages/py4j/ directory.
# NOTE: Replace '/path/to/py4j<version>.jar' with the actual path to your Py4J JAR file.
# You can find it by running: `python -c "import py4j; import os; print(os.path.join(os.path.dirname(py4j.__file__), 'py4j0.10.9.9.jar'))"`
PY4J_JAR_PATH = os.environ.get('PY4J_JAR_PATH', '/path/to/py4j0.10.9.9.jar') # Update this path!
java_code = """
import py4j.GatewayServer;
public class AdditionApplication {
public int addition(int first, int second) {
return first + second;
}
public static void main(String[] args) {
AdditionApplication app = new AdditionApplication();
GatewayServer server = new GatewayServer(app, 25333);
server.start();
System.out.println("Gateway Server Started on port 25333");
}
}
"""
# Attempt to compile and run the Java code for quickstart demo
# This is a simplification and might require manual setup for complex environments.
# In a production setting, the Java server would be a separate, long-running process.
# Create temporary files for Java code and compiled class
java_file_name = "AdditionApplication.java"
class_file_name = "AdditionApplication.class"
with open(java_file_name, "w") as f:
f.write(java_code)
try:
# Compile Java code (requires javac in PATH)
compile_process = subprocess.run(
["javac", "-cp", PY4J_JAR_PATH, java_file_name],
capture_output=True, text=True
)
if compile_process.returncode != 0:
print("Java compilation failed:", compile_process.stderr)
print("Please ensure javac is in your PATH and PY4J_JAR_PATH is correct.")
# Fallback for systems without javac or if compilation fails: manual start instruction
print("Alternatively, you can manually compile and run the Java server:")
print(f"1. Save the Java code above as {java_file_name}")
print(f"2. Compile: javac -cp {PY4J_JAR_PATH} {java_file_name}")
print(f"3. Run: java -cp {PY4J_JAR_PATH}:. AdditionApplication")
# If on Windows, use ';' instead of ':' for classpath separator in commands
raise RuntimeError("Java compilation failed, cannot run quickstart.")
# Run Java Gateway Server in a separate process
# Using 'nohup' and '&' for background on *NIX, or 'start' on Windows
if os.name == 'nt': # Windows
java_server_command = ["java", "-cp", f".;{PY4J_JAR_PATH}", "AdditionApplication"]
java_process = subprocess.Popen(java_server_command, creationflags=subprocess.CREATE_NEW_PROCESS_GROUP)
else: # Unix-like
java_server_command = ["java", "-cp", f":{PY4J_JAR_PATH}", "AdditionApplication"]
java_process = subprocess.Popen(java_server_command, preexec_fn=os.setsid)
print("Starting Java Gateway Server...")
time.sleep(5) # Give Java server time to start
# --- Python Client ---
gateway = JavaGateway(gateway_parameters=GatewayParameters(port=25333))
# Access the Java entry point (AdditionApplication instance)
addition_app = gateway.entry_point
# Call a Java method
number1 = 5
number2 = 3
result = addition_app.addition(number1, number2)
print(f"Python calling Java: {number1} + {number2} = {result}")
# Access JVM directly for standard Java objects
java_list = gateway.jvm.java.util.ArrayList()
java_list.add("Hello from Python!")
print(f"Java list created and modified from Python: {java_list}")
except Exception as e:
print(f"An error occurred during quickstart: {e}")
finally:
# Clean up Java process if it was started
if 'java_process' in locals() and java_process.poll() is None:
print("Shutting down Java Gateway Server...")
if os.name == 'nt':
subprocess.run(["taskkill", "/F", "/T", "/PID", str(java_process.pid)], capture_output=True)
else:
os.killpg(os.getpgid(java_process.pid), 15) # Send SIGTERM
java_process.wait(timeout=5)
# Clean up temporary files
os.remove(java_file_name) if os.path.exists(java_file_name) else None
os.remove(class_file_name) if os.path.exists(class_file_name) else None
# Also remove AdditionApplication$*.class files if they exist
for f in os.listdir('.'):
if f.startswith('AdditionApplication$') and f.endswith('.class'):
os.remove(f)
py4j --version
Debug
Known issues
gotchaPy4J does not automatically convert pure Python `list` objects to Java `List` objects when passed as arguments to Java methods. This will result in an `InvalidGatewayException` or similar error if not handled.fixUse explicit collection conversion. Either configure Py4J for automatic conversion (see documentation on 'Collections Conversion') or manually construct Java collection types via `gateway.jvm.java.util.ArrayList()` and populate them before passing.
affects: All versions
gotchaAttempting to connect to the Java Gateway Server before it has started, or if it is not running on the expected host/port, will result in a `socket.error: [Errno 111] Connection refused`.fixEnsure your Java Gateway Server application is running and listening on the correct host and port (default is `localhost:25333`) before initializing `JavaGateway` in Python. Verify network connectivity if connecting remotely.
affects: All versions
breakingStarting with Py4J 0.10.9.9, Python's magic members (e.g., `__name__`, `__class__`) are no longer sent to the Java side, raising an `AttributeError` instead. This prevents unintended exposure and potential issues on the Java side.fixDo not rely on Python magic members being accessible from Java. If you were implicitly or explicitly relying on these, you will need to refactor your Python code or Java code to pass explicit values or methods.
affects: 0.10.9.9 and later
gotchaFor Java versions 11 and later, changes related to the Java Platform Module System (JPMS) and reflective access (e.g., `setAccessible`) might require specific JVM arguments (`--add-opens`) or adjustments to how the Py4J Java Gateway Server is launched, particularly for complex applications.fixConsult the Py4J documentation and Java documentation regarding `--add-opens` flags if you encounter `InaccessibleObjectException` or similar errors related to reflection when using Java 11+. Ensure your Py4J JAR is compatible with your Java version. The Py4J project has a strong commitment to backward compatibility, but system-level changes in Java may require configuration updates.
affects: Java 11+ (with Py4J 0.9.x to 0.10.x)
breakingPrior to Py4J 0.7, Java `byte[]` arrays passed to Python were treated as references, requiring individual calls for each byte access. Since 0.7, `byte[]` are passed by value and converted to Python `bytearray` (Python 2.x) or `bytes` (Python 3.x), and vice versa.fixIf you are upgrading from an older Py4J version (pre-0.7) and previously implemented custom handling for `byte[]` due to the reference behavior, you might need to remove or adapt that code as Py4J now handles the conversion automatically and passes by value. Test your code thoroughly after upgrading.
affects: Prior to 0.7 (behavior changed in 0.7)
gotchaThe error `[Errno 2] No such file or directory: 'javac'` indicates that the Java Development Kit (JDK) is either not installed on your system or its executable directory (`bin`) is not included in your system's PATH environment variable. `javac` is the Java compiler and is required for compiling Java source files, which may be part of Py4J's quickstart examples, internal processes, or custom Java code you are trying to use.fixInstall a suitable Java Development Kit (JDK) for your operating system. After installation, ensure that the `bin` directory of your JDK installation (e.g., `/usr/lib/jvm/java-XX-openjdk/bin` on Linux, `C:\Program Files\Java\jdk-XX\bin` on Windows) is correctly added to your system's `PATH` environment variable. You may need to restart your terminal or environment for the changes to take effect.
affects: All versions
gotchaThe `javac` command was not found, indicating that a Java Development Kit (JDK) is either not installed, not correctly configured, or not in the system's PATH. Some Py4J quickstart processes or applications may require `javac` for compilation.fixEnsure a compatible Java Development Kit (JDK) is installed on your system. Verify that the `javac` executable's directory (e.g., `JDK_HOME/bin`) is included in your system's PATH environment variable. For Docker environments, ensure the base image or subsequent steps install the JDK.
affects: All versions
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'py4j'
The 'py4j' Python package is not installed in the current Python environment or is not accessible in the `PYTHONPATH`.
fixInstall the py4j package using pip: `pip install py4j` or ensure your `PYTHONPATH` correctly includes the directory where py4j is installed, especially in PySpark environments where it might be within `SPARK_HOME/python/lib/py4j-*-src.zip`.
ImportError: No module named py4j.java_gateway
Similar to `ModuleNotFoundError`, this error typically occurs when the `py4j` library or its `java_gateway` submodule cannot be found in the `PYTHONPATH`, often specific to PySpark setups where `py4j` is bundled within Spark's installation.
fixSet the `PYTHONPATH` environment variable to include the `py4j` zip file located within your Spark installation (e.g., `export PYTHONPATH=$SPARK_HOME/python/lib/py4j-*-src.zip:$PYTHONPATH`) or explicitly install `py4j` using `pip` if not using PySpark's bundled version.
py4j.protocol.Py4JJavaError: An error occurred while calling
This generic error indicates that an exception occurred within the Java Virtual Machine (JVM) when a Python program tried to call a Java method or access a Java object, and Py4J propagated that Java exception back to Python.
fixExamine the full traceback (including the Java stack trace provided within the `Py4JJavaError` message) to identify the specific Java exception and its cause, then debug the corresponding Java code or Python logic interacting with it.
py4j.protocol.Py4JNetworkError: An error occurred while trying to connect to the Java server (127.0.0.1:XXXXX)
This error occurs when the Python client cannot establish a network connection with the Java Gateway server, often due to the Java server not running, being on a different host/port, or firewall issues. It often appears alongside `ConnectionRefusedError`.
fixEnsure the Java Gateway server is running and listening on the expected host and port (default 25333). Verify network connectivity and firewall settings. If running in containers, ensure ports are exposed and accessible between containers.
py4j.protocol.Py4JNetworkError: Answer from Java side is empty
This error signifies that the Python side sent a command to the Java gateway, but the Java side did not send back an expected response, often indicating an issue with the Java process or an unexpected termination of the Java call.
fixCheck the Java gateway server logs for any unhandled exceptions or crashes that might prevent a response. Ensure sufficient memory and resources for the Java process, especially in Spark environments, as this can sometimes relate to out-of-memory issues or task failures.
Upgrade
Version history
0.10.9.9latest on PyPI · released Jan 15, 2025
Audit
Dependencies
Java Development Kit (JDK) 7+requiredPy4J requires a running Java Virtual Machine (JVM) to connect to, for which JDK 7+ is necessary.
Python 3.8+requiredPy4J officially supports and is tested with Python versions 3.8 and newer.