PemJa
PemJa is a Python-Java bridge that enables embedding a JVM within a Python process, allowing dynamic interaction with Java objects and classes. It simplifies calling Java methods from Python and provides mechanisms for classpath management. The current version is 0.6.1, with releases occurring as features are added or bugs are fixed, but without a strict regular cadence.
Common errors
-
pemja.JavaException: java.lang.NoClassDefFoundError: Your/Custom/Class
cause The specified Java class or one of its dependencies could not be found by the JVM. This usually means the JAR containing the class was not added to the JVM's classpath.fixEnsure that the JAR file containing 'Your/Custom/Class' (and any of its dependencies) is correctly specified in the `classpath` argument when calling `pemja.launch_jvm()`. Use `pemja.find_jar()` to help locate JARs if they are in standard locations. -
FileNotFoundError: Cannot find JDK home directory. Please ensure JAVA_HOME is set or java is in PATH.
cause PemJa could not locate a Java Development Kit (JDK) installation on your system, which is required to launch the JVM.fixInstall JDK 8 or higher on your system. Then, either add the JDK's `bin` directory to your system's PATH environment variable, or set the `JAVA_HOME` environment variable to point to your JDK installation directory (e.g., `/Library/Java/JavaVirtualMachines/jdk-17.jdk/Contents/Home` on macOS). -
pemja.PemjaException: JVM already launched. Can't launch it again.
cause You are attempting to call `pemja.launch_jvm()` more than once within the same Python process.fixEnsure `pemja.launch_jvm()` is called only once. Store the returned `jvm` object and reuse it throughout your application. If you need to reconfigure the JVM, you must restart your Python process.
Warnings
- breaking The parameters for `pemja.launch_jvm()` changed significantly in version 0.6.0. The `config` dictionary was replaced with more explicit parameters like `options` and `classpath`.
- gotcha PemJa requires a Java Development Kit (JDK) version 8 or higher to be installed on the system where Python is running. Without a properly configured JDK, PemJa cannot launch the JVM.
- gotcha The JVM should generally be launched only once per Python process using `pemja.launch_jvm()`. Attempting to launch it multiple times can lead to errors or undefined behavior.
- gotcha When working with custom Java JARs, ensuring they are correctly added to the JVM's classpath is critical. Incorrect classpath configuration leads to `NoClassDefFoundError` or similar issues.
Install
-
pip install pemja
Imports
- launch_jvm
from pemja import launch_jvm
- find_jar
from pemja import find_jar
- JavaObject
from pemja import JavaObject
Quickstart
import pemja
# Ensure JDK 8+ is installed and accessible in your system's PATH or JAVA_HOME.
# In a production environment, consider explicit JVM options or classpath management.
try:
print("Launching JVM...")
# Using a context manager ensures the JVM is shut down cleanly
with pemja.launch_jvm() as jvm:
print("JVM launched successfully.")
# 1. Access a static method from a core Java class
System = jvm.find_class("java.lang.System")
java_version = System.getProperty("java.version")
print(f"Java version reported by JVM: {java_version}")
# 2. Create an instance of a Java class and call a method
String = jvm.find_class("java.lang.String")
greeting = jvm.create_instance(String, "Hello from PemJa in Python!")
print(f"Original Java string: {greeting}")
print(f"Uppercase Java string: {greeting.toUpperCase()}")
# 3. Handle exceptions from Java
# This is a simple example; real error handling would be more robust
try:
Integer = jvm.find_class("java.lang.Integer")
Integer.parseInt("not_a_number") # This will throw a Java NumberFormatException
except jvm.JavaException as e:
print(f"Caught Java Exception: {e.get_stack_trace()}")
except pemja.PemjaException as e:
print(f"PemJa specific error: {e}")
print("Please ensure JDK 8+ is correctly installed and configured.")
except Exception as e:
print(f"An unexpected error occurred: {e}")