A comprehensive Python-to-Java bridge enabling seamless integration between Python and Java virtual machines
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Manage Java classpath, configure import paths, and customize class loading behavior for Python-Java integration. This module provides comprehensive control over how Java classes are discovered and loaded within the JPype environment.
Functions for managing Java classpath during runtime.
def addClassPath(path):
"""Add paths to Java classpath.
Args:
path: String path or list of paths to add to classpath.
Can be JAR files, directories, or wildcards.
Raises:
RuntimeError: If JVM is already started (classpath must be set before JVM starts)
TypeError: If path is not string or list
Example:
addClassPath("/path/to/mylib.jar")
addClassPath(["/path/to/lib1.jar", "/path/to/lib2.jar"])
addClassPath("/path/to/libs/*")
"""
def getClassPath(env: bool = True) -> list:
"""Get full Java classpath.
Args:
env: If True, include system classpath from environment
Returns:
list: List of classpath entries
Example:
classpath = getClassPath()
print("Classpath entries:", classpath)
"""Advanced import management, customization system, and Python-style Java imports.
# From jpype.imports module - enables Python-style Java imports
import jpype.imports # Enables: from java.lang import String
def registerImportCustomizer(customizer):
"""Register a custom import handler.
Args:
customizer: Import customizer instance
"""
def registerDomain(domain: str):
"""Register an import domain.
Args:
domain: Domain name for import organization
"""
class JImportCustomizer:
"""Base class for import customizers.
Allows customization of how Java classes are imported and accessed.
"""
def canCustomize(self, name: str) -> bool:
"""Check if this customizer can handle the given name.
Args:
name: Class or package name
Returns:
bool: True if this customizer can handle the name
"""
def getClass(self, name: str):
"""Get customized class for the given name.
Args:
name: Class name to customize
Returns:
Customized class object
"""import jpype
# Add classpath before starting JVM
jpype.addClassPath("/path/to/myapp.jar")
jpype.addClassPath("/path/to/libs/database-driver.jar")
jpype.addClassPath("/path/to/config/")
# Add multiple paths at once
library_paths = [
"/opt/myapp/lib/core.jar",
"/opt/myapp/lib/utils.jar",
"/opt/myapp/plugins/"
]
jpype.addClassPath(library_paths)
# Use wildcards for all JARs in directory
jpype.addClassPath("/opt/myapp/lib/*")
# Start JVM with configured classpath
jpype.startJVM()
# Verify classpath
classpath = jpype.getClassPath()
print("Active classpath entries:")
for entry in classpath:
print(f" {entry}")
jpype.shutdownJVM()import jpype
import os
def load_application_libraries(app_home):
"""Load all application libraries from standard layout."""
lib_dir = os.path.join(app_home, "lib")
config_dir = os.path.join(app_home, "config")
plugins_dir = os.path.join(app_home, "plugins")
# Add core libraries
if os.path.exists(lib_dir):
jpype.addClassPath(f"{lib_dir}/*")
# Add configuration directory
if os.path.exists(config_dir):
jpype.addClassPath(config_dir)
# Add plugin directory
if os.path.exists(plugins_dir):
jpype.addClassPath(f"{plugins_dir}/*")
# Configure application
app_home = "/opt/myapplication"
load_application_libraries(app_home)
jpype.startJVM()
# Now can access application classes
MyApp = jpype.JClass("com.mycompany.myapp.Application")
app = MyApp()
app.initialize()
jpype.shutdownJVM()import jpype
import zipfile
import os
def add_jar_with_verification(jar_path):
"""Add JAR file to classpath with verification."""
if not os.path.exists(jar_path):
print(f"Warning: JAR file not found: {jar_path}")
return False
# Verify it's a valid ZIP/JAR file
try:
with zipfile.ZipFile(jar_path, 'r') as jar:
# Check for manifest
if 'META-INF/MANIFEST.MF' in jar.namelist():
print(f"Adding JAR: {jar_path}")
jpype.addClassPath(jar_path)
return True
else:
print(f"Warning: No manifest found in {jar_path}")
return False
except zipfile.BadZipFile:
print(f"Error: Invalid JAR file: {jar_path}")
return False
# Add JARs with verification
jar_files = [
"/path/to/app-core-1.0.jar",
"/path/to/database-connector-2.1.jar",
"/path/to/logging-framework-3.0.jar"
]
for jar_file in jar_files:
add_jar_with_verification(jar_file)
jpype.startJVM()
jpype.shutdownJVM()import jpype
import os
def configure_classpath_from_environment():
"""Configure classpath from environment variables."""
# Standard Java classpath
java_classpath = os.environ.get('CLASSPATH', '')
if java_classpath:
for path in java_classpath.split(os.pathsep):
jpype.addClassPath(path)
# Application-specific classpath
app_classpath = os.environ.get('MYAPP_CLASSPATH', '')
if app_classpath:
for path in app_classpath.split(os.pathsep):
jpype.addClassPath(path)
# Library directory from environment
lib_home = os.environ.get('MYAPP_LIB_HOME')
if lib_home and os.path.exists(lib_home):
jpype.addClassPath(f"{lib_home}/*")
# Configure from environment
configure_classpath_from_environment()
jpype.startJVM()
# Check what was loaded
current_classpath = jpype.getClassPath()
print("Loaded classpath from environment:")
for entry in current_classpath:
print(f" {entry}")
jpype.shutdownJVM()import jpype
from jpype import JImportCustomizer, registerImportCustomizer
class DatabaseDriverCustomizer(JImportCustomizer):
"""Custom import handler for database drivers."""
def canCustomize(self, name):
return name.startswith("com.database.driver")
def getClass(self, name):
# Custom logic for loading database drivers
print(f"Loading database driver: {name}")
# Could add special initialization, connection pooling, etc.
return jpype.JClass(name)
class CacheFrameworkCustomizer(JImportCustomizer):
"""Custom import handler for caching framework."""
def canCustomize(self, name):
return name.startswith("com.cache.framework")
def getClass(self, name):
print(f"Loading cache framework class: {name}")
# Could add configuration, monitoring, etc.
return jpype.JClass(name)
# Register customizers before starting JVM
registerImportCustomizer(DatabaseDriverCustomizer())
registerImportCustomizer(CacheFrameworkCustomizer())
# Add required JARs
jpype.addClassPath("/opt/database/driver.jar")
jpype.addClassPath("/opt/cache/framework.jar")
jpype.startJVM()
# Import will use customizers
DatabaseConnection = jpype.JClass("com.database.driver.Connection")
CacheManager = jpype.JClass("com.cache.framework.Manager")
jpype.shutdownJVM()import jpype
import sys
import os
def debug_classpath():
"""Debug classpath configuration and class loading."""
print("=== Classpath Debug Information ===")
# Show system classpath
system_cp = os.environ.get('CLASSPATH', 'Not set')
print(f"System CLASSPATH: {system_cp}")
# Show JPype classpath before JVM start
print("\nJPype classpath (before JVM start):")
try:
cp_before = jpype.getClassPath()
for i, entry in enumerate(cp_before):
print(f" {i}: {entry}")
except:
print(" No classpath set yet")
# Start JVM
jpype.startJVM()
# Show final classpath
print("\nFinal JVM classpath:")
cp_after = jpype.getClassPath()
for i, entry in enumerate(cp_after):
exists = "✓" if os.path.exists(entry) else "✗"
print(f" {i}: {exists} {entry}")
# Test class loading
print("\n=== Class Loading Tests ===")
test_classes = [
"java.lang.String",
"java.util.ArrayList",
"java.sql.Connection"
]
for class_name in test_classes:
try:
cls = jpype.JClass(class_name)
print(f"✓ {class_name}: {cls}")
except Exception as e:
print(f"✗ {class_name}: {e}")
jpype.shutdownJVM()
# Add some test JARs
jpype.addClassPath("/usr/share/java/*") # Common system JARs
debug_classpath()import jpype
import os
import platform
def load_platform_specific_libraries():
"""Load libraries based on platform and availability."""
system = platform.system().lower()
arch = platform.machine().lower()
# Platform-specific native libraries
native_lib_dirs = {
'windows': [
"C:/Program Files/MyApp/lib/windows",
f"C:/Program Files/MyApp/lib/windows-{arch}"
],
'linux': [
"/usr/lib/myapp",
f"/usr/lib/myapp/{arch}",
"/opt/myapp/lib"
],
'darwin': [
"/usr/local/lib/myapp",
"/opt/myapp/lib"
]
}
# Add platform-specific paths
for lib_dir in native_lib_dirs.get(system, []):
if os.path.exists(lib_dir):
jpype.addClassPath(f"{lib_dir}/*")
print(f"Added platform library: {lib_dir}")
# Feature-based loading
optional_features = {
'database': ['/opt/db-drivers/*', '/usr/share/java/jdbc/*'],
'xml': ['/opt/xml-libs/*', '/usr/share/java/xml/*'],
'crypto': ['/opt/crypto-libs/*', '/usr/share/java/security/*']
}
# Load based on environment flags
for feature, paths in optional_features.items():
env_var = f"ENABLE_{feature.upper()}"
if os.environ.get(env_var, '').lower() in ('1', 'true', 'yes'):
for path in paths:
# Extract directory from wildcard pattern
dir_path = path.rstrip('/*')
if os.path.exists(dir_path):
jpype.addClassPath(path)
print(f"Added {feature} libraries: {path}")
# Configure platform-specific loading
load_platform_specific_libraries()
jpype.startJVM()
# Verify loaded capabilities
print("Available capabilities:")
capabilities = []
# Test database
try:
jpype.JClass("java.sql.DriverManager")
capabilities.append("Database/JDBC")
except:
pass
# Test XML
try:
jpype.JClass("javax.xml.parsers.DocumentBuilderFactory")
capabilities.append("XML Processing")
except:
pass
for capability in capabilities:
print(f" ✓ {capability}")
jpype.shutdownJVM()import jpype
import jpype.imports # Enable Python-style imports
jpype.startJVM()
# Standard Python import syntax for Java classes
from java.lang import String, System, Math
from java.util import ArrayList, HashMap
from javax.swing import JFrame, JButton
# Use imported classes directly
text = String("Hello from Java")
list_obj = ArrayList()
list_obj.add("Python")
list_obj.add("Java")
# System access
System.out.println("Hello World")
result = Math.sqrt(16.0)
# Import with aliases
from java.util import ArrayList as JavaList
from java.util import HashMap as JavaMap
java_list = JavaList()
java_map = JavaMap()
# Import static methods and fields
from java.lang.Math import PI, sqrt, abs
from java.lang.System import out
print(f"PI = {PI}")
print(f"sqrt(25) = {sqrt(25.0)}")
out.println("Direct access to System.out")
jpype.shutdownJVM()Install with Tessl CLI
npx tessl i tessl/pypi-jpype1