or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

class-visibility.mdclassloader.mdconfiguration.mddescriptors.mdindex.mdmetadata.mdwebapp-context.md

class-visibility.mddocs/

0

# Class Visibility Controls

1

2

Jetty WebApp provides fine-grained control over class visibility and loading delegation through pattern-based class matchers. This system allows precise control over which classes are loaded by the system classloader, server classloader, or webapp classloader.

3

4

## Capabilities

5

6

### ClassMatcher

7

8

Pattern-based matcher for controlling class visibility and loading delegation.

9

10

```java { .api }

11

/**

12

* Pattern matcher for classes based on package, location, and module patterns.

13

* Supports inclusion and exclusion patterns with precedence rules.

14

*/

15

public class ClassMatcher extends AbstractSet<String> {

16

17

/**

18

* Create empty class matcher

19

*/

20

public ClassMatcher();

21

22

/**

23

* Copy constructor

24

*/

25

public ClassMatcher(ClassMatcher patterns);

26

27

/**

28

* Create with initial patterns

29

*/

30

public ClassMatcher(String... patterns);

31

32

/**

33

* Create with single pattern

34

*/

35

public ClassMatcher(String pattern);

36

}

37

```

38

39

### Pattern Management

40

41

Methods for adding and managing class patterns.

42

43

```java { .api }

44

/**

45

* Include class patterns (positive match)

46

*/

47

public boolean include(String name);

48

public boolean include(String... name);

49

50

/**

51

* Exclude class patterns (negative match)

52

*/

53

public boolean exclude(String name);

54

public boolean exclude(String... name);

55

56

/**

57

* Add patterns (defaults to inclusion)

58

*/

59

public boolean add(String pattern);

60

public boolean add(String... pattern);

61

62

/**

63

* Get all patterns

64

*/

65

public String[] getPatterns();

66

67

/**

68

* Get inclusion patterns only

69

*/

70

public String[] getInclusions();

71

72

/**

73

* Get exclusion patterns only

74

*/

75

public String[] getExclusions();

76

```

77

78

**Usage Examples:**

79

80

```java

81

ClassMatcher matcher = new ClassMatcher();

82

83

// Include patterns

84

matcher.include("com.mycompany.");

85

matcher.include("org.apache.commons.");

86

87

// Exclude patterns

88

matcher.exclude("com.mycompany.internal.");

89

matcher.exclude("org.apache.commons.logging.");

90

91

// Add multiple patterns

92

matcher.add("javax.servlet.", "jakarta.servlet.");

93

```

94

95

### Pattern Matching

96

97

Methods for testing class names against patterns.

98

99

```java { .api }

100

/**

101

* Test if class name matches patterns

102

*/

103

public boolean match(String name);

104

105

/**

106

* Test if class matches patterns

107

*/

108

public boolean match(Class<?> clazz);

109

110

/**

111

* Test if class name and URL match patterns

112

*/

113

public boolean match(String name, URL url);

114

```

115

116

**Usage Examples:**

117

118

```java

119

// Test class names

120

if (matcher.match("com.mycompany.MyClass")) {

121

// Class matches inclusion patterns

122

}

123

124

// Test class objects

125

if (matcher.match(String.class)) {

126

// java.lang.String matches patterns

127

}

128

129

// Test with URL context

130

URL jarUrl = new URL("file:/path/to/lib.jar");

131

if (matcher.match("com.example.Service", jarUrl)) {

132

// Class from specific JAR matches

133

}

134

```

135

136

### Pattern Entry Details

137

138

Information about individual pattern entries and specialized implementations.

139

140

```java { .api }

141

/**

142

* Represents a single pattern entry with inclusion/exclusion flag

143

*/

144

public static class Entry {

145

146

/**

147

* Get the pattern string

148

*/

149

public String getPattern();

150

151

/**

152

* Get the pattern name (same as pattern)

153

*/

154

public String getName();

155

156

/**

157

* Check if this is an inclusive pattern

158

*/

159

public boolean isInclusive();

160

161

/**

162

* Test if this entry matches a class name

163

*/

164

public boolean match(String name);

165

166

/**

167

* Test if this entry matches a class and URL

168

*/

169

public boolean match(String name, URL url);

170

}

171

172

/**

173

* Entry for package-based patterns

174

*/

175

public static class PackageEntry extends Entry {

176

public PackageEntry(String pattern, boolean inclusive);

177

}

178

179

/**

180

* Entry for exact class name patterns

181

*/

182

public static class ClassEntry extends Entry {

183

public ClassEntry(String pattern, boolean inclusive);

184

}

185

186

/**

187

* Entry for location-based patterns (JAR files, directories)

188

*/

189

public static class LocationEntry extends Entry {

190

public LocationEntry(String pattern, boolean inclusive);

191

}

192

193

/**

194

* Entry for module-based patterns (Java 9+ modules)

195

*/

196

public static class ModuleEntry extends Entry {

197

public ModuleEntry(String pattern, boolean inclusive);

198

}

199

```

200

201

## Pattern Syntax

202

203

### Basic Patterns

204

205

```java

206

// Package prefix matching

207

"com.mycompany." // Matches com.mycompany.* packages

208

"org.eclipse.jetty." // Matches org.eclipse.jetty.* packages

209

210

// Exact class matching

211

"com.mycompany.MyClass" // Matches exact class only

212

213

// Wildcard matching

214

"com.mycompany.*" // Same as "com.mycompany."

215

"*.internal.*" // Matches any package containing "internal"

216

```

217

218

### Advanced Patterns

219

220

```java

221

// Exclusion patterns (prefix with '-')

222

"-com.mycompany.internal." // Exclude internal packages

223

"-org.eclipse.jetty.util.log." // Exclude logging utilities

224

225

// Location-based patterns

226

"file:/path/to/specific.jar" // Match classes from specific JAR

227

"file:/lib/" // Match classes from lib directory

228

229

// Module-based patterns (Java 9+)

230

"java.base/" // Match classes from java.base module

231

"java.logging/" // Match classes from java.logging module

232

```

233

234

### Pattern Precedence

235

236

```java

237

ClassMatcher matcher = new ClassMatcher();

238

239

// More specific patterns take precedence

240

matcher.include("com.mycompany."); // Include mycompany packages

241

matcher.exclude("com.mycompany.internal."); // But exclude internal

242

matcher.include("com.mycompany.internal.api."); // Except API classes

243

244

// Test precedence

245

matcher.match("com.mycompany.Service"); // true (included)

246

matcher.match("com.mycompany.internal.Util"); // false (excluded)

247

matcher.match("com.mycompany.internal.api.Service"); // true (re-included)

248

```

249

250

## Integration with WebApp Components

251

252

### WebAppContext Integration

253

254

WebAppContext uses ClassMatcher for system and server class controls.

255

256

```java { .api }

257

// WebAppContext methods using ClassMatcher

258

public ClassMatcher getSystemClassMatcher();

259

public void setSystemClassMatcher(ClassMatcher systemClasses);

260

public void addSystemClassMatcher(ClassMatcher systemClasses);

261

262

public ClassMatcher getServerClassMatcher();

263

public void setServerClassMatcher(ClassMatcher serverClasses);

264

public void addServerClassMatcher(ClassMatcher serverClasses);

265

```

266

267

**Usage Examples:**

268

269

```java

270

WebAppContext webapp = new WebAppContext();

271

272

// Set system classes (loaded by system classloader)

273

ClassMatcher systemClasses = new ClassMatcher();

274

systemClasses.include("java.", "javax.", "jakarta.");

275

systemClasses.include("org.xml.", "org.w3c.");

276

webapp.setSystemClassMatcher(systemClasses);

277

278

// Set server classes (hidden from webapp)

279

ClassMatcher serverClasses = new ClassMatcher();

280

serverClasses.include("org.eclipse.jetty.");

281

serverClasses.exclude("org.eclipse.jetty.servlet.listener.");

282

webapp.setServerClassMatcher(serverClasses);

283

```

284

285

### Configuration Integration

286

287

Configurations can contribute class visibility patterns.

288

289

```java { .api }

290

// Configuration interface methods

291

default ClassMatcher getSystemClasses() { return null; }

292

default ClassMatcher getServerClasses() { return null; }

293

294

// AbstractConfiguration protected methods

295

protected void protect(String... classes); // Add to system classes

296

protected void hide(String... classes); // Add to server classes

297

protected void expose(String... classes); // Remove from server classes

298

protected void protectAndExpose(String... classes); // Add to system, remove from server

299

```

300

301

**Usage Examples:**

302

303

```java

304

public class MyConfiguration extends AbstractConfiguration {

305

public MyConfiguration() {

306

// Protect shared libraries

307

protect("com.mycompany.shared.");

308

309

// Hide internal server classes

310

hide("com.mycompany.server.internal.");

311

312

// Expose specific server utilities to webapps

313

expose("com.mycompany.server.util.StringUtils");

314

}

315

}

316

```

317

318

## Default Class Patterns

319

320

### Default System Classes

321

322

Classes loaded by the system classloader (not isolated per webapp).

323

324

```java

325

// Java platform classes

326

"java."

327

"javax."

328

"jakarta."

329

"sun."

330

"com.sun."

331

332

// XML processing

333

"org.xml."

334

"org.w3c."

335

336

// Other system classes

337

"org.slf4j." // Logging facade

338

"org.apache.commons.logging." // Commons logging

339

```

340

341

### Default Server Classes

342

343

Classes hidden from webapps (loaded by server classloader).

344

345

```java

346

// Jetty server classes

347

"org.eclipse.jetty."

348

"-org.eclipse.jetty.servlet.listener." // Except servlet listeners

349

"-org.eclipse.jetty.util.log." // Except webapp logging

350

351

// Server implementation classes

352

"org.mortbay."

353

"org.apache.jasper." // JSP compiler (when present)

354

```

355

356

## Usage Patterns

357

358

### Custom Class Isolation

359

360

```java

361

// Create webapp with custom class isolation

362

WebAppContext webapp = new WebAppContext();

363

364

// System classes: shared across all webapps

365

ClassMatcher systemClasses = new ClassMatcher();

366

systemClasses.include("java.", "javax.", "jakarta.");

367

systemClasses.include("com.mycompany.shared.");

368

webapp.setSystemClassMatcher(systemClasses);

369

370

// Server classes: hidden from webapps

371

ClassMatcher serverClasses = new ClassMatcher();

372

serverClasses.include("org.eclipse.jetty.");

373

serverClasses.include("com.mycompany.server.");

374

serverClasses.exclude("com.mycompany.server.api."); // Expose API

375

webapp.setServerClassMatcher(serverClasses);

376

```

377

378

### Development vs Production Patterns

379

380

```java

381

// Development: expose more server classes for debugging

382

if (isDevelopmentMode()) {

383

ClassMatcher serverClasses = webapp.getServerClassMatcher();

384

serverClasses.exclude("org.eclipse.jetty.util.log.");

385

serverClasses.exclude("org.eclipse.jetty.server.handler.DebugHandler");

386

}

387

388

// Production: strict isolation

389

if (isProductionMode()) {

390

ClassMatcher serverClasses = new ClassMatcher();

391

serverClasses.include("org.eclipse.jetty.");

392

serverClasses.include("com.mycompany.server.");

393

// No exclusions - strict hiding

394

webapp.setServerClassMatcher(serverClasses);

395

}

396

```

397

398

### Multi-Tenant Applications

399

400

```java

401

// Isolate tenant-specific classes

402

public class TenantConfiguration extends AbstractConfiguration {

403

private final String tenantId;

404

405

public TenantConfiguration(String tenantId) {

406

this.tenantId = tenantId;

407

408

// Each tenant gets their own version of these classes

409

hide("com.myapp.tenant." + tenantId + ".");

410

411

// But shared utilities are system classes

412

protect("com.myapp.shared.");

413

}

414

}

415

416

// Apply to webapp

417

webapp.addConfiguration(new TenantConfiguration("tenant1"));

418

```

419

420

### Library Version Isolation

421

422

```java

423

// Isolate specific library versions per webapp

424

ClassMatcher serverClasses = webapp.getServerClassMatcher();

425

426

// Hide server's Jackson version, let webapp use its own

427

serverClasses.include("com.fasterxml.jackson.");

428

429

// Hide server's Spring version

430

serverClasses.include("org.springframework.");

431

432

// But expose specific server utilities

433

serverClasses.exclude("com.mycompany.server.jackson.CustomModule");

434

```

435

436

### Dynamic Class Pattern Updates

437

438

```java

439

// Update patterns at runtime (before webapp start)

440

ClassMatcher matcher = webapp.getSystemClassMatcher();

441

442

// Add patterns dynamically

443

Properties config = loadConfiguration();

444

for (String pattern : config.getProperty("system.classes", "").split(",")) {

445

if (!pattern.trim().isEmpty()) {

446

matcher.include(pattern.trim());

447

}

448

}

449

450

// Remove patterns

451

for (String pattern : config.getProperty("exclude.system.classes", "").split(",")) {

452

if (!pattern.trim().isEmpty()) {

453

matcher.exclude(pattern.trim());

454

}

455

}

456

```