or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

annotation-support.mdindex.mdjndi-integration.mdsecurity-services.md

jndi-integration.mddocs/

0

# JNDI Resource Binding

1

2

Comprehensive JNDI naming and resource binding capabilities supporting environment entries, resources, links, and transactions with full webapp context integration and scope management.

3

4

## Capabilities

5

6

### Base JNDI Functionality

7

8

Core abstract base class for all JNDI-related entities with scope management and ENC (Environment Naming Context) binding capabilities.

9

10

```java { .api }

11

abstract class NamingEntry {

12

// Constants

13

static final String __contextName = "__";

14

15

// Protected constructor - use concrete subclasses

16

protected NamingEntry(Object scope, String jndiName, Object objectToBind) throws NamingException;

17

18

// Bind to java:comp/env namespace

19

void bindToENC(String localName) throws NamingException;

20

21

// Unbind from java:comp/env namespace

22

void unbindENC();

23

24

// Complete release and cleanup

25

void release();

26

27

// Query methods

28

String getJndiName();

29

String getJndiNameInScope();

30

String getNamingEntryNameInScope();

31

}

32

```

33

34

### JNDI Utility Operations

35

36

Comprehensive utility class providing static methods for JNDI operations, NamingEntry management, and context manipulation with scope awareness.

37

38

```java { .api }

39

class NamingEntryUtil {

40

// Link name in webapp's java:comp/env to global JNDI name

41

static boolean bindToENC(Object scope, String asName, String mappedName) throws NamingException;

42

43

// Find NamingEntry in specific scope

44

static NamingEntry lookupNamingEntry(Object scope, String jndiName) throws NamingException;

45

46

// Lookup object in scope

47

static Object lookup(Object scope, String jndiName) throws NamingException;

48

49

// Get all NamingEntries of specific type in scope

50

static <T> List<? extends T> lookupNamingEntries(Object scope, Class<T> clazz) throws NamingException;

51

52

// Name creation utilities

53

static Name makeNamingEntryName(NameParser parser, NamingEntry namingEntry) throws NamingException;

54

static Name makeNamingEntryName(NameParser parser, String jndiName) throws NamingException;

55

56

// Scope management

57

static Name getNameForScope(Object scope);

58

static Context getContextForScope(Object scope) throws NamingException;

59

static void destroyContextForScope(Object scope) throws NamingException;

60

}

61

```

62

63

**Usage Example:**

64

```java

65

// Bind a local ENC name to a global JNDI name

66

boolean bound = NamingEntryUtil.bindToENC(webappContext, "jdbc/LocalDB", "java:/comp/env/jdbc/GlobalDB");

67

68

// Lookup resources by type

69

List<? extends Resource> resources = NamingEntryUtil.lookupNamingEntries(webappContext, Resource.class);

70

71

// Get context for scope operations

72

Context scopeContext = NamingEntryUtil.getContextForScope(webappContext);

73

```

74

75

### Environment Entries

76

77

Environment entries for binding configuration values and simple objects to JNDI with web.xml override capabilities.

78

79

```java { .api }

80

class EnvEntry extends NamingEntry {

81

// Constructors with scope

82

EnvEntry(Object scope, String jndiName, Object objToBind, boolean overrideWebXml) throws NamingException;

83

84

// Global constructors

85

EnvEntry(String jndiName, Object objToBind, boolean overrideWebXml) throws NamingException;

86

EnvEntry(String jndiName, Object objToBind) throws NamingException;

87

88

// Check if this entry overrides web.xml settings

89

boolean isOverrideWebXml();

90

}

91

```

92

93

**Usage Example:**

94

```java

95

// Create environment entries with different scopes

96

EnvEntry maxConnections = new EnvEntry(webapp, "maxConnections", 100, true);

97

EnvEntry debugMode = new EnvEntry("debugMode", false);

98

99

// Environment entry automatically available in JNDI

100

InitialContext ctx = new InitialContext();

101

Integer maxConn = (Integer) ctx.lookup("java:comp/env/maxConnections");

102

Boolean debug = (Boolean) ctx.lookup("java:comp/env/debugMode");

103

```

104

105

### Resource Binding

106

107

Resource binding for complex objects like DataSources, JMS resources, and other enterprise resources with automatic JNDI registration.

108

109

```java { .api }

110

class Resource extends NamingEntry {

111

// Scoped resource binding

112

Resource(Object scope, String jndiName, Object objToBind) throws NamingException;

113

114

// Global resource binding

115

Resource(String jndiName, Object objToBind) throws NamingException;

116

}

117

```

118

119

**Usage Example:**

120

```java

121

// Bind various types of resources

122

DataSource dataSource = createDataSource();

123

Resource dsResource = new Resource(webapp, "jdbc/MyDB", dataSource);

124

125

ConnectionFactory jmsFactory = createJMSConnectionFactory();

126

Resource jmsResource = new Resource("jms/MyConnectionFactory", jmsFactory);

127

128

// Resources automatically available via JNDI lookup

129

InitialContext ctx = new InitialContext();

130

DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/MyDB");

131

ConnectionFactory cf = (ConnectionFactory) ctx.lookup("java:comp/env/jms/MyConnectionFactory");

132

```

133

134

### JNDI Links

135

136

Create links between JNDI names for aliasing and indirection, supporting complex naming hierarchies and resource sharing patterns.

137

138

```java { .api }

139

class Link extends NamingEntry {

140

// Scoped link creation

141

Link(Object scope, String jndiName, String link) throws NamingException;

142

143

// Global link creation

144

Link(String jndiName, String link) throws NamingException;

145

146

// Get target link destination

147

String getLink();

148

149

// Override - Links cannot be bound to ENC directly

150

void bindToENC(String localName) throws NamingException; // Throws UnsupportedOperationException

151

}

152

```

153

154

**Usage Example:**

155

```java

156

// Create links for resource aliasing

157

Link dbLink = new Link(webapp, "jdbc/PrimaryDB", "jdbc/ProductionDatabase");

158

Link testDbLink = new Link("jdbc/TestDB", "jdbc/DevelopmentDatabase");

159

160

// Links provide indirection

161

InitialContext ctx = new InitialContext();

162

DataSource primary = (DataSource) ctx.lookup("java:comp/env/jdbc/PrimaryDB");

163

// Actually resolves to jdbc/ProductionDatabase

164

```

165

166

### Transaction Integration

167

168

JTA UserTransaction implementation with ENC binding support for transaction management in enterprise applications.

169

170

```java { .api }

171

class Transaction extends NamingEntry {

172

// Constants

173

static final String USER_TRANSACTION = "UserTransaction";

174

175

// Protected constructor for direct use

176

protected Transaction(String scope, Object entry) throws NamingException;

177

178

// Reference-based constructor

179

Transaction(String scope, Reference userTransactionRef) throws NamingException;

180

181

// Static utility for binding UserTransaction to ENC

182

static void bindTransactionToENC(String scope) throws NamingException;

183

184

// Override to allow additional UserTransaction bindings

185

void bindToENC(String localName) throws NamingException;

186

187

// Custom unbind behavior

188

void unbindENC();

189

}

190

```

191

192

**Usage Example:**

193

```java

194

// Bind UserTransaction for webapp

195

Transaction.bindTransactionToENC(webapp.toString());

196

197

// Access transaction in application code

198

InitialContext ctx = new InitialContext();

199

UserTransaction utx = (UserTransaction) ctx.lookup("java:comp/UserTransaction");

200

201

// Use JTA transactions

202

utx.begin();

203

try {

204

// Transactional operations

205

performDatabaseOperations();

206

utx.commit();

207

} catch (Exception e) {

208

utx.rollback();

209

throw e;

210

}

211

```

212

213

### DataSource Resource Management

214

215

Proper cleanup and shutdown support for DataSource resources, especially important for connection pools and embedded databases.

216

217

```java { .api }

218

class DataSourceCloser implements Destroyable {

219

// Basic constructor

220

DataSourceCloser(DataSource datasource);

221

222

// Constructor with shutdown SQL

223

DataSourceCloser(DataSource datasource, String shutdownSQL);

224

225

// Implement Destroyable interface

226

void destroy();

227

}

228

```

229

230

**Usage Example:**

231

```java

232

// Set up DataSource with proper cleanup

233

DataSource dataSource = createAtomikosDataSource();

234

DataSourceCloser closer = new DataSourceCloser(dataSource, "SHUTDOWN");

235

236

// Register for cleanup (typically with webapp lifecycle)

237

webapp.addBean(closer);

238

239

// Automatic cleanup on webapp shutdown

240

// closer.destroy() will be called, executing shutdown SQL if provided

241

```

242

243

## Integration Patterns

244

245

### Complete JNDI Configuration

246

247

```java

248

// Set up comprehensive JNDI environment for webapp

249

WebAppContext webapp = new WebAppContext();

250

251

// Database resources

252

DataSource primaryDB = createPrimaryDataSource();

253

DataSource replicaDB = createReplicaDataSource();

254

Resource primary = new Resource(webapp, "jdbc/PrimaryDB", primaryDB);

255

Resource replica = new Resource(webapp, "jdbc/ReplicaDB", replicaDB);

256

257

// Environment configuration

258

EnvEntry maxConnections = new EnvEntry(webapp, "maxConnections", 50, true);

259

EnvEntry timeout = new EnvEntry(webapp, "timeout", 30000, false);

260

261

// Create convenient aliases

262

Link mainDB = new Link(webapp, "jdbc/MainDB", "jdbc/PrimaryDB");

263

Link backupDB = new Link(webapp, "jdbc/BackupDB", "jdbc/ReplicaDB");

264

265

// JMS resources

266

ConnectionFactory jmsFactory = createJMSConnectionFactory();

267

Resource jms = new Resource(webapp, "jms/ConnectionFactory", jmsFactory);

268

269

// Transaction support

270

Transaction.bindTransactionToENC(webapp.toString());

271

272

// Cleanup management

273

DataSourceCloser primaryCloser = new DataSourceCloser(primaryDB);

274

DataSourceCloser replicaCloser = new DataSourceCloser(replicaDB, "SHUTDOWN IMMEDIATELY");

275

webapp.addBean(primaryCloser);

276

webapp.addBean(replicaCloser);

277

```

278

279

### Dynamic Resource Discovery

280

281

```java

282

// Discover all resources bound in a webapp context

283

List<? extends Resource> resources = NamingEntryUtil.lookupNamingEntries(webapp, Resource.class);

284

List<? extends EnvEntry> envEntries = NamingEntryUtil.lookupNamingEntries(webapp, EnvEntry.class);

285

List<? extends Link> links = NamingEntryUtil.lookupNamingEntries(webapp, Link.class);

286

287

// Process each type of resource

288

for (Resource resource : resources) {

289

System.out.println("Resource: " + resource.getJndiName());

290

Object boundObject = NamingEntryUtil.lookup(webapp, resource.getJndiName());

291

System.out.println("Type: " + boundObject.getClass());

292

}

293

294

for (EnvEntry entry : envEntries) {

295

System.out.println("EnvEntry: " + entry.getJndiName() +

296

" (overrides web.xml: " + entry.isOverrideWebXml() + ")");

297

}

298

299

for (Link link : links) {

300

System.out.println("Link: " + link.getJndiName() + " -> " + link.getLink());

301

}

302

```

303

304

### Scope-based Resource Management

305

306

```java

307

// Different scoping strategies for resources

308

309

// 1. Global scope resources (available to all webapps)

310

Resource globalDB = new Resource("jdbc/GlobalDB", globalDataSource);

311

EnvEntry globalConfig = new EnvEntry("globalSetting", "production");

312

313

// 2. Webapp-scoped resources (available only to specific webapp)

314

Resource webappDB = new Resource(webapp, "jdbc/WebappDB", webappDataSource);

315

EnvEntry webappConfig = new EnvEntry(webapp, "webappSetting", "enabled", true);

316

317

// 3. Context management

318

Context globalContext = NamingEntryUtil.getContextForScope(null);

319

Context webappContext = NamingEntryUtil.getContextForScope(webapp);

320

321

// 4. Cleanup on webapp shutdown

322

webapp.addEventListener(new LifeCycle.Listener() {

323

@Override

324

public void lifeCycleStopping(LifeCycle event) {

325

try {

326

NamingEntryUtil.destroyContextForScope(webapp);

327

} catch (NamingException e) {

328

LOG.warn("Error destroying JNDI context", e);

329

}

330

}

331

});

332

```

333

334

## Error Handling and Best Practices

335

336

### Exception Handling

337

338

```java

339

try {

340

// Resource binding with error handling

341

Resource resource = new Resource(webapp, "jdbc/MyDB", dataSource);

342

343

// Verify binding worked

344

Object lookup = NamingEntryUtil.lookup(webapp, "jdbc/MyDB");

345

if (lookup == null) {

346

throw new IllegalStateException("Resource binding failed");

347

}

348

349

} catch (NamingException e) {

350

LOG.error("JNDI binding failed for jdbc/MyDB", e);

351

// Fallback strategy or re-throw

352

}

353

```

354

355

### Resource Lifecycle Management

356

357

```java

358

// Proper resource lifecycle with cleanup

359

DataSource dataSource = null;

360

Resource resource = null;

361

try {

362

dataSource = createDataSource();

363

resource = new Resource(webapp, "jdbc/MyDB", dataSource);

364

365

// Use resource...

366

367

} finally {

368

// Cleanup in reverse order

369

if (resource != null) {

370

try {

371

resource.release();

372

} catch (Exception e) {

373

LOG.warn("Error releasing JNDI resource", e);

374

}

375

}

376

377

if (dataSource instanceof Closeable) {

378

try {

379

((Closeable) dataSource).close();

380

} catch (Exception e) {

381

LOG.warn("Error closing DataSource", e);

382

}

383

}

384

}

385

```