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

classpath-management.mddocs/

0

# Classpath and Import Management

1

2

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.

3

4

## Capabilities

5

6

### Classpath Management

7

8

Functions for managing Java classpath during runtime.

9

10

```python { .api }

11

def addClassPath(path):

12

"""Add paths to Java classpath.

13

14

Args:

15

path: String path or list of paths to add to classpath.

16

Can be JAR files, directories, or wildcards.

17

18

Raises:

19

RuntimeError: If JVM is already started (classpath must be set before JVM starts)

20

TypeError: If path is not string or list

21

22

Example:

23

addClassPath("/path/to/mylib.jar")

24

addClassPath(["/path/to/lib1.jar", "/path/to/lib2.jar"])

25

addClassPath("/path/to/libs/*")

26

"""

27

28

def getClassPath(env: bool = True) -> list:

29

"""Get full Java classpath.

30

31

Args:

32

env: If True, include system classpath from environment

33

34

Returns:

35

list: List of classpath entries

36

37

Example:

38

classpath = getClassPath()

39

print("Classpath entries:", classpath)

40

"""

41

```

42

43

### Import Customization and Standard Imports

44

45

Advanced import management, customization system, and Python-style Java imports.

46

47

```python { .api }

48

# From jpype.imports module - enables Python-style Java imports

49

import jpype.imports # Enables: from java.lang import String

50

51

def registerImportCustomizer(customizer):

52

"""Register a custom import handler.

53

54

Args:

55

customizer: Import customizer instance

56

"""

57

58

def registerDomain(domain: str):

59

"""Register an import domain.

60

61

Args:

62

domain: Domain name for import organization

63

"""

64

65

class JImportCustomizer:

66

"""Base class for import customizers.

67

68

Allows customization of how Java classes are imported and accessed.

69

"""

70

71

def canCustomize(self, name: str) -> bool:

72

"""Check if this customizer can handle the given name.

73

74

Args:

75

name: Class or package name

76

77

Returns:

78

bool: True if this customizer can handle the name

79

"""

80

81

def getClass(self, name: str):

82

"""Get customized class for the given name.

83

84

Args:

85

name: Class name to customize

86

87

Returns:

88

Customized class object

89

"""

90

```

91

92

## Usage Examples

93

94

### Basic Classpath Management

95

96

```python

97

import jpype

98

99

# Add classpath before starting JVM

100

jpype.addClassPath("/path/to/myapp.jar")

101

jpype.addClassPath("/path/to/libs/database-driver.jar")

102

jpype.addClassPath("/path/to/config/")

103

104

# Add multiple paths at once

105

library_paths = [

106

"/opt/myapp/lib/core.jar",

107

"/opt/myapp/lib/utils.jar",

108

"/opt/myapp/plugins/"

109

]

110

jpype.addClassPath(library_paths)

111

112

# Use wildcards for all JARs in directory

113

jpype.addClassPath("/opt/myapp/lib/*")

114

115

# Start JVM with configured classpath

116

jpype.startJVM()

117

118

# Verify classpath

119

classpath = jpype.getClassPath()

120

print("Active classpath entries:")

121

for entry in classpath:

122

print(f" {entry}")

123

124

jpype.shutdownJVM()

125

```

126

127

### Dynamic Library Loading

128

129

```python

130

import jpype

131

import os

132

133

def load_application_libraries(app_home):

134

"""Load all application libraries from standard layout."""

135

lib_dir = os.path.join(app_home, "lib")

136

config_dir = os.path.join(app_home, "config")

137

plugins_dir = os.path.join(app_home, "plugins")

138

139

# Add core libraries

140

if os.path.exists(lib_dir):

141

jpype.addClassPath(f"{lib_dir}/*")

142

143

# Add configuration directory

144

if os.path.exists(config_dir):

145

jpype.addClassPath(config_dir)

146

147

# Add plugin directory

148

if os.path.exists(plugins_dir):

149

jpype.addClassPath(f"{plugins_dir}/*")

150

151

# Configure application

152

app_home = "/opt/myapplication"

153

load_application_libraries(app_home)

154

155

jpype.startJVM()

156

157

# Now can access application classes

158

MyApp = jpype.JClass("com.mycompany.myapp.Application")

159

app = MyApp()

160

app.initialize()

161

162

jpype.shutdownJVM()

163

```

164

165

### Working with JAR Files

166

167

```python

168

import jpype

169

import zipfile

170

import os

171

172

def add_jar_with_verification(jar_path):

173

"""Add JAR file to classpath with verification."""

174

if not os.path.exists(jar_path):

175

print(f"Warning: JAR file not found: {jar_path}")

176

return False

177

178

# Verify it's a valid ZIP/JAR file

179

try:

180

with zipfile.ZipFile(jar_path, 'r') as jar:

181

# Check for manifest

182

if 'META-INF/MANIFEST.MF' in jar.namelist():

183

print(f"Adding JAR: {jar_path}")

184

jpype.addClassPath(jar_path)

185

return True

186

else:

187

print(f"Warning: No manifest found in {jar_path}")

188

return False

189

except zipfile.BadZipFile:

190

print(f"Error: Invalid JAR file: {jar_path}")

191

return False

192

193

# Add JARs with verification

194

jar_files = [

195

"/path/to/app-core-1.0.jar",

196

"/path/to/database-connector-2.1.jar",

197

"/path/to/logging-framework-3.0.jar"

198

]

199

200

for jar_file in jar_files:

201

add_jar_with_verification(jar_file)

202

203

jpype.startJVM()

204

jpype.shutdownJVM()

205

```

206

207

### Environment-Based Configuration

208

209

```python

210

import jpype

211

import os

212

213

def configure_classpath_from_environment():

214

"""Configure classpath from environment variables."""

215

216

# Standard Java classpath

217

java_classpath = os.environ.get('CLASSPATH', '')

218

if java_classpath:

219

for path in java_classpath.split(os.pathsep):

220

jpype.addClassPath(path)

221

222

# Application-specific classpath

223

app_classpath = os.environ.get('MYAPP_CLASSPATH', '')

224

if app_classpath:

225

for path in app_classpath.split(os.pathsep):

226

jpype.addClassPath(path)

227

228

# Library directory from environment

229

lib_home = os.environ.get('MYAPP_LIB_HOME')

230

if lib_home and os.path.exists(lib_home):

231

jpype.addClassPath(f"{lib_home}/*")

232

233

# Configure from environment

234

configure_classpath_from_environment()

235

236

jpype.startJVM()

237

238

# Check what was loaded

239

current_classpath = jpype.getClassPath()

240

print("Loaded classpath from environment:")

241

for entry in current_classpath:

242

print(f" {entry}")

243

244

jpype.shutdownJVM()

245

```

246

247

### Custom Import Handling

248

249

```python

250

import jpype

251

from jpype import JImportCustomizer, registerImportCustomizer

252

253

class DatabaseDriverCustomizer(JImportCustomizer):

254

"""Custom import handler for database drivers."""

255

256

def canCustomize(self, name):

257

return name.startswith("com.database.driver")

258

259

def getClass(self, name):

260

# Custom logic for loading database drivers

261

print(f"Loading database driver: {name}")

262

# Could add special initialization, connection pooling, etc.

263

return jpype.JClass(name)

264

265

class CacheFrameworkCustomizer(JImportCustomizer):

266

"""Custom import handler for caching framework."""

267

268

def canCustomize(self, name):

269

return name.startswith("com.cache.framework")

270

271

def getClass(self, name):

272

print(f"Loading cache framework class: {name}")

273

# Could add configuration, monitoring, etc.

274

return jpype.JClass(name)

275

276

# Register customizers before starting JVM

277

registerImportCustomizer(DatabaseDriverCustomizer())

278

registerImportCustomizer(CacheFrameworkCustomizer())

279

280

# Add required JARs

281

jpype.addClassPath("/opt/database/driver.jar")

282

jpype.addClassPath("/opt/cache/framework.jar")

283

284

jpype.startJVM()

285

286

# Import will use customizers

287

DatabaseConnection = jpype.JClass("com.database.driver.Connection")

288

CacheManager = jpype.JClass("com.cache.framework.Manager")

289

290

jpype.shutdownJVM()

291

```

292

293

### Classpath Debugging

294

295

```python

296

import jpype

297

import sys

298

import os

299

300

def debug_classpath():

301

"""Debug classpath configuration and class loading."""

302

303

print("=== Classpath Debug Information ===")

304

305

# Show system classpath

306

system_cp = os.environ.get('CLASSPATH', 'Not set')

307

print(f"System CLASSPATH: {system_cp}")

308

309

# Show JPype classpath before JVM start

310

print("\nJPype classpath (before JVM start):")

311

try:

312

cp_before = jpype.getClassPath()

313

for i, entry in enumerate(cp_before):

314

print(f" {i}: {entry}")

315

except:

316

print(" No classpath set yet")

317

318

# Start JVM

319

jpype.startJVM()

320

321

# Show final classpath

322

print("\nFinal JVM classpath:")

323

cp_after = jpype.getClassPath()

324

for i, entry in enumerate(cp_after):

325

exists = "✓" if os.path.exists(entry) else "✗"

326

print(f" {i}: {exists} {entry}")

327

328

# Test class loading

329

print("\n=== Class Loading Tests ===")

330

331

test_classes = [

332

"java.lang.String",

333

"java.util.ArrayList",

334

"java.sql.Connection"

335

]

336

337

for class_name in test_classes:

338

try:

339

cls = jpype.JClass(class_name)

340

print(f"✓ {class_name}: {cls}")

341

except Exception as e:

342

print(f"✗ {class_name}: {e}")

343

344

jpype.shutdownJVM()

345

346

# Add some test JARs

347

jpype.addClassPath("/usr/share/java/*") # Common system JARs

348

349

debug_classpath()

350

```

351

352

### Conditional Library Loading

353

354

```python

355

import jpype

356

import os

357

import platform

358

359

def load_platform_specific_libraries():

360

"""Load libraries based on platform and availability."""

361

362

system = platform.system().lower()

363

arch = platform.machine().lower()

364

365

# Platform-specific native libraries

366

native_lib_dirs = {

367

'windows': [

368

"C:/Program Files/MyApp/lib/windows",

369

f"C:/Program Files/MyApp/lib/windows-{arch}"

370

],

371

'linux': [

372

"/usr/lib/myapp",

373

f"/usr/lib/myapp/{arch}",

374

"/opt/myapp/lib"

375

],

376

'darwin': [

377

"/usr/local/lib/myapp",

378

"/opt/myapp/lib"

379

]

380

}

381

382

# Add platform-specific paths

383

for lib_dir in native_lib_dirs.get(system, []):

384

if os.path.exists(lib_dir):

385

jpype.addClassPath(f"{lib_dir}/*")

386

print(f"Added platform library: {lib_dir}")

387

388

# Feature-based loading

389

optional_features = {

390

'database': ['/opt/db-drivers/*', '/usr/share/java/jdbc/*'],

391

'xml': ['/opt/xml-libs/*', '/usr/share/java/xml/*'],

392

'crypto': ['/opt/crypto-libs/*', '/usr/share/java/security/*']

393

}

394

395

# Load based on environment flags

396

for feature, paths in optional_features.items():

397

env_var = f"ENABLE_{feature.upper()}"

398

if os.environ.get(env_var, '').lower() in ('1', 'true', 'yes'):

399

for path in paths:

400

# Extract directory from wildcard pattern

401

dir_path = path.rstrip('/*')

402

if os.path.exists(dir_path):

403

jpype.addClassPath(path)

404

print(f"Added {feature} libraries: {path}")

405

406

# Configure platform-specific loading

407

load_platform_specific_libraries()

408

409

jpype.startJVM()

410

411

# Verify loaded capabilities

412

print("Available capabilities:")

413

capabilities = []

414

415

# Test database

416

try:

417

jpype.JClass("java.sql.DriverManager")

418

capabilities.append("Database/JDBC")

419

except:

420

pass

421

422

# Test XML

423

try:

424

jpype.JClass("javax.xml.parsers.DocumentBuilderFactory")

425

capabilities.append("XML Processing")

426

except:

427

pass

428

429

for capability in capabilities:

430

print(f" ✓ {capability}")

431

432

jpype.shutdownJVM()

433

```

434

435

### Python-Style Java Imports

436

437

```python

438

import jpype

439

import jpype.imports # Enable Python-style imports

440

441

jpype.startJVM()

442

443

# Standard Python import syntax for Java classes

444

from java.lang import String, System, Math

445

from java.util import ArrayList, HashMap

446

from javax.swing import JFrame, JButton

447

448

# Use imported classes directly

449

text = String("Hello from Java")

450

list_obj = ArrayList()

451

list_obj.add("Python")

452

list_obj.add("Java")

453

454

# System access

455

System.out.println("Hello World")

456

result = Math.sqrt(16.0)

457

458

# Import with aliases

459

from java.util import ArrayList as JavaList

460

from java.util import HashMap as JavaMap

461

462

java_list = JavaList()

463

java_map = JavaMap()

464

465

# Import static methods and fields

466

from java.lang.Math import PI, sqrt, abs

467

from java.lang.System import out

468

469

print(f"PI = {PI}")

470

print(f"sqrt(25) = {sqrt(25.0)}")

471

out.println("Direct access to System.out")

472

473

jpype.shutdownJVM()

474

```