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
Create Python implementations of Java interfaces and proxy objects for bidirectional communication between Python and Java code. This module enables Python classes to implement Java interfaces and allows Java code to call back into Python.
Modern approach using annotations to implement Java interfaces from Python classes.
class JImplements:
"""Annotation to implement Java interfaces from Python classes.
Modern approach for creating Python implementations of Java interfaces.
"""
def __init__(self, *interfaces, **kwargs):
"""Create interface implementation annotation.
Args:
*interfaces: Java interface classes to implement
**kwargs: Additional options like deferred=True
"""
def JOverride(func):
"""Decorator to mark method as overriding Java method.
Used to explicitly mark methods that override or implement
Java interface methods.
Args:
func: Python method that overrides Java method
Returns:
func: The decorated method
"""Legacy proxy system for interface implementation (deprecated in favor of JImplements).
class JProxy:
"""Create proxies for Java interfaces (legacy approach).
Note: Deprecated in favor of JImplements annotation.
"""
def __init__(self, interface, inst=None, loader=None, dict=None):
"""Create a proxy for Java interface.
Args:
interface: Java interface class
inst: Python instance implementing the interface
loader: Class loader (optional)
dict: Method dictionary (optional)
"""import jpype
from jpype import JImplements, JOverride
jpype.startJVM()
# Get Java interface
Runnable = jpype.java.lang.Runnable
ActionListener = jpype.javax.swing.event.ActionListener
# Implement single interface
@JImplements(Runnable)
class MyRunnable:
def __init__(self, name):
self.name = name
@JOverride
def run(self):
print(f"Running task: {self.name}")
# Create instance and use with Java
task = MyRunnable("background_task")
thread = jpype.java.lang.Thread(task)
thread.start()
thread.join()
jpype.shutdownJVM()import jpype
from jpype import JImplements, JOverride
jpype.startJVM()
# Import required interfaces
Runnable = jpype.java.lang.Runnable
Comparable = jpype.java.lang.Comparable
# Implement multiple interfaces
@JImplements(Runnable, Comparable)
class MultiTask:
def __init__(self, priority, name):
self.priority = priority
self.name = name
@JOverride
def run(self):
print(f"Executing task: {self.name} (priority: {self.priority})")
@JOverride
def compareTo(self, other):
return self.priority - other.priority
# Use with Java APIs
task1 = MultiTask(1, "high_priority")
task2 = MultiTask(2, "low_priority")
# Sort using Java Collections
tasks = jpype.java.util.ArrayList()
tasks.add(task1)
tasks.add(task2)
jpype.java.util.Collections.sort(tasks)
jpype.shutdownJVM()import jpype
from jpype import JImplements, JOverride
jpype.startJVM()
# GUI event handling
ActionListener = jpype.javax.swing.event.ActionListener
@JImplements(ActionListener)
class ButtonClickHandler:
def __init__(self, button_name):
self.button_name = button_name
@JOverride
def actionPerformed(self, event):
print(f"Button clicked: {self.button_name}")
source = event.getSource()
print(f"Event source: {source}")
# Use with Swing components
JFrame = jpype.javax.swing.JFrame
JButton = jpype.javax.swing.JButton
frame = JFrame("Test Window")
button = JButton("Click Me")
handler = ButtonClickHandler("test_button")
button.addActionListener(handler)
frame.add(button)
frame.setSize(200, 100)
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
# frame.setVisible(True) # Uncomment for GUI display
jpype.shutdownJVM()import jpype
from jpype import JImplements, JOverride
jpype.startJVM()
# Custom observer interface implementation
Observer = jpype.java.util.Observer
@JImplements(Observer)
class DataObserver:
def __init__(self, name):
self.name = name
@JOverride
def update(self, observable, arg):
print(f"Observer {self.name} received update: {arg}")
# Use with Observable
Observable = jpype.java.util.Observable
class DataModel(jpype.java.util.Observable):
def __init__(self):
super().__init__()
self.data = ""
def set_data(self, data):
self.data = data
self.setChanged()
self.notifyObservers(data)
# Set up observer pattern
model = DataModel()
observer1 = DataObserver("console_logger")
observer2 = DataObserver("file_logger")
model.addObserver(observer1)
model.addObserver(observer2)
model.set_data("New data arrived")
jpype.shutdownJVM()import jpype
from jpype import JImplements, JOverride
jpype.startJVM()
# Deferred implementation (loaded after JVM starts)
@JImplements("java.lang.Runnable", deferred=True)
class DeferredTask:
def __init__(self, message):
self.message = message
@JOverride
def run(self):
print(f"Deferred task: {self.message}")
# Use normally
task = DeferredTask("delayed_initialization")
thread = jpype.java.lang.Thread(task)
thread.start()
thread.join()
jpype.shutdownJVM()import jpype
from jpype import JImplements, JOverride
jpype.startJVM()
Callable = jpype.java.util.concurrent.Callable
@JImplements(Callable)
class RiskyTask:
def __init__(self, should_fail=False):
self.should_fail = should_fail
@JOverride
def call(self):
if self.should_fail:
# Raise Java exception from Python
raise jpype.java.lang.RuntimeException("Task failed!")
return "Task completed successfully"
# Use with ExecutorService
ExecutorService = jpype.java.util.concurrent.Executors.newSingleThreadExecutor()
# Successful task
success_task = RiskyTask(False)
future1 = ExecutorService.submit(success_task)
print(future1.get()) # "Task completed successfully"
# Failing task
fail_task = RiskyTask(True)
future2 = ExecutorService.submit(fail_task)
try:
result = future2.get()
except jpype.java.util.concurrent.ExecutionException as e:
print(f"Task failed with: {e.getCause()}")
ExecutorService.shutdown()
jpype.shutdownJVM()import jpype
jpype.startJVM()
# Legacy proxy approach (not recommended)
Runnable = jpype.java.lang.Runnable
class LegacyTask:
def run(self):
print("Legacy task running")
# Create proxy (deprecated approach)
task_instance = LegacyTask()
proxy = jpype.JProxy(Runnable, inst=task_instance)
thread = jpype.java.lang.Thread(proxy)
thread.start()
thread.join()
jpype.shutdownJVM()import jpype
from jpype import JImplements, JOverride
jpype.startJVM()
# Handle method name conflicts with Python keywords
ActionListener = jpype.javax.swing.event.ActionListener
@JImplements(ActionListener)
class KeywordHandler:
@JOverride
def actionPerformed(self, event):
# Python method name maps to Java actionPerformed
print("Action performed")
# Explicit method mapping for complex cases
Comparator = jpype.java.util.Comparator
@JImplements(Comparator)
class CustomComparator:
@JOverride
def compare(self, o1, o2):
# Compare based on string representation
s1 = str(o1)
s2 = str(o2)
if s1 < s2:
return -1
elif s1 > s2:
return 1
else:
return 0
@JOverride
def equals(self, other):
return self is other
jpype.shutdownJVM()Install with Tessl CLI
npx tessl i tessl/pypi-jpype1