Skip to main content

[Japanese/日本語]

JVM-PyBind

JVM bindings for Python that enable seamless integration between Python and Java code through JNI (Java Native Interface).

Features

  • Direct JNI Integration: Low-level JNI bindings using ctypes for maximum performance
  • Dynamic Class Discovery: Automatic discovery of Java classes, methods, and fields using reflection
  • Python Import Hook: Use standard Python import syntax to access Java classes
  • Type Conversion: Automatic conversion between Python and Java types
  • Memory Safety: Proper JNI reference management and safe shutdown procedures
  • Cross-Platform: Support for Windows, macOS (including ARM64), and Linux
  • Configuration: Flexible configuration through pyproject.toml

Quick Start

Installation

pip install jvm-pybind

Basic Usage

# Import Java classes using standard Python syntax
from java.lang import System

# Call Java methods directly
System.out.println("Hello from JVM!")

# Access Java properties
print(f"Java Version: {System.getProperty('java.version')}")
print(f"Java Vendor: {System.getProperty('java.vendor')}")

Command Line Interface

jvm-pybind provides a CLI for managing Java type stubs in your development environment.

Installation

Install type stubs to enable IDE support and autocompletion:

# Install the default java.lang, java.util, and java.io packages
python -m jvm --install-stub

# Generate and install one selected package
python -m jvm --install-stub="java.lang"

# Select JDK and custom-JAR packages with a comma-separated list
python -m jvm --install-stub="java.io,mypkg"

Uninstallation

Remove type stubs when no longer needed:

# Remove Java type stubs from current virtual environment
python -m jvm --uninstall-stub

PTH File Installation

Install a .pth file to enable automatic JVM import in your virtual environment:

# Install jvm.pth file for automatic import
python -m jvm --install-pth

This creates a jvm.pth file in your virtual environment's site-packages directory that automatically imports the JVM module when Python starts, enabling seamless Java class imports without manual initialization.

Features

Type Stub Management:

  • Install stubs: Generates and installs type stubs for comma-separated Java package names
  • Uninstall stubs: Cleanly removes all installed Java type stubs
  • Auto-generation: Generates fresh stubs from your JVM installation if needed
  • Virtual environment detection: Works with venv, virtualenv, conda, and other Python environment managers

PTH File Management:

  • Install PTH file: Creates a jvm.pth file in your virtual environment that automatically imports the JVM module at Python startup
  • Automatic import: Enables seamless Java class imports without manual JVM initialization
  • Virtual environment safety: Only works within active virtual environments for isolated setup

Default Packages:

  • java.lang - Core Java classes (String, System, Object, etc.)
  • java.util - Collections and utilities (List, Map, ArrayList, etc.)
  • java.io - Input/output classes (File, InputStream, OutputStream, etc.)

Packages from JARs or class directories in [tool.jvm].classpath can also be selected, for example with --install-stub="mypkg".

Requirements

  • Virtual Environment: CLI operations require an active virtual environment
  • JVM Installation: Java must be installed and accessible for stub generation

Examples

# Create and activate virtual environment
python -m venv .venv
source .venv/bin/activate  # On Windows: .venv\Scripts\activate

# Install jvm-pybind
pip install jvm-pybind

# Install JDK and custom-JAR type stubs for IDE support
python -m jvm --install-stub="java.lang,mypkg"

# OR install PTH file for automatic JVM import
python -m jvm --install-pth

# Now you get autocompletion in your IDE
from java.lang import System  # IDE will show available methods

Help

python -m jvm --help

Output:

usage: jvm [-h] (--install-stub [PACKAGES] | --uninstall-stub | --install-pth)

JVM-PyBind: Python bindings for JVM with type stub management

options:
  -h, --help         show this help message and exit
  --install-stub [PACKAGES]
                     Install comma-separated Java package stubs; defaults to
                     java.lang,java.util,java.io
  --uninstall-stub   Remove JDK type stubs from the current virtual environment
  --install-pth      Install jvm.pth file to enable automatic JVM import in
                     virtual environment

Examples:
  python -m jvm --install-stub="java.lang"       Install one package stub
  python -m jvm --install-stub="java.io,mypkg"  Install multiple package stubs
  python -m jvm --uninstall-stub   Remove JDK type stubs from virtual environment
  python -m jvm --install-pth      Install jvm.pth file to enable automatic JVM import

Working with Custom Java Classes

# pyproject.toml
[tool.jvm]
java-version = "21"
classpath = ["./hello.jar"]

Relative classpath entries are resolved from the directory containing the declaring pyproject.toml. Packages and classes in configured JARs are discovered automatically and can be accessed with normal Python imports.

import jvm  # Install the Java import hook
from mypkg import Hello

print(Hello.greet("World"))

Generate its IDE stub from a directory where the same configuration is discoverable:

python -m jvm --install-stub="mypkg"

Method, field, and constructor signatures are obtained from Java Reflection and JNI after class loading. Overloads, primitive values, object values, and arrays are dispatched according to those reflected signatures.

Configuration

Configure jvm-pybind through your pyproject.toml file:

[tool.jvm]
java-version = "17"  # Java version to use
classpath = [        # JAR files and directories to include
    "path/to/your.jar",
    "path/to/classes/"
]

[tool.jvm.deps]
maven = [            # Maven dependencies (future feature)
    "org.apache.commons:commons-lang3:3.12.0"
]

System Requirements

Java Runtime

  • Java 17 (recommended, configurable)
  • Supported JDK distributions:
    • Oracle JDK
    • Eclipse Adoptium (formerly AdoptOpenJDK)
    • Amazon Corretto
    • Microsoft Build of OpenJDK
    • Azul Zulu
    • OpenJDK

Python

  • Python 3.12+
  • Supported platforms:
    • Windows (x64)
    • macOS (Intel and Apple Silicon)
    • Linux (x64, ARM64)

Architecture

jvm-pybind consists of several key components:

  • JVMLoader: Initializes the JVM and loads the libjvm library
  • JNIHelper: Low-level JNI function bindings with type safety
  • JVM: Main interface for Java class discovery and method execution
  • Proxy Classes: Python wrappers for Java packages, classes, and objects
  • Import Hook: Integration with Python's import system

Advanced Usage

Direct JNI Access

import jvm

# Get the JVM instance
jvm_instance = jvm.get_jvm()

# Find a Java class
string_class = jvm_instance.find_class("java.lang.String")

# Access class information
print(f"Methods: {len(string_class.methods)}")
print(f"Fields: {len(string_class.fields)}")

Memory Management

The library automatically manages JNI references, but you can also control memory explicitly:

from java.lang import System

# The JVM will be automatically shut down when Python exits
# For explicit control:
jvm.shutdown()

Internal API Reference

📋 Note: This section documents the internal API for advanced users and developers. For most use cases, the high-level import syntax (from java.lang import System) is recommended.

JVM Instance Management

import jvm

# Get the current JVM instance (if running)
jvm_instance = jvm.get_jvm()  # Returns None if JVM not started

# Start JVM with custom configuration
from jvm.config import Config
from jvm.loader import JVMLoader

config = Config(java_version="17", classpath=["path/to/jar"], deps={})
jvm_instance = JVMLoader(config).start()

Low-Level Class Access

# Find a Java class by name
java_class = jvm_instance.find_class("java/lang/String")
print(f"Class: {java_class.name}")
print(f"Methods: {len(java_class.methods)}")
print(f"Fields: {len(java_class.fields)}")

# Access class methods and fields
for method in java_class.methods:
    print(f"Method: {method.name}({', '.join(method.parameters)}) -> {method.return_type}")
    print(f"Static: {method.is_static}")

Direct JNI Operations

# Access the underlying JNI helper
jni = jvm_instance.jni

# Find class and get method ID
string_class = jni.FindClass("java/lang/String")
length_method = jni.GetMethodID(string_class, "length", "()I")

# Create a Java string
java_str = jni.NewStringUTF("Hello World")

# Call method
length = jni.CallIntMethod(java_str, length_method)
print(f"String length: {length}")

Package Discovery

# Discover classes in a package
classes = jvm_instance.discover_package_classes("java.util")
for class_name in classes:
    print(f"Found class: {class_name}")

Proxy Objects

from jvm.proxy import ClassProxy, PackageProxy

# Create proxy for a Java package
java_lang = PackageProxy(jvm_instance, "java.lang")
system_class = java_lang.System  # Returns ClassProxy

# Access static methods
system_class.gc()  # Calls System.gc()
property_value = system_class.getProperty("java.version")

Configuration Access

from jvm.config import Config

# Load configuration from pyproject.toml
config = Config.from_pyproject()
print(f"Java Version: {config.java_version}")
print(f"Classpath: {config.classpath}")
print(f"Dependencies: {config.deps}")

# Create custom configuration
custom_config = Config(
    java_version="11",
    classpath=["/path/to/custom.jar"],
    deps={"maven": ["org.apache.commons:commons-lang3:3.12.0"]}
)

Type Conversion

from jvm.typeconv import to_java, to_python

# Convert Python values to Java
java_string = to_java(jvm_instance, "Hello")
java_int = to_java(jvm_instance, 42)
java_bool = to_java(jvm_instance, True)

# Convert Java values to Python
python_value = to_python(jvm_instance, java_string)

Exception Handling

from jvm.jvm import JNIException

try:
    # JNI operations that might fail
    unknown_class = jvm_instance.find_class("com/nonexistent/Class")
except JNIException as e:
    print(f"JNI error: {e}")

Available Classes and Methods

The main classes you can import and use:

Class Purpose Example Usage
jvm.JVM Main JVM interface jvm_instance.find_class()
jvm.JNIHelper Low-level JNI functions jni.FindClass()
jvm.Config Configuration management Config.from_pyproject()
jvm.JVMLoader JVM initialization JVMLoader(config).start()
jvm.proxy.* Java object proxies ClassProxy(), ObjectProxy()

Development

Setting up Development Environment

# Clone the repository
git clone https://github.com/t3tra-dev/jvm-pybind.git
cd jvm-pybind

# Initialize environment
./reinstall.sh  # Or manually create a virtual environment

Running Tests

# Run the example
cd examples/hello
python main.py

Project Structure

jvm-pybind/
├── src/jvm/           # Main package
│   ├── __init__.py    # Package initialization
│   ├── jvm.py         # JVM interface
│   ├── jni.py         # JNI bindings
│   ├── loader.py      # JVM loader
│   ├── proxy.py       # Java object proxies
│   ├── config.py      # Configuration management
│   ├── typeconv.py    # Type conversion utilities
│   └── import_hook/   # Python import hook
├── examples/          # Usage examples
└── tests/             # Test suite

Supported Java Types

Primitive Types

  • boolean ↔ bool
  • int ↔ int
  • long ↔ int
  • float ↔ float
  • double ↔ float
  • String ↔ str

Complex Types

  • Java objects are wrapped in proxy classes
  • Arrays and collections (planned)
  • Custom classes through reflection

Performance Considerations

  • JVM Startup: The JVM is initialized lazily on first Java import
  • Memory Usage: JNI references are managed automatically
  • Method Calls: Direct JNI calls for optimal performance
  • ARM64 Optimization: Special optimizations for Apple Silicon

Troubleshooting

Common Issues

  1. Java not found: Ensure Java is installed and JAVA_HOME is set
  2. ClassNotFoundException: Check your classpath configuration
  3. Memory errors: Verify adequate heap space for your application

Debug Mode

Enable debug logging:

import logging
logging.basicConfig(level=logging.DEBUG)

from java.lang import System  # Will show debug output

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

  • Built with Python's ctypes for JNI integration
  • Inspired by JPype and similar Java-Python bridge projects
  • Special thanks to the Python and Java communities

Roadmap

High Priority

  • Custom Java class import support - Enable from mypkg import MyClass syntax for custom classes
  • Enhanced type conversion - Support for more Java types (arrays, collections, etc.)
  • Comprehensive test suite - Full test coverage for all features

Medium Priority

  • Maven dependency resolution - Automatic downloading and management of Maven dependencies
  • Java collection support - Native Python integration with Java Lists, Maps, etc.
  • Performance optimizations - Method call optimization and caching

Low Priority

  • Callback support - Enable Java code to call Python functions
  • Advanced debugging tools - Better error messages and debugging capabilities
  • IDE integration - Type hints and autocompletion for Java classes

Metadata

Release files for jvm-pybind 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for jvm-pybind 0.1.2
File Size Uploaded Provenance Actions
jvm_pybind-0.1.2.tar.gz 72.0 kB With provenance Details for jvm_pybind-0.1.2.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for jvm-pybind 0.1.2
File Interpreter ABI Platform Actions
jvm_pybind-0.1.2-py3-none-any.whl Python 3 none any Details for jvm_pybind-0.1.2-py3-none-any.whl

Total release size: 121.9 kB

Release files / jvm_pybind-0.1.2.tar.gz

Download URL jvm_pybind-0.1.2.tar.gz
Size 72.0 kB
Tags Source
SHA-256 checksum
How to use checksums
2ba8685e15a41fca139974d91b10aee2b2a2ff4242df1d45c5b36c3f12f76d65
BLAKE2b-256 checksum
How to use checksums
1e50d5b11946d9d442d24bc9e70b0f09c7587b1bcdefb00c4d6b2521ce7c4791
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 14, 2026.

Transparency log

Release files / jvm_pybind-0.1.2-py3-none-any.whl

Download URL jvm_pybind-0.1.2-py3-none-any.whl
Size 49.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a4c821013fb5e461d6b0575453cc460dca982575e7c530ad5ff091e7583d11ce
BLAKE2b-256 checksum
How to use checksums
655dfb2734990201dcb53cec8bf0b318af487e9a2f9b5ab21e6fb7a15562d712
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 14, 2026.

Transparency log

Security for jvm-pybind 0.1.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for jvm_pybind-0.1.2.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 14, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page