0
# Advanced Features
1
2
Specialized functionality including threading support, GUI integration, NIO buffer support, customization framework, and database API integration. This module covers JPype's advanced features for complex integration scenarios.
3
4
## Capabilities
5
6
### Synchronization
7
8
Java-style synchronization primitives for thread-safe operations.
9
10
```python { .api }
11
def synchronized(obj):
12
"""Create Java monitor lock for with statements.
13
14
Args:
15
obj: Java object to synchronize on
16
17
Returns:
18
Context manager for synchronization block
19
20
Example:
21
with synchronized(java_object):
22
# Thread-safe operations
23
java_object.modify()
24
"""
25
```
26
27
### NIO Buffer Support
28
29
Convert Python objects to Java NIO buffers for high-performance operations.
30
31
```python { .api }
32
def convertToDirectBuffer(obj):
33
"""Convert arrays/buffers to Java NIO direct buffers.
34
35
Args:
36
obj: Python array, bytes, or buffer-like object
37
38
Returns:
39
Java NIO Buffer: Direct buffer for efficient Java operations
40
41
Raises:
42
TypeError: If object cannot be converted to buffer
43
"""
44
```
45
46
### GUI Environment Support
47
48
Platform-specific GUI environment configuration (macOS/Darwin specific).
49
50
```python { .api }
51
def setupGuiEnvironment(cb):
52
"""Setup GUI environment for Java Swing/AWT applications.
53
54
Args:
55
cb: Callback function for GUI setup
56
57
Note:
58
Darwin/macOS specific functionality
59
"""
60
61
def shutdownGuiEnvironment():
62
"""Shutdown GUI environment.
63
64
Note:
65
Darwin/macOS specific functionality
66
"""
67
```
68
69
### Type Customization Framework
70
71
Advanced customization system for extending JPype's type handling.
72
73
```python { .api }
74
class JImplementationFor:
75
"""Decorator for registering class implementations for Java types.
76
77
Allows Python classes to serve as implementations for Java types.
78
"""
79
80
def __init__(self, classname: str, base: bool = False):
81
"""Create implementation decorator.
82
83
Args:
84
classname: Java class name to implement
85
base: Whether this is a base implementation
86
"""
87
88
class JConversion:
89
"""Decorator for registering type conversions.
90
91
Allows custom conversion between Python and Java types.
92
"""
93
94
def __init__(self, cls, **kwargs):
95
"""Create conversion decorator.
96
97
Args:
98
cls: Target class for conversion
99
**kwargs: Additional conversion options
100
"""
101
```
102
103
### Database API Integration
104
105
SQL database API 2.0 constants and type definitions for JDBC integration.
106
107
```python { .api }
108
# SQL Type Constants (from jpype.dbapi2)
109
ARRAY: int
110
ASCII_STREAM: int
111
BIGINT: int
112
BINARY: int
113
BINARY_STREAM: int
114
BIT: int
115
BLOB: int
116
BOOLEAN: int
117
CHAR: int
118
CHARACTER_STREAM: int
119
CLOB: int
120
DATE: int
121
DATETIME: int
122
DECIMAL: int
123
DISTINCT: int
124
DOUBLE: int
125
FLOAT: int
126
INTEGER: int
127
JAVA_OBJECT: int
128
LONGNVARCHAR: int
129
LONGVARBINARY: int
130
LONGVARCHAR: int
131
NCHAR: int
132
NCHARACTER_STREAM: int
133
NCLOB: int
134
NULL: int
135
NUMBER: int
136
NUMERIC: int
137
NVARCHAR: int
138
OBJECT: int
139
OTHER: int
140
REAL: int
141
REF: int
142
RESULTSET: int
143
ROWID: int
144
SMALLINT: int
145
SQLXML: int
146
STRING: int
147
STRUCT: int
148
TEXT: int
149
TIME: int
150
TIMESTAMP: int
151
TIMESTAMP_WITH_TIMEZONE: int
152
TIME_WITH_TIMEZONE: int
153
TINYINT: int
154
URL: int
155
VARBINARY: int
156
VARCHAR: int
157
158
# Additional Database API classes and functions
159
class Connection: ...
160
class Cursor: ...
161
def connect(*args, **kwargs): ...
162
apilevel: str # "2.0"
163
threadsafety: int # 2
164
paramstyle: str # "qmark"
165
```
166
167
## Usage Examples
168
169
### Synchronization
170
171
```python
172
import jpype
173
import threading
174
import time
175
176
jpype.startJVM()
177
178
# Create shared Java object
179
shared_list = jpype.java.util.ArrayList()
180
181
def worker_thread(thread_id):
182
"""Worker thread that modifies shared Java object safely."""
183
for i in range(5):
184
# Synchronize access to Java object
185
with jpype.synchronized(shared_list):
186
current_size = shared_list.size()
187
time.sleep(0.01) # Simulate work
188
shared_list.add(f"Thread-{thread_id}-Item-{i}")
189
print(f"Thread {thread_id}: Added item, size now {shared_list.size()}")
190
191
# Create multiple Python threads
192
threads = []
193
for i in range(3):
194
thread = threading.Thread(target=worker_thread, args=(i,))
195
threads.append(thread)
196
thread.start()
197
198
# Wait for all threads to complete
199
for thread in threads:
200
thread.join()
201
202
print(f"Final list size: {shared_list.size()}")
203
print("List contents:")
204
for i in range(shared_list.size()):
205
print(f" {i}: {shared_list.get(i)}")
206
207
jpype.shutdownJVM()
208
```
209
210
### NIO Buffer Operations
211
212
```python
213
import jpype
214
import array
215
import numpy as np
216
217
jpype.startJVM()
218
219
# Convert Python array to Java NIO buffer
220
python_array = array.array('i', [1, 2, 3, 4, 5])
221
java_buffer = jpype.convertToDirectBuffer(python_array)
222
223
print(f"Buffer type: {java_buffer.getClass().getName()}")
224
print(f"Buffer capacity: {java_buffer.capacity()}")
225
print(f"Buffer remaining: {java_buffer.remaining()}")
226
227
# Read from buffer
228
values = []
229
while java_buffer.hasRemaining():
230
values.append(java_buffer.get())
231
print(f"Buffer contents: {values}")
232
233
# Reset buffer position
234
java_buffer.rewind()
235
236
# Use with Java NIO operations
237
FileChannel = jpype.JClass("java.nio.channels.FileChannel")
238
# Example: could write buffer to file channel
239
240
# Convert NumPy array to buffer (if NumPy available)
241
try:
242
import numpy as np
243
numpy_array = np.array([10, 20, 30, 40, 50], dtype=np.int32)
244
numpy_buffer = jpype.convertToDirectBuffer(numpy_array)
245
print(f"NumPy buffer capacity: {numpy_buffer.capacity()}")
246
except ImportError:
247
print("NumPy not available for buffer conversion example")
248
249
jpype.shutdownJVM()
250
```
251
252
### Custom Type Implementation
253
254
```python
255
import jpype
256
from jpype import JImplementationFor, JConversion
257
258
jpype.startJVM()
259
260
# Custom implementation for Java Iterator
261
@JImplementationFor("java.util.Iterator")
262
class PythonListIterator:
263
"""Python implementation of Java Iterator interface."""
264
265
def __init__(self, python_list):
266
self.items = python_list
267
self.index = 0
268
269
def hasNext(self):
270
return self.index < len(self.items)
271
272
def next(self):
273
if not self.hasNext():
274
raise jpype.java.util.NoSuchElementException()
275
item = self.items[self.index]
276
self.index += 1
277
return item
278
279
# Custom conversion for Python datetime to Java Date
280
import datetime
281
282
@JConversion(jpype.java.util.Date)
283
class DateTimeConverter:
284
"""Convert Python datetime to Java Date."""
285
286
@staticmethod
287
def convert(py_datetime):
288
if isinstance(py_datetime, datetime.datetime):
289
timestamp_ms = int(py_datetime.timestamp() * 1000)
290
return jpype.java.util.Date(timestamp_ms)
291
return py_datetime
292
293
# Use custom implementations
294
python_list = ["apple", "banana", "cherry"]
295
iterator = PythonListIterator(python_list)
296
297
# Java code can use our Python iterator
298
while iterator.hasNext():
299
print(f"Next item: {iterator.next()}")
300
301
jpype.shutdownJVM()
302
```
303
304
### Database API Integration
305
306
```python
307
import jpype
308
from jpype import dbapi2
309
310
jpype.startJVM()
311
312
# Add JDBC driver to classpath (example)
313
# jpype.addClassPath("/path/to/jdbc-driver.jar")
314
315
# SQL type mapping using dbapi2 constants
316
sql_type_names = {
317
dbapi2.VARCHAR: "VARCHAR",
318
dbapi2.INTEGER: "INTEGER",
319
dbapi2.BIGINT: "BIGINT",
320
dbapi2.DECIMAL: "DECIMAL",
321
dbapi2.BOOLEAN: "BOOLEAN",
322
dbapi2.DATE: "DATE",
323
dbapi2.TIMESTAMP: "TIMESTAMP",
324
dbapi2.BLOB: "BLOB",
325
dbapi2.CLOB: "CLOB"
326
}
327
328
def map_java_sql_type(java_type_code):
329
"""Map Java SQL type code to readable name."""
330
return sql_type_names.get(java_type_code, f"UNKNOWN({java_type_code})")
331
332
# Example JDBC operations (requires JDBC driver)
333
try:
334
# Load JDBC driver (example)
335
# driver_class = jpype.JClass("com.example.jdbc.Driver")
336
# jpype.java.sql.DriverManager.registerDriver(driver_class())
337
338
# Example connection (would need real database)
339
# connection = jpype.java.sql.DriverManager.getConnection("jdbc:example://localhost")
340
# metadata = connection.getMetaData()
341
342
print("SQL type constants available:")
343
for constant_name in dir(dbapi2):
344
if constant_name.isupper() and not constant_name.startswith('_'):
345
value = getattr(dbapi2, constant_name)
346
if isinstance(value, int):
347
print(f" {constant_name}: {value}")
348
349
except Exception as e:
350
print(f"JDBC example requires database driver: {e}")
351
352
jpype.shutdownJVM()
353
```
354
355
### GUI Environment Setup (macOS)
356
357
```python
358
import jpype
359
import platform
360
361
if platform.system() == "Darwin": # macOS only
362
363
def gui_callback():
364
"""Callback for GUI environment setup."""
365
print("GUI environment initialized")
366
# Additional GUI setup code here
367
368
# Setup GUI before creating Swing components
369
jpype.startJVM()
370
jpype.setupGuiEnvironment(gui_callback)
371
372
# Now safe to create Swing/AWT components
373
JFrame = jpype.javax.swing.JFrame
374
JButton = jpype.javax.swing.JButton
375
376
frame = JFrame("Test Window")
377
button = JButton("Click Me")
378
frame.add(button)
379
frame.setSize(300, 200)
380
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
381
382
# For actual display, uncomment:
383
# frame.setVisible(True)
384
385
# Cleanup GUI environment
386
jpype.shutdownGuiEnvironment()
387
jpype.shutdownJVM()
388
389
else:
390
print("GUI environment setup is macOS-specific")
391
```
392
393
### Memory and Performance Optimization
394
395
```python
396
import jpype
397
import gc
398
import time
399
400
jpype.startJVM()
401
402
def performance_test():
403
"""Test performance optimization techniques."""
404
405
# Large object creation test
406
start_time = time.time()
407
408
# Create many Java objects
409
objects = []
410
for i in range(10000):
411
string_obj = jpype.java.lang.String(f"Object {i}")
412
objects.append(string_obj)
413
414
creation_time = time.time() - start_time
415
print(f"Created 10000 objects in {creation_time:.3f} seconds")
416
417
# Memory usage optimization
418
# Clear Python references
419
objects.clear()
420
421
# Force garbage collection
422
gc.collect()
423
424
# Java garbage collection hint
425
jpype.java.lang.System.gc()
426
427
# Check memory usage
428
runtime = jpype.java.lang.Runtime.getRuntime()
429
total_memory = runtime.totalMemory()
430
free_memory = runtime.freeMemory()
431
used_memory = total_memory - free_memory
432
433
print(f"JVM Memory - Total: {total_memory//1024//1024}MB, " +
434
f"Used: {used_memory//1024//1024}MB, " +
435
f"Free: {free_memory//1024//1024}MB")
436
437
performance_test()
438
jpype.shutdownJVM()
439
```
440
441
### Advanced Exception Handling
442
443
```python
444
import jpype
445
from jpype import JImplements, JOverride
446
447
jpype.startJVM()
448
449
# Custom exception handler
450
@JImplements("java.lang.Thread$UncaughtExceptionHandler")
451
class PythonExceptionHandler:
452
"""Python implementation of Java UncaughtExceptionHandler."""
453
454
@JOverride
455
def uncaughtException(self, thread, exception):
456
print(f"Uncaught exception in thread {thread.getName()}: {exception}")
457
# Could log to Python logging system, send alerts, etc.
458
459
# Set global exception handler
460
handler = PythonExceptionHandler()
461
jpype.java.lang.Thread.setDefaultUncaughtExceptionHandler(handler)
462
463
# Create thread that will throw exception
464
@JImplements("java.lang.Runnable")
465
class FailingTask:
466
@JOverride
467
def run(self):
468
raise jpype.java.lang.RuntimeException("This task always fails!")
469
470
# Run failing task in Java thread
471
failing_task = FailingTask()
472
thread = jpype.java.lang.Thread(failing_task, "FailingThread")
473
thread.start()
474
thread.join()
475
476
jpype.shutdownJVM()
477
```