A suite of extensible XJC (JAXB) plugins designed to streamline XML-to-Java binding, customize generated code structures, and eliminate boilerplate in modern Java projects (Java 21+).
- Modern Standards: Full support for Java 21+ and
java.time(JSR-310) date/time API mapping. - Flexible Configuration: Supports compact inline mappings (
pattern->replacement) and structured nested CLI flags. - Boilerplate Reduction: Direct Lombok integration (
-Xlombok), automated wrapper class flattening (-Xelement-wrapper), and getter/setter removal. - Fine-Grained Customization: Comprehensive annotation injection/removal, custom naming transformations, and namespace/prefix management.
Maps XSD date and time types to modern java.time (JSR-310) classes.
- Timezone-aware date/time handling (
OffsetDateTime,OffsetTime). - Timezone-tolerant unmarshalling (automatically falls back to system local offset if timezone is omitted in XML).
- Custom formatting patterns.
- Automated
XmlAdaptergeneration (derived from common package prefixes).
-Xjsr310 \
-type-mapping \
-xsd-type=dateTime \
-target-type=java.time.OffsetDateTime-Xjsr310 \
-adapter-package=package.name \ # Optional: defaults to <common_package>.adapter
-type-mapping \ # Group marker
-xsd-type=xsdType \
-target-type=java.time.Class \
-format=dateFormat \
-adapter=custom.AdapterClass \
-field=fieldPattern \
-xsd-type=anotherType \ # Repeated child field starts next item
-target-type=java.time.LocalDate| XSD Type | Java Target Type | Notes |
|---|---|---|
xs:dateTime |
java.time.OffsetDateTime |
Timezone-tolerant |
xs:date |
java.time.LocalDate |
ISO_DATE |
xs:time |
java.time.OffsetTime |
Timezone-tolerant |
xs:gYearMonth |
java.time.YearMonth |
|
xs:gYear |
java.time.Year |
|
xs:gMonthDay |
java.time.MonthDay |
|
xs:gDay |
java.lang.Integer |
|
xs:gMonth |
java.time.Month |
|
xs:duration |
java.time.Duration |
Adds, removes, or modifies annotations on generated classes, fields, methods, and package metadata.
- Inject JSON binding annotations (e.g., Jackson
@JsonProperty). - Add Jakarta validation constraints (
@NotNull,@Size). - Attach framework-specific metadata.
- Strip unwanted JAXB-generated annotations.
-Xannotate \
-add-to-class \
-anno=@com.example.MyAnnotation \
-target=.*Person \
-add-to-field \
-anno=@com.fasterxml.jackson.annotation.JsonProperty("value") \
-target=.*name-Xannotate \
-add-to-class \ # Target kind: class
-anno=@AnnotationClass(param="value") \
-target=pattern \
-add-to-field \ # Target kind: field
-anno=@AnnotationClass(param="value") \
-target=pattern \
-remove-from-class|-remove-from-field|-remove-from-method|-remove-from-package \
-anno=AnnotationClass \
-target=patternCustomizes how XJC maps XML element names to Java identifiers (class names, field names, method names, and package names).
- Convert
snake_caseXML definitions intocamelCaseJava properties. - Apply regular expression replacements to auto-generated class/variable names.
- Resolve conflicts with legacy naming conventions.
-Xconvert-name \
-class-name=XMLDocument->Document \
-variable-name \
-name=(.*)_ID \
-to=$1Id-Xconvert-name \
# Compact format:
-class-name=originalName->newName \
-class-name=/(.*)_ID/->$1Id \
-package-name=http://example.com/a->com.example.a \
# Structured format:
-variable-name \
-name=(.*)_ID \
-to=$1Id \
# Or exact match on original NameConverter input:
-class-name \
-input=Person \
-to=CustomPersonFlattens XML collection wrapper elements by moving @XmlElementWrapper and @XmlElement annotations directly to the collection field and optionally deleting unnecessary wrapper classes.
- Removes redundant wrapper DTO classes.
- Simplifies object graphs and cleans up API signatures.
-Xelement-wrapper \
-remove-wrapper-class=truePromotes nested static classes and enums toward package scope level by level, stopping automatically upon name collisions.
- Un-nests deeply scoped anonymous complex types and local enums.
- Avoids unsafe renames by respecting namespace boundaries.
- Executes during the
postProcessModelphase.
-Xpromote-nested-classCustomizes Java package names and XML namespace prefixes for XML namespaces.
Replaces the former -Xns-prefix plugin.
- Explicit Java package mapping per XML target namespace URI.
- Optional XML prefix on
@XmlSchemafor that namespace. - Package-scoped multi-
xmlnsprefix mappings with optional Java package regex filter. - Package bindings use
schemaLocation="*"and match bytargetNamespace(CLI schema order independent).
-Xnamespace \
-package-mapping \
-ns=http://example.com/schema \
-package=com.example.schema \
-prefix=ex-Xnamespace \
# Compact package mapping:
-package-mapping=namespaceURI->java.package.name \
-package-mapping=namespaceURI->java.package.name:xmlPrefix \
# Structured package mapping (+ optional xmlns set for that package):
-package-mapping \
-ns=namespaceURI \
-package=java.package.name \
-prefix=xmlPrefix \
-xmlns=http://other.example.com->ot \
-xmlns \
-ns=http://third.example.com \
-prefix=th \
# Prefix-only / multi-xmlns without package mapping (optional package filter):
-ns-prefix \
-package=com\.example\.* \
-xmlns=namespaceURI->xmlPrefix \
-xmlns \
-ns=http://other.example.com \
-prefix=otGenerates Lombok-annotated beans and strips default XJC getters/setters. Replaces hand-crafted -Xannotate + -Xremove-getter + -Xremove-setter pipelines.
- Replaces getter/setter boilerplate with
@Data. - Supports optional
@Builderpattern generation. - Automatically handles
@EqualsAndHashCode(callSuper = true)for non-Objectsubclasses.
-Xlombok-Xlombok \
-anno=@lombok.Data \ # Repeatable; defaults to @Data
-class-name=.*Person \ # Optional class filter
-remove-getter=true \ # Default: true
-remove-setter=true \ # Default: true
-builder # Default: false; adds @Builder + @NoArgsConstructor + @AllArgsConstructorNote: Lombok dependencies must be present on both the XJC classpath (for annotation resolution) and compile classpath.
Removes property getter methods generated by XJC (matched against the property model rather than raw method names).
-Xremove-getterRemoves property setter methods generated by XJC to create read-only DTOs and enforce immutability.
-Xremove-setterFlattens multi-element properties (such as @XmlElements choice groups or @XmlElementRefs) into individual single-element fields.
- Splits heterogenous multi-element collection properties into distinct fields per element type.
- Preserves relative field order in generated classes.
-Xflatten-multi-element-propAdds @jakarta.annotation.Generated annotations to generated classes and package-info files.
- Automatically decorates generated classes with standard
@Generatedmarkers. - Supports optional generation date timestamp and custom comments.
-Xgenerated-anno \
-value="JAXB Generator" \
-comments="Auto-generated file" \
-date=trueRenames generated classes, enums, and element classes post-model building with simulated conflict detection.
- Rewrites short class names using regex replacement patterns.
- Safe execution: detects squeezed name collisions and rolls back conflicting renames with build warnings.
-Xrename-class \
-mapping=/(.*)Type/->$1 \
-mapping=Person->CustomPersonRenames multi-element properties produced by XJC to a short plural base name (e.g. items, items2).
- Replaces verbose generated property names (like
restorcontent) with clean plural naming conventions.
-Xrename-multi-element-prop \
-name=elementsAdd the plugin dependency to your project:
<dependency>
<groupId>io.github.rawvoid</groupId>
<artifactId>jaxb-plugins</artifactId>
<version>${latest-version}</version>
</dependency>Configure jaxb-maven-plugin with desired plugin arguments:
<plugin>
<groupId>org.jvnet.jaxb</groupId>
<artifactId>jaxb-maven-plugin</artifactId>
<version>4.0.12</version>
<configuration>
<plugins>
<plugin>
<groupId>io.github.rawvoid</groupId>
<artifactId>jaxb-plugins</artifactId>
<version>${latest-version}</version>
</plugin>
</plugins>
<args>
<arg>-Xjsr310</arg>
<arg>-Xannotate</arg>
<arg>-Xconvert-name</arg>
<arg>-Xnamespace</arg>
</args>
</configuration>
</plugin>xjc -d src -p com.example \
-extension \
-Xjsr310 \
-Xannotate \
-Xconvert-name \
-Xnamespace \
schema.xsdxjc schema.xsd \
-d src/main/java \
-p com.example.api \
-extension \
-Xjsr310 \
-adapter-package=com.example.adapters \
-type-mapping \
-xsd-type=dateTime \
-target-type=java.time.LocalDateTime \
-Xannotate \
-add-to-class \
-anno=@com.fasterxml.jackson.annotation.JsonInclude(JsonInclude.Include.NON_NULL) \
-add-to-field \
-anno=@com.fasterxml.jackson.annotation.JsonProperty("value") \
-target=.*\.value \
-Xconvert-name \
-class-name \
-name=(.*)Type \
-to=$1DTO \
-variable-name \
-name=(.*)_ID \
-to=$1Id \
-Xnamespace \
-package-mapping \
-ns=http://api.example.com \
-package=com.example.apixjc schema.xsd \
-d src/main/java \
-p com.example.domain \
-extension \
-Xlombok \
-builder \
-anno=@lombok.Data \
-anno=@lombok.experimental.Accessors(chain = true)- JDK 21+
- Apache Maven 3.6+
git clone https://github.com/rawvoid/jaxb-plugins.git
cd jaxb-plugins
mvn clean installContributions are welcome! Please follow these steps:
- Fork the repository.
- Create a feature branch (
git checkout -b feat/new-plugin-feature). - Commit your changes using Conventional Commits format (
git commit -m 'feat(plugin): add feature X'). - Push to your branch (
git push origin feat/new-plugin-feature). - Submit a Pull Request.
Distributed under the Apache License 2.0. See LICENSE for details.