CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-jpype1

A comprehensive Python-to-Java bridge enabling seamless integration between Python and Java virtual machines

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

classpath-management.mddocs/

Classpath and Import Management

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.

Capabilities

Classpath Management

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)
    """

Import Customization and Standard Imports

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
        """

Usage Examples

Basic Classpath Management

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()

Dynamic Library Loading

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()

Working with JAR Files

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()

Environment-Based Configuration

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()

Custom Import Handling

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()

Classpath Debugging

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()

Conditional Library Loading

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()

Python-Style Java Imports

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

docs

advanced-features.md

class-object-access.md

classpath-management.md

exception-handling.md

index.md

interface-implementation.md

jvm-management.md

type-system.md

tile.json