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

error-handling.mddocs/

Error Handling and Validation

JAXB XJC provides comprehensive error reporting and validation capabilities through a flexible error handling system that supports different integration patterns and customization levels.

Capabilities

Error Receiver System

Base error handling infrastructure for both command-line and programmatic usage.

/**
 * Abstract base class for handling compilation errors, warnings, and info messages
 */
public abstract class ErrorReceiver {
    /**
     * Handle compilation errors that prevent successful generation
     * @param exception SAXParseException containing error details and location
     */
    public abstract void error(SAXParseException exception);
    
    /**
     * Handle compilation warnings that don't prevent generation
     * @param exception SAXParseException containing warning details and location
     */
    public abstract void warning(SAXParseException exception);
    
    /**
     * Handle informational messages about compilation process
     * @param exception SAXParseException containing info details and location
     */
    public abstract void info(SAXParseException exception);
    
    /**
     * Check if compilation should be aborted
     * Called periodically during long-running operations
     * @throws AbortException if compilation should be terminated
     */
    public void pollAbort() throws AbortException;
    
    /**
     * Handle generic exceptions during compilation
     * @param e Exception that occurred
     */
    public void error(Exception e);
    
    /**
     * Handle errors with custom messages
     * @param msg Error message
     * @param e Underlying exception, may be null
     */
    public void error(String msg, Exception e);
    
    /**
     * Log debug messages if debug mode is enabled
     * @param msg Debug message
     */
    public final void debug(String msg);
}

Programmatic API Error Listener

Simplified error handling interface for programmatic API usage.

/**
 * Error handling interface for programmatic API with structured error reporting
 */
public interface ErrorListener {
    /**
     * Handle compilation errors
     * @param exception SAXParseException with error details including line/column numbers
     */
    void error(SAXParseException exception);
    
    /**
     * Handle compilation warnings
     * @param exception SAXParseException with warning details including line/column numbers
     */
    void warning(SAXParseException exception);
    
    /**
     * Handle informational messages
     * @param exception SAXParseException with info details including line/column numbers
     */
    void info(SAXParseException exception);
}

Error Filtering and Processing

Advanced error processing utilities for customizing error handling behavior.

/**
 * Error receiver that filters and processes errors before delegating
 */
public class ErrorReceiverFilter extends ErrorReceiver {
    /**
     * Delegate error receiver
     */
    protected final ErrorReceiver core;
    
    /**
     * Create filter with delegate receiver
     * @param core ErrorReceiver to delegate filtered messages to
     */
    public ErrorReceiverFilter(ErrorReceiver core);
    
    // Filtering can be customized in subclasses
    public void error(SAXParseException exception);
    public void warning(SAXParseException exception);
    public void info(SAXParseException exception);
    public void pollAbort() throws AbortException;
}

Console Error Reporting

Built-in console error reporter for command-line usage.

/**
 * Console-based error reporter with formatted output
 */
public class ConsoleErrorReporter extends ErrorReceiver {
    /**
     * Create console reporter writing to specified PrintStream
     * @param output PrintStream for error output
     */
    public ConsoleErrorReporter(PrintStream output);
    
    /**
     * Create console reporter with custom error counter
     * @param output PrintStream for error output
     * @param errorCounter Counter for tracking error statistics
     */
    public ConsoleErrorReporter(PrintStream output, ErrorCounter errorCounter);
    
    public void error(SAXParseException exception);
    public void warning(SAXParseException exception);
    public void info(SAXParseException exception);
    
    /**
     * Check if any errors have been reported
     * @return true if errors occurred
     */
    public boolean hadError();
}

Exception Types

Specific exception types for different error conditions.

/**
 * Exception thrown when command line arguments are invalid
 */
public class BadCommandLineException extends Exception {
    /**
     * Create exception with message
     * @param message Error description
     */
    public BadCommandLineException(String message);
    
    /**
     * Create exception with message and cause
     * @param message Error description
     * @param cause Underlying cause
     */
    public BadCommandLineException(String message, Throwable cause);
    
    /**
     * Initialize with options for context
     * @param opts Options object for additional context
     */
    public void initOptions(Options opts);
    
    /**
     * Get associated options
     * @return Options object or null
     */
    public Options getOptions();
}

/**
 * Exception thrown to abort compilation
 */  
public class AbortException extends RuntimeException {
    /**
     * Create abort exception
     */
    public AbortException();
    
    /**
     * Create abort exception with message
     * @param message Exception message
     */
    public AbortException(String message);
}

Error Handling Examples

Basic Error Listener Implementation:

import com.sun.tools.xjc.api.ErrorListener;
import org.xml.sax.SAXParseException;
import java.util.ArrayList;
import java.util.List;

public class CollectingErrorListener implements ErrorListener {
    private final List<SAXParseException> errors = new ArrayList<>();
    private final List<SAXParseException> warnings = new ArrayList<>();
    private final List<SAXParseException> infos = new ArrayList<>();
    
    @Override
    public void error(SAXParseException exception) {
        errors.add(exception);
        System.err.printf("ERROR [%s:%d:%d] %s%n",
            exception.getSystemId(),
            exception.getLineNumber(),
            exception.getColumnNumber(),
            exception.getMessage());
    }
    
    @Override
    public void warning(SAXParseException exception) {
        warnings.add(exception);
        System.err.printf("WARNING [%s:%d:%d] %s%n",
            exception.getSystemId(),
            exception.getLineNumber(),
            exception.getColumnNumber(),
            exception.getMessage());
    }
    
    @Override
    public void info(SAXParseException exception) {
        infos.add(exception);
        System.out.printf("INFO: %s%n", exception.getMessage());
    }
    
    public boolean hasErrors() {
        return !errors.isEmpty();
    }
    
    public List<SAXParseException> getErrors() {
        return new ArrayList<>(errors);
    }
    
    public List<SAXParseException> getWarnings() {
        return new ArrayList<>(warnings);
    }
}

Custom Error Receiver with Filtering:

import com.sun.tools.xjc.util.ErrorReceiverFilter;
import com.sun.tools.xjc.ErrorReceiver;
import org.xml.sax.SAXParseException;

public class FilteringErrorReceiver extends ErrorReceiverFilter {
    private final Set<String> suppressedWarnings;
    private int errorCount = 0;
    private int warningCount = 0;
    
    public FilteringErrorReceiver(ErrorReceiver core, Set<String> suppressedWarnings) {
        super(core);
        this.suppressedWarnings = suppressedWarnings;
    }
    
    @Override
    public void error(SAXParseException exception) {
        errorCount++;
        super.error(exception);
    }
    
    @Override
    public void warning(SAXParseException exception) {
        // Filter out suppressed warnings
        String message = exception.getMessage().toLowerCase();
        boolean suppressed = suppressedWarnings.stream()
            .anyMatch(pattern -> message.contains(pattern.toLowerCase()));
            
        if (!suppressed) {
            warningCount++;
            super.warning(exception);
        }
    }
    
    @Override
    public void info(SAXParseException exception) {
        // Only show info messages in verbose mode
        if (System.getProperty("xjc.verbose") != null) {
            super.info(exception);
        }
    }
    
    public int getErrorCount() { return errorCount; }
    public int getWarningCount() { return warningCount; }
}

Integration with Logging Frameworks:

import com.sun.tools.xjc.api.ErrorListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.SAXParseException;

public class LoggingErrorListener implements ErrorListener {
    private static final Logger logger = LoggerFactory.getLogger(LoggingErrorListener.class);
    
    @Override
    public void error(SAXParseException exception) {
        logger.error("XJC compilation error at {}:{}:{} - {}",
            exception.getSystemId(),
            exception.getLineNumber(),
            exception.getColumnNumber(),
            exception.getMessage(),
            exception);
    }
    
    @Override
    public void warning(SAXParseException exception) {
        logger.warn("XJC compilation warning at {}:{}:{} - {}",
            exception.getSystemId(),
            exception.getLineNumber(),
            exception.getColumnNumber(),
            exception.getMessage());
    }
    
    @Override
    public void info(SAXParseException exception) {
        logger.info("XJC compilation info: {}", exception.getMessage());
    }
}

Build Tool Integration Error Handling:

import com.sun.tools.xjc.api.ErrorListener;
import org.apache.maven.plugin.logging.Log;
import org.xml.sax.SAXParseException;

public class MavenLogErrorListener implements ErrorListener {
    private final Log log;
    private boolean hasErrors = false;
    
    public MavenLogErrorListener(Log log) {
        this.log = log;
    }
    
    @Override
    public void error(SAXParseException exception) {
        hasErrors = true;
        log.error(String.format("XJC Error [%s:%d:%d]: %s",
            getFileName(exception.getSystemId()),
            exception.getLineNumber(),
            exception.getColumnNumber(),
            exception.getMessage()),
            exception);
    }
    
    @Override
    public void warning(SAXParseException exception) {
        log.warn(String.format("XJC Warning [%s:%d:%d]: %s",
            getFileName(exception.getSystemId()),
            exception.getLineNumber(),
            exception.getColumnNumber(),
            exception.getMessage()));
    }
    
    @Override
    public void info(SAXParseException exception) {
        if (log.isDebugEnabled()) {
            log.debug("XJC Info: " + exception.getMessage());
        }
    }
    
    private String getFileName(String systemId) {
        if (systemId == null) return "unknown";
        int lastSlash = Math.max(systemId.lastIndexOf('/'), systemId.lastIndexOf('\\'));
        return lastSlash >= 0 ? systemId.substring(lastSlash + 1) : systemId;
    }
    
    public boolean hasErrors() {
        return hasErrors;
    }
}

Validation and Schema Processing

Schema Validation Error Handling:

import com.sun.tools.xjc.api.*;
import org.xml.sax.SAXParseException;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.XMLConstants;

public class ValidatingSchemaCompiler {
    
    public static S2JJAXBModel compileWithValidation(File schemaFile) throws Exception {
        // Pre-validate schema before compilation
        SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
        ValidationErrorHandler validationHandler = new ValidationErrorHandler();
        factory.setErrorHandler(validationHandler);
        
        try {
            Schema schema = factory.newSchema(schemaFile);
            System.out.println("Schema validation successful");
        } catch (Exception e) {
            if (validationHandler.hasErrors()) {
                throw new Exception("Schema validation failed with errors", e);
            }
        }
        
        // Proceed with XJC compilation
        SchemaCompiler compiler = XJC.createSchemaCompiler();
        CollectingErrorListener errorListener = new CollectingErrorListener();
        compiler.setErrorListener(errorListener);
        
        compiler.parseSchema(new InputSource(new FileInputStream(schemaFile)));
        S2JJAXBModel model = compiler.bind();
        
        if (errorListener.hasErrors()) {
            throw new Exception("XJC compilation failed with errors");
        }
        
        return model;
    }
    
    private static class ValidationErrorHandler implements org.xml.sax.ErrorHandler {
        private boolean hasErrors = false;
        
        @Override
        public void error(SAXParseException exception) {
            hasErrors = true;
            System.err.println("Validation Error: " + exception.getMessage());
        }
        
        @Override
        public void warning(SAXParseException exception) {
            System.err.println("Validation Warning: " + exception.getMessage());
        }
        
        @Override
        public void fatalError(SAXParseException exception) {
            hasErrors = true;
            System.err.println("Validation Fatal Error: " + exception.getMessage());
        }
        
        public boolean hasErrors() { return hasErrors; }
    }
}

Error Recovery and Reporting

Error Recovery Strategies:

import com.sun.tools.xjc.Driver;
import com.sun.tools.xjc.XJCListener;
import org.xml.sax.SAXParseException;

public class RobustXJCExecution {
    
    public static boolean executeWithRecovery(String[] args) {
        RecoveryListener listener = new RecoveryListener();
        
        try {
            int result = Driver.run(args, listener);
            
            if (result != 0) {
                System.err.println("XJC execution failed with exit code: " + result);
                listener.printSummary();
                return false;
            }
            
            if (listener.hasWarnings()) {
                System.out.println("XJC completed with warnings:");
                listener.printSummary();
            }
            
            return true;
            
        } catch (Exception e) {
            System.err.println("XJC execution failed with exception: " + e.getMessage());
            listener.printSummary();
            return false;
        }
    }
    
    private static class RecoveryListener extends XJCListener {
        private final List<String> errors = new ArrayList<>();
        private final List<String> warnings = new ArrayList<>();
        
        @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 for debugging
        }
        
        @Override
        public void generatedFile(String fileName, int count, int total) {
            System.out.printf("Generated %s (%d/%d)%n", fileName, count, total);
        }
        
        @Override
        public void message(String msg) {
            System.out.println(msg);
        }
        
        private 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());
        }
        
        public boolean hasErrors() { return !errors.isEmpty(); }
        public boolean hasWarnings() { return !warnings.isEmpty(); }
        
        public void printSummary() {
            if (!errors.isEmpty()) {
                System.err.println("\nErrors:");
                errors.forEach(System.err::println);
            }
            
            if (!warnings.isEmpty()) {
                System.err.println("\nWarnings:");
                warnings.forEach(System.err::println);
            }
            
            System.err.printf("\nSummary: %d errors, %d warnings%n", 
                errors.size(), warnings.size());
        }
    }
}

This error handling system provides comprehensive error reporting and validation capabilities, enabling robust integration of XJC into various development workflows and build systems.

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