or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-features.mdclass-object-access.mdclasspath-management.mdexception-handling.mdindex.mdinterface-implementation.mdjvm-management.mdtype-system.md

interface-implementation.mddocs/

0

# Interface Implementation and Proxying

1

2

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.

3

4

## Capabilities

5

6

### Modern Interface Implementation

7

8

Modern approach using annotations to implement Java interfaces from Python classes.

9

10

```python { .api }

11

class JImplements:

12

"""Annotation to implement Java interfaces from Python classes.

13

14

Modern approach for creating Python implementations of Java interfaces.

15

"""

16

17

def __init__(self, *interfaces, **kwargs):

18

"""Create interface implementation annotation.

19

20

Args:

21

*interfaces: Java interface classes to implement

22

**kwargs: Additional options like deferred=True

23

"""

24

25

def JOverride(func):

26

"""Decorator to mark method as overriding Java method.

27

28

Used to explicitly mark methods that override or implement

29

Java interface methods.

30

31

Args:

32

func: Python method that overrides Java method

33

34

Returns:

35

func: The decorated method

36

"""

37

```

38

39

### Legacy Proxy System

40

41

Legacy proxy system for interface implementation (deprecated in favor of JImplements).

42

43

```python { .api }

44

class JProxy:

45

"""Create proxies for Java interfaces (legacy approach).

46

47

Note: Deprecated in favor of JImplements annotation.

48

"""

49

50

def __init__(self, interface, inst=None, loader=None, dict=None):

51

"""Create a proxy for Java interface.

52

53

Args:

54

interface: Java interface class

55

inst: Python instance implementing the interface

56

loader: Class loader (optional)

57

dict: Method dictionary (optional)

58

"""

59

```

60

61

## Usage Examples

62

63

### Implementing Java Interfaces (Modern Approach)

64

65

```python

66

import jpype

67

from jpype import JImplements, JOverride

68

69

jpype.startJVM()

70

71

# Get Java interface

72

Runnable = jpype.java.lang.Runnable

73

ActionListener = jpype.javax.swing.event.ActionListener

74

75

# Implement single interface

76

@JImplements(Runnable)

77

class MyRunnable:

78

def __init__(self, name):

79

self.name = name

80

81

@JOverride

82

def run(self):

83

print(f"Running task: {self.name}")

84

85

# Create instance and use with Java

86

task = MyRunnable("background_task")

87

thread = jpype.java.lang.Thread(task)

88

thread.start()

89

thread.join()

90

91

jpype.shutdownJVM()

92

```

93

94

### Multiple Interface Implementation

95

96

```python

97

import jpype

98

from jpype import JImplements, JOverride

99

100

jpype.startJVM()

101

102

# Import required interfaces

103

Runnable = jpype.java.lang.Runnable

104

Comparable = jpype.java.lang.Comparable

105

106

# Implement multiple interfaces

107

@JImplements(Runnable, Comparable)

108

class MultiTask:

109

def __init__(self, priority, name):

110

self.priority = priority

111

self.name = name

112

113

@JOverride

114

def run(self):

115

print(f"Executing task: {self.name} (priority: {self.priority})")

116

117

@JOverride

118

def compareTo(self, other):

119

return self.priority - other.priority

120

121

# Use with Java APIs

122

task1 = MultiTask(1, "high_priority")

123

task2 = MultiTask(2, "low_priority")

124

125

# Sort using Java Collections

126

tasks = jpype.java.util.ArrayList()

127

tasks.add(task1)

128

tasks.add(task2)

129

130

jpype.java.util.Collections.sort(tasks)

131

132

jpype.shutdownJVM()

133

```

134

135

### Event Handling with GUI

136

137

```python

138

import jpype

139

from jpype import JImplements, JOverride

140

141

jpype.startJVM()

142

143

# GUI event handling

144

ActionListener = jpype.javax.swing.event.ActionListener

145

146

@JImplements(ActionListener)

147

class ButtonClickHandler:

148

def __init__(self, button_name):

149

self.button_name = button_name

150

151

@JOverride

152

def actionPerformed(self, event):

153

print(f"Button clicked: {self.button_name}")

154

source = event.getSource()

155

print(f"Event source: {source}")

156

157

# Use with Swing components

158

JFrame = jpype.javax.swing.JFrame

159

JButton = jpype.javax.swing.JButton

160

161

frame = JFrame("Test Window")

162

button = JButton("Click Me")

163

handler = ButtonClickHandler("test_button")

164

165

button.addActionListener(handler)

166

frame.add(button)

167

frame.setSize(200, 100)

168

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)

169

# frame.setVisible(True) # Uncomment for GUI display

170

171

jpype.shutdownJVM()

172

```

173

174

### Callback and Observer Patterns

175

176

```python

177

import jpype

178

from jpype import JImplements, JOverride

179

180

jpype.startJVM()

181

182

# Custom observer interface implementation

183

Observer = jpype.java.util.Observer

184

185

@JImplements(Observer)

186

class DataObserver:

187

def __init__(self, name):

188

self.name = name

189

190

@JOverride

191

def update(self, observable, arg):

192

print(f"Observer {self.name} received update: {arg}")

193

194

# Use with Observable

195

Observable = jpype.java.util.Observable

196

197

class DataModel(jpype.java.util.Observable):

198

def __init__(self):

199

super().__init__()

200

self.data = ""

201

202

def set_data(self, data):

203

self.data = data

204

self.setChanged()

205

self.notifyObservers(data)

206

207

# Set up observer pattern

208

model = DataModel()

209

observer1 = DataObserver("console_logger")

210

observer2 = DataObserver("file_logger")

211

212

model.addObserver(observer1)

213

model.addObserver(observer2)

214

215

model.set_data("New data arrived")

216

217

jpype.shutdownJVM()

218

```

219

220

### Deferred Interface Implementation

221

222

```python

223

import jpype

224

from jpype import JImplements, JOverride

225

226

jpype.startJVM()

227

228

# Deferred implementation (loaded after JVM starts)

229

@JImplements("java.lang.Runnable", deferred=True)

230

class DeferredTask:

231

def __init__(self, message):

232

self.message = message

233

234

@JOverride

235

def run(self):

236

print(f"Deferred task: {self.message}")

237

238

# Use normally

239

task = DeferredTask("delayed_initialization")

240

thread = jpype.java.lang.Thread(task)

241

thread.start()

242

thread.join()

243

244

jpype.shutdownJVM()

245

```

246

247

### Exception Handling in Interface Methods

248

249

```python

250

import jpype

251

from jpype import JImplements, JOverride

252

253

jpype.startJVM()

254

255

Callable = jpype.java.util.concurrent.Callable

256

257

@JImplements(Callable)

258

class RiskyTask:

259

def __init__(self, should_fail=False):

260

self.should_fail = should_fail

261

262

@JOverride

263

def call(self):

264

if self.should_fail:

265

# Raise Java exception from Python

266

raise jpype.java.lang.RuntimeException("Task failed!")

267

return "Task completed successfully"

268

269

# Use with ExecutorService

270

ExecutorService = jpype.java.util.concurrent.Executors.newSingleThreadExecutor()

271

272

# Successful task

273

success_task = RiskyTask(False)

274

future1 = ExecutorService.submit(success_task)

275

print(future1.get()) # "Task completed successfully"

276

277

# Failing task

278

fail_task = RiskyTask(True)

279

future2 = ExecutorService.submit(fail_task)

280

281

try:

282

result = future2.get()

283

except jpype.java.util.concurrent.ExecutionException as e:

284

print(f"Task failed with: {e.getCause()}")

285

286

ExecutorService.shutdown()

287

jpype.shutdownJVM()

288

```

289

290

### Legacy Proxy Usage (Deprecated)

291

292

```python

293

import jpype

294

295

jpype.startJVM()

296

297

# Legacy proxy approach (not recommended)

298

Runnable = jpype.java.lang.Runnable

299

300

class LegacyTask:

301

def run(self):

302

print("Legacy task running")

303

304

# Create proxy (deprecated approach)

305

task_instance = LegacyTask()

306

proxy = jpype.JProxy(Runnable, inst=task_instance)

307

308

thread = jpype.java.lang.Thread(proxy)

309

thread.start()

310

thread.join()

311

312

jpype.shutdownJVM()

313

```

314

315

### Method Name Mapping

316

317

```python

318

import jpype

319

from jpype import JImplements, JOverride

320

321

jpype.startJVM()

322

323

# Handle method name conflicts with Python keywords

324

ActionListener = jpype.javax.swing.event.ActionListener

325

326

@JImplements(ActionListener)

327

class KeywordHandler:

328

@JOverride

329

def actionPerformed(self, event):

330

# Python method name maps to Java actionPerformed

331

print("Action performed")

332

333

# Explicit method mapping for complex cases

334

Comparator = jpype.java.util.Comparator

335

336

@JImplements(Comparator)

337

class CustomComparator:

338

@JOverride

339

def compare(self, o1, o2):

340

# Compare based on string representation

341

s1 = str(o1)

342

s2 = str(o2)

343

if s1 < s2:

344

return -1

345

elif s1 > s2:

346

return 1

347

else:

348

return 0

349

350

@JOverride

351

def equals(self, other):

352

return self is other

353

354

jpype.shutdownJVM()

355

```