or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

build-integration.mdcli.mdcode-generation.mderror-handling.mdindex.mdplugin-system.mdprogrammatic-api.md

build-integration.mddocs/

0

# Build Tool Integration

1

2

JAXB XJC provides comprehensive integration capabilities for build systems including Ant tasks, Maven plugins, and Gradle integration through both dedicated tasks and programmatic APIs.

3

4

## Capabilities

5

6

### Ant Task Integration

7

8

XJC provides dedicated Ant tasks for integrating schema compilation into Ant-based build processes.

9

10

```java { .api }

11

/**

12

* Modern XJC Ant task with full feature support

13

*/

14

public class XJC2Task extends Task {

15

/**

16

* Set schema file or directory to compile

17

* @param schema File or directory containing schemas

18

*/

19

public void setSchema(File schema);

20

21

/**

22

* Set target directory for generated sources

23

* @param destdir Target directory

24

*/

25

public void setDestdir(File destdir);

26

27

/**

28

* Set target package name for generated classes

29

* @param packageName Package name

30

*/

31

public void setPackage(String packageName);

32

33

/**

34

* Set binding customization file

35

* @param binding Binding file

36

*/

37

public void setBinding(File binding);

38

39

/**

40

* Set catalog file for entity resolution

41

* @param catalog Catalog file

42

*/

43

public void setCatalog(File catalog);

44

45

/**

46

* Enable or disable package level annotations

47

* @param packageLevelAnnotations true to enable

48

*/

49

public void setPackageLevelAnnotations(boolean packageLevelAnnotations);

50

51

/**

52

* Set character encoding for generated files

53

* @param encoding Character encoding

54

*/

55

public void setEncoding(String encoding);

56

57

/**

58

* Enable read-only mode

59

* @param readOnly true for read-only

60

*/

61

public void setReadOnly(boolean readOnly);

62

63

/**

64

* Set header comment for generated files

65

* @param header Header comment

66

*/

67

public void setHeader(String header);

68

69

/**

70

* Enable extension mode

71

* @param extension true to enable extensions

72

*/

73

public void setExtension(boolean extension);

74

75

/**

76

* Execute the task

77

* @throws BuildException if compilation fails

78

*/

79

public void execute() throws BuildException;

80

}

81

82

/**

83

* Legacy XJC Ant task for compatibility

84

*/

85

public class XJCTask extends Task {

86

// Similar interface to XJC2Task but with legacy behavior

87

public void setSchema(String schema);

88

public void setDestdir(File destdir);

89

public void setPackage(String packageName);

90

public void execute() throws BuildException;

91

}

92

93

/**

94

* Base class for XJC Ant tasks

95

*/

96

public class XJCBase {

97

/**

98

* Common configuration and execution logic for XJC Ant tasks

99

*/

100

protected void configureOptions(Options options);

101

protected void executeXJC(Options options) throws BuildException;

102

}

103

```

104

105

**Ant Task Usage Examples:**

106

107

```xml

108

<!-- Basic XJC task -->

109

<taskdef name="xjc" classname="com.sun.tools.xjc.XJC2Task">

110

<classpath>

111

<fileset dir="lib" includes="jaxb-xjc-*.jar"/>

112

</classpath>

113

</taskdef>

114

115

<!-- Simple schema compilation -->

116

<xjc schema="src/main/resources/schema.xsd"

117

destdir="target/generated-sources"

118

package="com.example.generated"/>

119

120

<!-- Advanced configuration -->

121

<xjc destdir="target/generated-sources" package="com.example.api">

122

<schema dir="src/main/resources/schemas" includes="**/*.xsd"/>

123

<binding dir="src/main/resources/bindings" includes="**/*.xjb"/>

124

<classpath>

125

<fileset dir="lib" includes="*.jar"/>

126

</classpath>

127

<arg value="-Xfluent-api"/>

128

<arg value="-verbose"/>

129

</xjc>

130

131

<!-- Multiple schemas with dependencies -->

132

<xjc destdir="target/generated-sources"

133

package="com.example.common"

134

extension="true">

135

<schema file="common.xsd"/>

136

<produces dir="target/generated-sources/com/example/common" includes="**/*.java"/>

137

<depends file="common.xsd"/>

138

</xjc>

139

140

<xjc destdir="target/generated-sources"

141

package="com.example.specific"

142

extension="true">

143

<schema file="specific.xsd"/>

144

<classpath>

145

<pathelement path="target/generated-sources"/>

146

</classpath>

147

<arg value="-episode"/>

148

<arg value="target/common.episode"/>

149

</xjc>

150

```

151

152

### Maven Plugin Integration

153

154

Integration patterns for Maven-based builds using the JAXB Maven plugin.

155

156

**Maven Plugin Configuration Examples:**

157

158

```xml

159

<!-- Basic Maven configuration -->

160

<plugin>

161

<groupId>org.jvnet.jaxb2.maven2</groupId>

162

<artifactId>maven-jaxb2-plugin</artifactId>

163

<version>0.14.0</version>

164

<configuration>

165

<schemaDirectory>src/main/resources/schemas</schemaDirectory>

166

<generatePackage>com.example.generated</generatePackage>

167

<generateDirectory>target/generated-sources/xjc</generateDirectory>

168

</configuration>

169

<executions>

170

<execution>

171

<goals>

172

<goal>generate</goal>

173

</goals>

174

</execution>

175

</executions>

176

<dependencies>

177

<dependency>

178

<groupId>org.glassfish.jaxb</groupId>

179

<artifactId>jaxb-xjc</artifactId>

180

<version>4.0.5</version>

181

</dependency>

182

</dependencies>

183

</plugin>

184

185

<!-- Advanced Maven configuration with plugins -->

186

<plugin>

187

<groupId>org.jvnet.jaxb2.maven2</groupId>

188

<artifactId>maven-jaxb2-plugin</artifactId>

189

<version>0.14.0</version>

190

<configuration>

191

<schemaDirectory>src/main/resources/schemas</schemaDirectory>

192

<bindingDirectory>src/main/resources/bindings</bindingDirectory>

193

<generatePackage>com.example.api</generatePackage>

194

<generateDirectory>target/generated-sources/xjc</generateDirectory>

195

<extension>true</extension>

196

<args>

197

<arg>-Xfluent-api</arg>

198

<arg>-Xtostring</arg>

199

<arg>-XautoNameResolution</arg>

200

</args>

201

<plugins>

202

<plugin>

203

<groupId>com.example</groupId>

204

<artifactId>xjc-fluent-plugin</artifactId>

205

<version>1.0.0</version>

206

</plugin>

207

</plugins>

208

</configuration>

209

</plugin>

210

```

211

212

### Gradle Integration

213

214

Gradle integration using the JAXB plugin and custom task definitions.

215

216

**Gradle Plugin Usage:**

217

218

```groovy

219

// Apply JAXB plugin

220

plugins {

221

id 'java'

222

id 'org.unbroken-dome.xjc' version '2.0.0'

223

}

224

225

// Configure XJC

226

xjc {

227

srcDirName = 'src/main/schemas'

228

bindingFiles = fileTree(dir: 'src/main/bindings', include: '**/*.xjb')

229

targetPackage = 'com.example.generated'

230

outputDir = file('build/generated-sources/xjc')

231

}

232

233

// Dependencies

234

dependencies {

235

implementation 'org.glassfish.jaxb:jaxb-runtime:4.0.5'

236

xjc 'org.glassfish.jaxb:jaxb-xjc:4.0.5'

237

}

238

239

// Custom XJC task

240

task generateFromCustomSchema(type: org.unbroken_dome.gradle.plugins.xjc.XjcGenerate) {

241

source = fileTree(dir: 'custom-schemas', include: '**/*.xsd')

242

bindingFiles = fileTree(dir: 'custom-bindings', include: '**/*.xjb')

243

targetPackage = 'com.example.custom'

244

outputDirectory = file('build/generated-sources/custom')

245

options {

246

extension = true

247

header = false

248

verbose = true

249

}

250

}

251

```

252

253

### Programmatic Build Integration

254

255

Custom build integration using the programmatic API for specialized build requirements.

256

257

```java { .api }

258

/**

259

* Custom build integration utility

260

*/

261

public class BuildIntegration {

262

/**

263

* Execute XJC compilation with build-specific configuration

264

* @param config Build configuration

265

* @return true if compilation successful

266

*/

267

public static boolean executeXJC(BuildConfiguration config);

268

269

/**

270

* Generate code with custom post-processing

271

* @param schemas Schema files to compile

272

* @param outputDir Output directory

273

* @param packageName Target package

274

* @param postProcessor Custom post-processor

275

* @return Generated code model

276

*/

277

public static JCodeModel generateWithPostProcessing(

278

List<File> schemas,

279

File outputDir,

280

String packageName,

281

CodePostProcessor postProcessor);

282

}

283

284

/**

285

* Configuration for build integration

286

*/

287

public class BuildConfiguration {

288

private List<File> schemaFiles;

289

private List<File> bindingFiles;

290

private File outputDirectory;

291

private String targetPackage;

292

private List<String> plugins;

293

private Map<String, String> properties;

294

private ErrorListener errorListener;

295

296

// Configuration methods

297

public void addSchemaFile(File schema);

298

public void addBindingFile(File binding);

299

public void setOutputDirectory(File dir);

300

public void setTargetPackage(String packageName);

301

public void addPlugin(String pluginName);

302

public void setProperty(String key, String value);

303

public void setErrorListener(ErrorListener listener);

304

}

305

```

306

307

**Custom Build Integration Example:**

308

309

```java

310

import com.sun.tools.xjc.api.*;

311

import com.sun.codemodel.*;

312

import java.io.File;

313

import java.util.List;

314

import java.util.ArrayList;

315

316

public class CustomBuildIntegration {

317

318

public static class BuildResult {

319

private final boolean success;

320

private final List<String> generatedFiles;

321

private final List<String> errors;

322

private final List<String> warnings;

323

324

public BuildResult(boolean success, List<String> generatedFiles,

325

List<String> errors, List<String> warnings) {

326

this.success = success;

327

this.generatedFiles = new ArrayList<>(generatedFiles);

328

this.errors = new ArrayList<>(errors);

329

this.warnings = new ArrayList<>(warnings);

330

}

331

332

public boolean isSuccess() { return success; }

333

public List<String> getGeneratedFiles() { return generatedFiles; }

334

public List<String> getErrors() { return errors; }

335

public List<String> getWarnings() { return warnings; }

336

}

337

338

public static BuildResult compileSchemas(

339

List<File> schemaFiles,

340

File outputDir,

341

String packageName,

342

List<String> pluginArgs) {

343

344

List<String> generatedFiles = new ArrayList<>();

345

List<String> errors = new ArrayList<>();

346

List<String> warnings = new ArrayList<>();

347

348

try {

349

// Create compiler

350

SchemaCompiler compiler = XJC.createSchemaCompiler();

351

352

// Configure error handling

353

compiler.setErrorListener(new ErrorListener() {

354

@Override

355

public void error(SAXParseException exception) {

356

errors.add(formatError("ERROR", exception));

357

}

358

359

@Override

360

public void warning(SAXParseException exception) {

361

warnings.add(formatError("WARNING", exception));

362

}

363

364

@Override

365

public void info(SAXParseException exception) {

366

// Log info messages

367

}

368

});

369

370

// Configure compiler

371

compiler.setDefaultPackageName(packageName);

372

373

// Parse schemas

374

for (File schemaFile : schemaFiles) {

375

InputSource source = new InputSource(new FileInputStream(schemaFile));

376

source.setSystemId(schemaFile.toURI().toString());

377

compiler.parseSchema(source);

378

}

379

380

// Compile

381

S2JJAXBModel model = compiler.bind();

382

if (model == null) {

383

errors.add("Schema compilation failed");

384

return new BuildResult(false, generatedFiles, errors, warnings);

385

}

386

387

// Generate code

388

JCodeModel codeModel = model.generateCode(null, null);

389

390

// Custom code writer that tracks generated files

391

FileCodeWriter writer = new FileCodeWriter(outputDir) {

392

@Override

393

public Writer openSource(JPackage pkg, String fileName) throws IOException {

394

generatedFiles.add(pkg.name().replace('.', '/') + "/" + fileName);

395

return super.openSource(pkg, fileName);

396

}

397

};

398

399

codeModel.build(writer);

400

401

return new BuildResult(true, generatedFiles, errors, warnings);

402

403

} catch (Exception e) {

404

errors.add("Build failed: " + e.getMessage());

405

return new BuildResult(false, generatedFiles, errors, warnings);

406

}

407

}

408

409

private static String formatError(String level, SAXParseException e) {

410

return String.format("%s [%s:%d:%d] %s",

411

level,

412

e.getSystemId() != null ? e.getSystemId() : "unknown",

413

e.getLineNumber(),

414

e.getColumnNumber(),

415

e.getMessage());

416

}

417

}

418

```

419

420

### Multi-Module Build Support

421

422

Support for complex multi-module builds with shared schemas and episode files.

423

424

**Episode-Based Multi-Module Build:**

425

426

```java

427

import com.sun.tools.xjc.Driver;

428

import java.io.File;

429

import java.util.Arrays;

430

431

public class MultiModuleBuildSupport {

432

433

public static void buildCommonModule(File schemaDir, File outputDir, File episodeFile)

434

throws Exception {

435

String[] args = {

436

"-d", outputDir.getAbsolutePath(),

437

"-p", "com.example.common",

438

"-episode", episodeFile.getAbsolutePath(),

439

new File(schemaDir, "common.xsd").getAbsolutePath()

440

};

441

442

int result = Driver.run(args, System.out, System.err);

443

if (result != 0) {

444

throw new Exception("Common module compilation failed");

445

}

446

}

447

448

public static void buildSpecificModule(File schemaDir, File outputDir,

449

File episodeFile, File commonClasspath)

450

throws Exception {

451

String[] args = {

452

"-d", outputDir.getAbsolutePath(),

453

"-p", "com.example.specific",

454

"-classpath", commonClasspath.getAbsolutePath(),

455

episodeFile.getAbsolutePath(),

456

new File(schemaDir, "specific.xsd").getAbsolutePath()

457

};

458

459

int result = Driver.run(args, System.out, System.err);

460

if (result != 0) {

461

throw new Exception("Specific module compilation failed");

462

}

463

}

464

}

465

```

466

467

### Incremental Build Support

468

469

Support for incremental builds to optimize build performance.

470

471

```java

472

import java.io.File;

473

import java.nio.file.Files;

474

import java.nio.file.attribute.FileTime;

475

import java.util.List;

476

import java.util.stream.Collectors;

477

478

public class IncrementalBuildSupport {

479

480

public static boolean needsRecompilation(List<File> schemaFiles,

481

List<File> bindingFiles,

482

File outputDir) {

483

// Check if output directory exists

484

if (!outputDir.exists() || !outputDir.isDirectory()) {

485

return true;

486

}

487

488

// Find newest input file

489

FileTime newestInput = schemaFiles.stream()

490

.flatMap(f -> Stream.concat(

491

Stream.of(f),

492

bindingFiles.stream()

493

))

494

.map(f -> {

495

try {

496

return Files.getLastModifiedTime(f.toPath());

497

} catch (IOException e) {

498

return FileTime.fromMillis(0);

499

}

500

})

501

.max(FileTime::compareTo)

502

.orElse(FileTime.fromMillis(0));

503

504

// Find oldest output file

505

try {

506

FileTime oldestOutput = Files.walk(outputDir.toPath())

507

.filter(Files::isRegularFile)

508

.filter(p -> p.toString().endsWith(".java"))

509

.map(p -> {

510

try {

511

return Files.getLastModifiedTime(p);

512

} catch (IOException e) {

513

return FileTime.fromMillis(Long.MAX_VALUE);

514

}

515

})

516

.min(FileTime::compareTo)

517

.orElse(FileTime.fromMillis(Long.MAX_VALUE));

518

519

return newestInput.compareTo(oldestOutput) > 0;

520

521

} catch (IOException e) {

522

return true; // Error reading output, force recompilation

523

}

524

}

525

526

public static void cleanOutputDirectory(File outputDir, String packageName) {

527

File packageDir = new File(outputDir, packageName.replace('.', '/'));

528

if (packageDir.exists()) {

529

try {

530

Files.walk(packageDir.toPath())

531

.sorted(Comparator.reverseOrder())

532

.map(Path::toFile)

533

.forEach(File::delete);

534

} catch (IOException e) {

535

System.err.println("Warning: Could not clean output directory: " + e.getMessage());

536

}

537

}

538

}

539

}

540

```

541

542

### Build Performance Optimization

543

544

Optimization techniques for large-scale builds.

545

546

```java

547

public class BuildOptimization {

548

549

/**

550

* Parallel schema compilation for independent schema groups

551

*/

552

public static void compileInParallel(List<SchemaGroup> schemaGroups,

553

int maxThreads) {

554

ExecutorService executor = Executors.newFixedThreadPool(maxThreads);

555

List<Future<BuildResult>> futures = new ArrayList<>();

556

557

for (SchemaGroup group : schemaGroups) {

558

Future<BuildResult> future = executor.submit(() -> {

559

return CustomBuildIntegration.compileSchemas(

560

group.getSchemaFiles(),

561

group.getOutputDir(),

562

group.getPackageName(),

563

group.getPluginArgs()

564

);

565

});

566

futures.add(future);

567

}

568

569

// Wait for all compilations to complete

570

for (Future<BuildResult> future : futures) {

571

try {

572

BuildResult result = future.get();

573

if (!result.isSuccess()) {

574

System.err.println("Compilation failed: " + result.getErrors());

575

}

576

} catch (Exception e) {

577

System.err.println("Compilation error: " + e.getMessage());

578

}

579

}

580

581

executor.shutdown();

582

}

583

584

/**

585

* Memory-efficient compilation for large schemas

586

*/

587

public static void compileWithMemoryOptimization(List<File> schemaFiles,

588

File outputDir,

589

String packageName) {

590

// Process schemas in batches to manage memory usage

591

int batchSize = 10;

592

for (int i = 0; i < schemaFiles.size(); i += batchSize) {

593

int endIndex = Math.min(i + batchSize, schemaFiles.size());

594

List<File> batch = schemaFiles.subList(i, endIndex);

595

596

try {

597

CustomBuildIntegration.compileSchemas(batch, outputDir,

598

packageName + ".batch" + (i / batchSize), Collections.emptyList());

599

600

// Force garbage collection between batches

601

System.gc();

602

603

} catch (Exception e) {

604

System.err.println("Batch compilation failed: " + e.getMessage());

605

}

606

}

607

}

608

}

609

```

610

611

This build integration system provides comprehensive support for integrating JAXB XJC into various build systems and workflows, with optimizations for performance and maintainability in large-scale projects.