or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

classloader.mdconfiguration.mdindex.mdmetadata.mdwebapp-context.md

metadata.mddocs/

0

# Metadata Processing

1

2

The Jetty EE10 WebApp metadata processing system handles comprehensive analysis and resolution of web application descriptors, annotations, and fragment information. It provides a unified view of all configuration sources including web.xml, web-fragment.xml files, and discovered annotations.

3

4

## MetaData Container

5

6

The central container for all web application metadata.

7

8

```java { .api }

9

public class MetaData {

10

11

// Metadata management

12

public void clear();

13

14

// Descriptor management

15

public void setDefaultsDescriptor(DefaultsDescriptor descriptor)

16

throws Exception;

17

public void setWebDescriptor(WebDescriptor descriptor) throws Exception;

18

public void addOverrideDescriptor(OverrideDescriptor descriptor)

19

throws Exception;

20

public void addFragmentDescriptor(Resource jarResource,

21

FragmentDescriptor descriptor) throws Exception;

22

23

// Annotation management

24

public void addDiscoveredAnnotations(List<DiscoveredAnnotation> annotations);

25

public void addDiscoveredAnnotation(DiscoveredAnnotation annotation);

26

27

// Processor management

28

public void addDescriptorProcessor(DescriptorProcessor p);

29

public void removeDescriptorProcessor(DescriptorProcessor p);

30

31

// Resolution and validation

32

public void resolve(WebAppContext context) throws Exception;

33

public boolean isMetaDataComplete();

34

public boolean isDistributable();

35

36

// Descriptor access

37

public WebDescriptor getWebDescriptor();

38

public List<WebDescriptor> getOverrideDescriptors();

39

public WebDescriptor getDefaultsDescriptor();

40

41

// Fragment management

42

public boolean isOrdered();

43

public Ordering getOrdering();

44

public void setOrdering(Ordering o);

45

public FragmentDescriptor getFragmentDescriptor(String name);

46

public Resource getJarForFragmentName(String name);

47

public Map<String, FragmentDescriptor> getNamedFragmentDescriptors();

48

49

// Origin tracking

50

public Origin getOrigin(String name);

51

public OriginInfo getOriginInfo(String name);

52

public void setOrigin(String name, Descriptor d);

53

public void setOrigin(String name, Annotation annotation, Class<?> annotated);

54

public void setOriginAPI(String name);

55

56

// Resource management

57

public List<Resource> getWebInfResources(boolean withOrdering);

58

public List<Resource> getContainerResources();

59

60

// Configuration properties

61

public boolean isAllowDuplicateFragmentNames();

62

public void setAllowDuplicateFragmentNames(boolean allowDuplicateFragmentNames);

63

public boolean isValidateXml();

64

public void setValidateXml(boolean validateXml);

65

}

66

```

67

68

## Descriptor Base Classes

69

70

### Descriptor

71

72

Base class for all XML descriptor parsing.

73

74

```java { .api }

75

public abstract class Descriptor {

76

77

// Constructor

78

public Descriptor(Resource resource);

79

80

// Parsing

81

public void parse(XmlParser parser) throws Exception;

82

83

// Access methods

84

public String getURI();

85

public Resource getResource();

86

public XmlParser.Node getRoot();

87

}

88

```

89

90

### WebDescriptor

91

92

Handles web.xml, web-defaults.xml, and web-overrides.xml parsing.

93

94

```java { .api }

95

public class WebDescriptor extends Descriptor {

96

97

// Static utility methods

98

public static boolean isMetaDataComplete(WebDescriptor d);

99

public static XmlParser getParser(boolean validating);

100

public static XmlParser newParser(boolean validating);

101

102

// Metadata properties

103

public MetaData.Complete getMetaDataComplete();

104

public int getMajorVersion();

105

public int getMinorVersion();

106

107

// Class name management

108

public void addClassName(String className);

109

public ArrayList<String> getClassNames();

110

111

// Deployment properties

112

public boolean isDistributable();

113

114

// Ordering information

115

public boolean isOrdered();

116

public List<String> getOrdering();

117

}

118

```

119

120

### Specialized Descriptors

121

122

```java { .api }

123

public class DefaultsDescriptor extends WebDescriptor {

124

// Handles web-defaults.xml parsing

125

}

126

127

public class OverrideDescriptor extends WebDescriptor {

128

// Handles web-overrides.xml parsing

129

}

130

131

public class FragmentDescriptor extends WebDescriptor {

132

// Handles web-fragment.xml parsing from JAR files

133

}

134

```

135

136

## Descriptor Processing

137

138

### DescriptorProcessor Interface

139

140

```java { .api }

141

public interface DescriptorProcessor {

142

void process(WebAppContext context, Descriptor descriptor) throws Exception;

143

}

144

```

145

146

### StandardDescriptorProcessor

147

148

Processes standard servlet specification descriptors.

149

150

```java { .api }

151

public class StandardDescriptorProcessor extends IterativeDescriptorProcessor {

152

// Processes web.xml, web-defaults.xml, web-overrides.xml,

153

// and web-fragment.xml descriptors

154

}

155

```

156

157

### IterativeDescriptorProcessor

158

159

Base class for iterative descriptor processing.

160

161

```java { .api }

162

public abstract class IterativeDescriptorProcessor

163

implements DescriptorProcessor {

164

// Base functionality for iterating through descriptor elements

165

}

166

```

167

168

## Annotation Discovery

169

170

### DiscoveredAnnotation

171

172

Represents annotations discovered during classpath scanning.

173

174

```java { .api }

175

public abstract class DiscoveredAnnotation {

176

177

// Constructors

178

public DiscoveredAnnotation(WebAppContext context, String className);

179

public DiscoveredAnnotation(WebAppContext context, String className,

180

Resource resource);

181

182

// Core method - must be implemented by subclasses

183

public abstract void apply();

184

185

// Access methods

186

public String getClassName();

187

public Resource getResource();

188

public Class<?> getTargetClass();

189

}

190

```

191

192

## Ordering System

193

194

### Ordering Interface

195

196

```java { .api }

197

public interface Ordering {

198

List<Resource> order(List<Resource> fragments);

199

}

200

```

201

202

### Ordering Implementations

203

204

```java { .api }

205

public class AbsoluteOrdering implements Ordering {

206

// Implements absolute ordering for fragments

207

public List<Resource> order(List<Resource> fragments);

208

}

209

210

public class RelativeOrdering implements Ordering {

211

// Implements relative ordering for fragments

212

public List<Resource> order(List<Resource> fragments);

213

}

214

```

215

216

## Origin Tracking

217

218

### Origin Enum

219

220

```java { .api }

221

public enum Origin {

222

NotSet, WebXml, WebDefaults, WebOverride,

223

WebFragment, Annotation, API;

224

225

public static Origin of(Object o);

226

}

227

```

228

229

### OriginInfo

230

231

```java { .api }

232

public static class MetaData.OriginInfo {

233

// Contains detailed information about where metadata originated

234

}

235

```

236

237

## MetaData Constants

238

239

```java { .api }

240

public static final String VALIDATE_XML =

241

"org.eclipse.jetty.ee10.webapp.validateXml";

242

public static final String ORDERED_LIBS =

243

"org.eclipse.jetty.ee10.webapp.orderedLibs";

244

```

245

246

## MetaData Completion States

247

248

```java { .api }

249

public enum MetaData.Complete {

250

NotSet, True, False

251

}

252

```

253

254

## Usage Examples

255

256

### Basic MetaData Setup

257

258

```java

259

import org.eclipse.jetty.ee10.webapp.*;

260

261

WebAppContext context = new WebAppContext();

262

MetaData metaData = new MetaData();

263

264

// Set defaults descriptor

265

DefaultsDescriptor defaults = new DefaultsDescriptor(

266

ResourceFactory.of(context).newResource("webdefault.xml"));

267

defaults.parse(XmlParser.getParser(true));

268

metaData.setDefaultsDescriptor(defaults);

269

270

// Set main web descriptor

271

WebDescriptor webXml = new WebDescriptor(

272

context.getWebInf().resolve("web.xml"));

273

webXml.parse(XmlParser.getParser(true));

274

metaData.setWebDescriptor(webXml);

275

276

context.setMetaData(metaData);

277

```

278

279

### Fragment Processing

280

281

```java

282

import org.eclipse.jetty.ee10.webapp.*;

283

284

MetaData metaData = context.getMetaData();

285

286

// Add fragments from JAR files

287

Resource jarResource = ResourceFactory.of(context).newResource("lib/fragment.jar");

288

FragmentDescriptor fragment = new FragmentDescriptor(

289

jarResource.resolve("META-INF/web-fragment.xml"));

290

fragment.parse(XmlParser.getParser(true));

291

292

metaData.addFragmentDescriptor(jarResource, fragment);

293

294

// Set ordering if specified

295

if (metaData.isOrdered()) {

296

AbsoluteOrdering ordering = new AbsoluteOrdering();

297

metaData.setOrdering(ordering);

298

}

299

```

300

301

### Annotation Discovery and Processing

302

303

```java

304

import org.eclipse.jetty.ee10.webapp.*;

305

306

// Custom annotation implementation

307

public class WebServletAnnotation extends DiscoveredAnnotation {

308

309

private WebServlet annotation;

310

311

public WebServletAnnotation(WebAppContext context, String className,

312

Resource resource) {

313

super(context, className, resource);

314

// Extract annotation details

315

}

316

317

@Override

318

public void apply() {

319

// Apply the @WebServlet annotation to context

320

ServletHolder holder = new ServletHolder();

321

holder.setName(annotation.name());

322

holder.setClassName(getClassName());

323

324

// Add servlet mapping

325

for (String pattern : annotation.urlPatterns()) {

326

context.getServletHandler().addServletWithMapping(holder, pattern);

327

}

328

}

329

}

330

331

// Add discovered annotations

332

MetaData metaData = context.getMetaData();

333

List<DiscoveredAnnotation> annotations = new ArrayList<>();

334

annotations.add(new WebServletAnnotation(context, "com.example.MyServlet",

335

ResourceFactory.of(context).newResource("classes/com/example/MyServlet.class")));

336

337

metaData.addDiscoveredAnnotations(annotations);

338

```

339

340

### Custom Descriptor Processing

341

342

```java

343

import org.eclipse.jetty.ee10.webapp.*;

344

345

public class CustomDescriptorProcessor implements DescriptorProcessor {

346

347

@Override

348

public void process(WebAppContext context, Descriptor descriptor)

349

throws Exception {

350

351

if (descriptor instanceof WebDescriptor) {

352

WebDescriptor webDesc = (WebDescriptor) descriptor;

353

XmlParser.Node root = webDesc.getRoot();

354

355

// Process custom elements

356

XmlParser.Node[] customNodes = root.getNodes("custom-config");

357

for (XmlParser.Node node : customNodes) {

358

String value = node.toString();

359

context.setAttribute("custom.config", value);

360

}

361

}

362

}

363

}

364

365

// Add custom processor

366

MetaData metaData = context.getMetaData();

367

metaData.addDescriptorProcessor(new CustomDescriptorProcessor());

368

```

369

370

### Origin Tracking

371

372

```java

373

import org.eclipse.jetty.ee10.webapp.*;

374

375

MetaData metaData = context.getMetaData();

376

377

// Track origin of configuration elements

378

metaData.setOrigin("javax.servlet.Servlet", webXmlDescriptor);

379

metaData.setOrigin("com.example.MyServlet", annotation, MyServlet.class);

380

metaData.setOriginAPI("ServletContext.addServlet");

381

382

// Query origins

383

Origin servletOrigin = metaData.getOrigin("javax.servlet.Servlet");

384

OriginInfo info = metaData.getOriginInfo("com.example.MyServlet");

385

386

System.out.println("Servlet configuration came from: " + servletOrigin);

387

```

388

389

### MetaData Resolution and Validation

390

391

```java

392

import org.eclipse.jetty.ee10.webapp.*;

393

394

WebAppContext context = new WebAppContext();

395

MetaData metaData = context.getMetaData();

396

397

// Enable XML validation

398

metaData.setValidateXml(true);

399

400

// Allow duplicate fragment names if needed

401

metaData.setAllowDuplicateFragmentNames(false);

402

403

try {

404

// Resolve all metadata

405

metaData.resolve(context);

406

407

// Check completion status

408

if (metaData.isMetaDataComplete()) {

409

System.out.println("Metadata is complete - no annotation scanning needed");

410

} else {

411

System.out.println("Metadata incomplete - annotation scanning required");

412

}

413

414

// Check distributability

415

if (metaData.isDistributable()) {

416

System.out.println("Web application is distributable");

417

}

418

419

} catch (Exception e) {

420

System.err.println("Metadata resolution failed: " + e.getMessage());

421

}

422

```

423

424

### Resource and Fragment Management

425

426

```java

427

import org.eclipse.jetty.ee10.webapp.*;

428

429

MetaData metaData = context.getMetaData();

430

431

// Get WEB-INF resources with ordering

432

List<Resource> orderedResources = metaData.getWebInfResources(true);

433

List<Resource> containerResources = metaData.getContainerResources();

434

435

// Access fragment information

436

Map<String, FragmentDescriptor> fragments =

437

metaData.getNamedFragmentDescriptors();

438

439

for (Map.Entry<String, FragmentDescriptor> entry : fragments.entrySet()) {

440

String name = entry.getKey();

441

FragmentDescriptor fragment = entry.getValue();

442

Resource jar = metaData.getJarForFragmentName(name);

443

444

System.out.println("Fragment " + name + " from " + jar.getURI());

445

}

446

```

447

448

### Custom Ordering Implementation

449

450

```java

451

import org.eclipse.jetty.ee10.webapp.*;

452

453

public class CustomOrdering implements Ordering {

454

455

private List<String> beforeOthers;

456

private List<String> afterOthers;

457

458

@Override

459

public List<Resource> order(List<Resource> fragments) {

460

// Custom ordering logic

461

List<Resource> ordered = new ArrayList<>(fragments);

462

463

// Sort based on custom criteria

464

ordered.sort((r1, r2) -> {

465

// Compare fragment names, priorities, etc.

466

return getFragmentName(r1).compareTo(getFragmentName(r2));

467

});

468

469

return ordered;

470

}

471

472

private String getFragmentName(Resource resource) {

473

// Extract fragment name from resource

474

return resource.getFileName();

475

}

476

}

477

478

// Use custom ordering

479

MetaData metaData = context.getMetaData();

480

metaData.setOrdering(new CustomOrdering());

481

```

482

483

## Error Handling

484

485

Metadata processing can encounter various exceptions:

486

487

- `Exception` - General parsing or processing errors

488

- `IOException` - I/O errors when reading descriptor files

489

- `SAXException` - XML parsing errors in descriptors

490

- `ClassNotFoundException` - Missing classes referenced in annotations

491

- `IllegalStateException` - Invalid metadata state during resolution

492

493

Common error scenarios:

494

- Malformed XML in web.xml or fragment files

495

- Circular dependencies between fragments

496

- Missing or inaccessible descriptor files

497

- Invalid metadata-complete settings

498

- Conflicting fragment ordering specifications

499

- Annotation processing errors for missing classes

500

501

## Performance Considerations

502

503

### Metadata Caching

504

505

```java

506

// Enable container metadata caching for better performance

507

System.setProperty(MetaInfConfiguration.USE_CONTAINER_METAINF_CACHE, "true");

508

```

509

510

### XML Validation Control

511

512

```java

513

// Disable XML validation for faster parsing (development only)

514

MetaData metaData = context.getMetaData();

515

metaData.setValidateXml(false);

516

```

517

518

### Fragment Processing Optimization

519

520

```java

521

// Allow duplicate fragment names to reduce validation overhead

522

MetaData metaData = context.getMetaData();

523

metaData.setAllowDuplicateFragmentNames(true);

524

```