CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-glassfish-jaxb--jaxb-xjc

JAXB Binding Compiler (XJC) that generates Java classes from XML Schema definitions with both command-line and programmatic APIs

Pending
Overview
Eval results
Files

build-integration.mddocs/

Build Tool Integration

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

Capabilities

Ant Task Integration

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

/**
 * Modern XJC Ant task with full feature support
 */
public class XJC2Task extends Task {
    /**
     * Set schema file or directory to compile
     * @param schema File or directory containing schemas
     */
    public void setSchema(File schema);
    
    /**
     * Set target directory for generated sources
     * @param destdir Target directory
     */
    public void setDestdir(File destdir);
    
    /**
     * Set target package name for generated classes
     * @param packageName Package name
     */
    public void setPackage(String packageName);
    
    /**
     * Set binding customization file
     * @param binding Binding file
     */
    public void setBinding(File binding);
    
    /**
     * Set catalog file for entity resolution
     * @param catalog Catalog file
     */
    public void setCatalog(File catalog);
    
    /**
     * Enable or disable package level annotations
     * @param packageLevelAnnotations true to enable
     */
    public void setPackageLevelAnnotations(boolean packageLevelAnnotations);
    
    /**
     * Set character encoding for generated files
     * @param encoding Character encoding
     */
    public void setEncoding(String encoding);
    
    /**
     * Enable read-only mode
     * @param readOnly true for read-only
     */
    public void setReadOnly(boolean readOnly);
    
    /**
     * Set header comment for generated files
     * @param header Header comment
     */
    public void setHeader(String header);
    
    /**
     * Enable extension mode
     * @param extension true to enable extensions
     */
    public void setExtension(boolean extension);
    
    /**
     * Execute the task
     * @throws BuildException if compilation fails
     */
    public void execute() throws BuildException;
}

/**
 * Legacy XJC Ant task for compatibility
 */
public class XJCTask extends Task {
    // Similar interface to XJC2Task but with legacy behavior
    public void setSchema(String schema);
    public void setDestdir(File destdir);
    public void setPackage(String packageName);
    public void execute() throws BuildException;
}

/**
 * Base class for XJC Ant tasks
 */
public class XJCBase {
    /**
     * Common configuration and execution logic for XJC Ant tasks
     */
    protected void configureOptions(Options options);
    protected void executeXJC(Options options) throws BuildException;
}

Ant Task Usage Examples:

<!-- Basic XJC task -->
<taskdef name="xjc" classname="com.sun.tools.xjc.XJC2Task">
    <classpath>
        <fileset dir="lib" includes="jaxb-xjc-*.jar"/>
    </classpath>
</taskdef>

<!-- Simple schema compilation -->
<xjc schema="src/main/resources/schema.xsd" 
     destdir="target/generated-sources" 
     package="com.example.generated"/>

<!-- Advanced configuration -->
<xjc destdir="target/generated-sources" package="com.example.api">
    <schema dir="src/main/resources/schemas" includes="**/*.xsd"/>
    <binding dir="src/main/resources/bindings" includes="**/*.xjb"/>
    <classpath>
        <fileset dir="lib" includes="*.jar"/>
    </classpath>
    <arg value="-Xfluent-api"/>
    <arg value="-verbose"/>
</xjc>

<!-- Multiple schemas with dependencies -->
<xjc destdir="target/generated-sources" 
     package="com.example.common"
     extension="true">
    <schema file="common.xsd"/>
    <produces dir="target/generated-sources/com/example/common" includes="**/*.java"/>
    <depends file="common.xsd"/>
</xjc>

<xjc destdir="target/generated-sources" 
     package="com.example.specific"
     extension="true">
    <schema file="specific.xsd"/>
    <classpath>
        <pathelement path="target/generated-sources"/>
    </classpath>
    <arg value="-episode"/>
    <arg value="target/common.episode"/>
</xjc>

Maven Plugin Integration

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

Maven Plugin Configuration Examples:

<!-- Basic Maven configuration -->
<plugin>
    <groupId>org.jvnet.jaxb2.maven2</groupId>
    <artifactId>maven-jaxb2-plugin</artifactId>
    <version>0.14.0</version>
    <configuration>
        <schemaDirectory>src/main/resources/schemas</schemaDirectory>
        <generatePackage>com.example.generated</generatePackage>
        <generateDirectory>target/generated-sources/xjc</generateDirectory>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>generate</goal>
            </goals>
        </execution>
    </executions>
    <dependencies>
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-xjc</artifactId>
            <version>4.0.5</version>
        </dependency>
    </dependencies>
</plugin>

<!-- Advanced Maven configuration with plugins -->
<plugin>
    <groupId>org.jvnet.jaxb2.maven2</groupId>
    <artifactId>maven-jaxb2-plugin</artifactId>
    <version>0.14.0</version>
    <configuration>
        <schemaDirectory>src/main/resources/schemas</schemaDirectory>
        <bindingDirectory>src/main/resources/bindings</bindingDirectory>
        <generatePackage>com.example.api</generatePackage>
        <generateDirectory>target/generated-sources/xjc</generateDirectory>
        <extension>true</extension>
        <args>
            <arg>-Xfluent-api</arg>
            <arg>-Xtostring</arg>
            <arg>-XautoNameResolution</arg>
        </args>
        <plugins>
            <plugin>
                <groupId>com.example</groupId>
                <artifactId>xjc-fluent-plugin</artifactId>
                <version>1.0.0</version>
            </plugin>
        </plugins>
    </configuration>
</plugin>

Gradle Integration

Gradle integration using the JAXB plugin and custom task definitions.

Gradle Plugin Usage:

// Apply JAXB plugin
plugins {
    id 'java'
    id 'org.unbroken-dome.xjc' version '2.0.0'
}

// Configure XJC
xjc {
    srcDirName = 'src/main/schemas'
    bindingFiles = fileTree(dir: 'src/main/bindings', include: '**/*.xjb')
    targetPackage = 'com.example.generated'
    outputDir = file('build/generated-sources/xjc')
}

// Dependencies
dependencies {
    implementation 'org.glassfish.jaxb:jaxb-runtime:4.0.5'
    xjc 'org.glassfish.jaxb:jaxb-xjc:4.0.5'
}

// Custom XJC task
task generateFromCustomSchema(type: org.unbroken_dome.gradle.plugins.xjc.XjcGenerate) {
    source = fileTree(dir: 'custom-schemas', include: '**/*.xsd')
    bindingFiles = fileTree(dir: 'custom-bindings', include: '**/*.xjb')
    targetPackage = 'com.example.custom'
    outputDirectory = file('build/generated-sources/custom')
    options {
        extension = true
        header = false
        verbose = true
    }
}

Programmatic Build Integration

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

/**
 * Custom build integration utility
 */
public class BuildIntegration {
    /**
     * Execute XJC compilation with build-specific configuration
     * @param config Build configuration
     * @return true if compilation successful
     */
    public static boolean executeXJC(BuildConfiguration config);
    
    /**
     * Generate code with custom post-processing
     * @param schemas Schema files to compile
     * @param outputDir Output directory
     * @param packageName Target package
     * @param postProcessor Custom post-processor
     * @return Generated code model
     */
    public static JCodeModel generateWithPostProcessing(
        List<File> schemas, 
        File outputDir, 
        String packageName,
        CodePostProcessor postProcessor);
}

/**
 * Configuration for build integration
 */
public class BuildConfiguration {
    private List<File> schemaFiles;
    private List<File> bindingFiles;
    private File outputDirectory;
    private String targetPackage;
    private List<String> plugins;
    private Map<String, String> properties;
    private ErrorListener errorListener;
    
    // Configuration methods
    public void addSchemaFile(File schema);
    public void addBindingFile(File binding);
    public void setOutputDirectory(File dir);
    public void setTargetPackage(String packageName);
    public void addPlugin(String pluginName);
    public void setProperty(String key, String value);
    public void setErrorListener(ErrorListener listener);
}

Custom Build Integration Example:

import com.sun.tools.xjc.api.*;
import com.sun.codemodel.*;
import java.io.File;
import java.util.List;
import java.util.ArrayList;

public class CustomBuildIntegration {
    
    public static class BuildResult {
        private final boolean success;
        private final List<String> generatedFiles;
        private final List<String> errors;
        private final List<String> warnings;
        
        public BuildResult(boolean success, List<String> generatedFiles, 
                          List<String> errors, List<String> warnings) {
            this.success = success;
            this.generatedFiles = new ArrayList<>(generatedFiles);
            this.errors = new ArrayList<>(errors);
            this.warnings = new ArrayList<>(warnings);
        }
        
        public boolean isSuccess() { return success; }
        public List<String> getGeneratedFiles() { return generatedFiles; }
        public List<String> getErrors() { return errors; }
        public List<String> getWarnings() { return warnings; }
    }
    
    public static BuildResult compileSchemas(
            List<File> schemaFiles,
            File outputDir,
            String packageName,
            List<String> pluginArgs) {
        
        List<String> generatedFiles = new ArrayList<>();
        List<String> errors = new ArrayList<>();
        List<String> warnings = new ArrayList<>();
        
        try {
            // Create compiler
            SchemaCompiler compiler = XJC.createSchemaCompiler();
            
            // Configure error handling
            compiler.setErrorListener(new ErrorListener() {
                @Override
                public void error(SAXParseException exception) {
                    errors.add(formatError("ERROR", exception));
                }
                
                @Override
                public void warning(SAXParseException exception) {
                    warnings.add(formatError("WARNING", exception));
                }
                
                @Override
                public void info(SAXParseException exception) {
                    // Log info messages
                }
            });
            
            // Configure compiler
            compiler.setDefaultPackageName(packageName);
            
            // Parse schemas
            for (File schemaFile : schemaFiles) {
                InputSource source = new InputSource(new FileInputStream(schemaFile));
                source.setSystemId(schemaFile.toURI().toString());
                compiler.parseSchema(source);
            }
            
            // Compile
            S2JJAXBModel model = compiler.bind();
            if (model == null) {
                errors.add("Schema compilation failed");
                return new BuildResult(false, generatedFiles, errors, warnings);
            }
            
            // Generate code
            JCodeModel codeModel = model.generateCode(null, null);
            
            // Custom code writer that tracks generated files
            FileCodeWriter writer = new FileCodeWriter(outputDir) {
                @Override
                public Writer openSource(JPackage pkg, String fileName) throws IOException {
                    generatedFiles.add(pkg.name().replace('.', '/') + "/" + fileName);
                    return super.openSource(pkg, fileName);
                }
            };
            
            codeModel.build(writer);
            
            return new BuildResult(true, generatedFiles, errors, warnings);
            
        } catch (Exception e) {
            errors.add("Build failed: " + e.getMessage());
            return new BuildResult(false, generatedFiles, errors, warnings);
        }
    }
    
    private static String formatError(String level, SAXParseException e) {
        return String.format("%s [%s:%d:%d] %s",
            level,
            e.getSystemId() != null ? e.getSystemId() : "unknown",
            e.getLineNumber(),
            e.getColumnNumber(),
            e.getMessage());
    }
}

Multi-Module Build Support

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

Episode-Based Multi-Module Build:

import com.sun.tools.xjc.Driver;
import java.io.File;
import java.util.Arrays;

public class MultiModuleBuildSupport {
    
    public static void buildCommonModule(File schemaDir, File outputDir, File episodeFile) 
            throws Exception {
        String[] args = {
            "-d", outputDir.getAbsolutePath(),
            "-p", "com.example.common",
            "-episode", episodeFile.getAbsolutePath(),
            new File(schemaDir, "common.xsd").getAbsolutePath()
        };
        
        int result = Driver.run(args, System.out, System.err);
        if (result != 0) {
            throw new Exception("Common module compilation failed");
        }
    }
    
    public static void buildSpecificModule(File schemaDir, File outputDir, 
                                         File episodeFile, File commonClasspath) 
            throws Exception {
        String[] args = {
            "-d", outputDir.getAbsolutePath(),
            "-p", "com.example.specific",
            "-classpath", commonClasspath.getAbsolutePath(),
            episodeFile.getAbsolutePath(),
            new File(schemaDir, "specific.xsd").getAbsolutePath()
        };
        
        int result = Driver.run(args, System.out, System.err);
        if (result != 0) {
            throw new Exception("Specific module compilation failed");
        }
    }
}

Incremental Build Support

Support for incremental builds to optimize build performance.

import java.io.File;
import java.nio.file.Files;
import java.nio.file.attribute.FileTime;
import java.util.List;
import java.util.stream.Collectors;

public class IncrementalBuildSupport {
    
    public static boolean needsRecompilation(List<File> schemaFiles, 
                                           List<File> bindingFiles,
                                           File outputDir) {
        // Check if output directory exists
        if (!outputDir.exists() || !outputDir.isDirectory()) {
            return true;
        }
        
        // Find newest input file
        FileTime newestInput = schemaFiles.stream()
            .flatMap(f -> Stream.concat(
                Stream.of(f),
                bindingFiles.stream()
            ))
            .map(f -> {
                try {
                    return Files.getLastModifiedTime(f.toPath());
                } catch (IOException e) {
                    return FileTime.fromMillis(0);
                }
            })
            .max(FileTime::compareTo)
            .orElse(FileTime.fromMillis(0));
        
        // Find oldest output file
        try {
            FileTime oldestOutput = Files.walk(outputDir.toPath())
                .filter(Files::isRegularFile)
                .filter(p -> p.toString().endsWith(".java"))
                .map(p -> {
                    try {
                        return Files.getLastModifiedTime(p);
                    } catch (IOException e) {
                        return FileTime.fromMillis(Long.MAX_VALUE);
                    }
                })
                .min(FileTime::compareTo)
                .orElse(FileTime.fromMillis(Long.MAX_VALUE));
            
            return newestInput.compareTo(oldestOutput) > 0;
            
        } catch (IOException e) {
            return true; // Error reading output, force recompilation
        }
    }
    
    public static void cleanOutputDirectory(File outputDir, String packageName) {
        File packageDir = new File(outputDir, packageName.replace('.', '/'));
        if (packageDir.exists()) {
            try {
                Files.walk(packageDir.toPath())
                    .sorted(Comparator.reverseOrder())
                    .map(Path::toFile)
                    .forEach(File::delete);
            } catch (IOException e) {
                System.err.println("Warning: Could not clean output directory: " + e.getMessage());
            }
        }
    }
}

Build Performance Optimization

Optimization techniques for large-scale builds.

public class BuildOptimization {
    
    /**
     * Parallel schema compilation for independent schema groups
     */
    public static void compileInParallel(List<SchemaGroup> schemaGroups, 
                                       int maxThreads) {
        ExecutorService executor = Executors.newFixedThreadPool(maxThreads);
        List<Future<BuildResult>> futures = new ArrayList<>();
        
        for (SchemaGroup group : schemaGroups) {
            Future<BuildResult> future = executor.submit(() -> {
                return CustomBuildIntegration.compileSchemas(
                    group.getSchemaFiles(),
                    group.getOutputDir(),
                    group.getPackageName(),
                    group.getPluginArgs()
                );
            });
            futures.add(future);
        }
        
        // Wait for all compilations to complete
        for (Future<BuildResult> future : futures) {
            try {
                BuildResult result = future.get();
                if (!result.isSuccess()) {
                    System.err.println("Compilation failed: " + result.getErrors());
                }
            } catch (Exception e) {
                System.err.println("Compilation error: " + e.getMessage());
            }
        }
        
        executor.shutdown();
    }
    
    /**
     * Memory-efficient compilation for large schemas
     */
    public static void compileWithMemoryOptimization(List<File> schemaFiles,
                                                   File outputDir,
                                                   String packageName) {
        // Process schemas in batches to manage memory usage
        int batchSize = 10;
        for (int i = 0; i < schemaFiles.size(); i += batchSize) {
            int endIndex = Math.min(i + batchSize, schemaFiles.size());
            List<File> batch = schemaFiles.subList(i, endIndex);
            
            try {
                CustomBuildIntegration.compileSchemas(batch, outputDir, 
                    packageName + ".batch" + (i / batchSize), Collections.emptyList());
                
                // Force garbage collection between batches
                System.gc();
                
            } catch (Exception e) {
                System.err.println("Batch compilation failed: " + e.getMessage());
            }
        }
    }
}

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.

Install with Tessl CLI

npx tessl i tessl/maven-org-glassfish-jaxb--jaxb-xjc

docs

build-integration.md

cli.md

code-generation.md

error-handling.md

index.md

plugin-system.md

programmatic-api.md

tile.json