apache/beam · error · RuntimeException
Error when creating marshaller from JAXB Context.
Error message
Error when creating marshaller from JAXB Context.
What it means
JAXBCoder lazily creates a thread-local JAXB Marshaller for XML serialization. If JAXBContext.createMarshaller() throws a JAXBException (bad context configuration, invalid class setup), the ThreadLocal initialValue wraps it in this RuntimeException. It indicates the coder cannot produce a marshaller and XML writes will fail.
Solutions
- Inspect the chained JAXBException cause for the real problem and fix the annotated classes accordingly.
- Ensure all classes passed to JAXBCoder/XMLIO are valid JAXB-annotated classes.
- On Java 11+, add an explicit JAXB implementation dependency (e.g. org.glassfish.jaxb:jaxb-runtime) and align versions.
- Test JAXBContext.newInstance(recordClass).createMarshaller() in isolation to reproduce and diagnose.
Example fix
// before: class without JAXB annotations passed to coder
Coder<MyPojo> coder = Jaxbcoder.of(MyPojo.class);
// after
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class MyPojo { ... } Defensive patterns
Strategy: try-catch
Validate before calling
try ( Marshaller unused = JAXBContext.newInstance(recordClass).createMarshaller() ) { /* ok */ } catch (JAXBException e) { throw new IllegalStateException("Record class not JAXB-marshalable", e); } Try / catch
try { coder = Jaxbcoder.of(Record.class); } catch (RuntimeException e) { throw new IllegalStateException("JAXB marshaller setup failed: " + e.getCause(), e); } Prevention
- Annotate all record classes with @XmlRootElement and @XmlAccessorType(FIELD).
- Include jaxb-runtime in the pipeline fat jar when using Java 11+.
- Smoke-test JAXBContext creation in a unit test before deploying pipelines.
When it happens
Trigger: Constructing a JAXBCoder whose JAXBContext was built from classes that are not properly JAXB-annotated or whose context fails, then attempting to encode an element, which triggers the ThreadLocal's initialValue.
Common situations: Annotating POJOs incorrectly for JAXB, missing @XmlRootElement/@XmlAccessorType annotations, mixing JAXB implementations after Java 11 removal of javax.xml.bind from the JDK, or conflicting JAXB versions on the classpath.
Understand the failure class
Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.
Related errors
- Error binding classes to a JAXB Context.
- Error when creating unmarshaller from JAXB Context.
- at key is not supported
- A function must be provided to convert the input type into…
- A PValue contained in
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/25341f68288eec22.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/io/xml/src/main/java/org/apache/beam/sdk/io/xml/JAXBCoder.java:73
private transient volatile XMLInputFactory xmlInputFactory;
private final EmptyOnDeserializationThreadLocal<Marshaller> jaxbMarshaller;
private final EmptyOnDeserializationThreadLocal<Unmarshaller> jaxbUnmarshaller;
public Class<T> getJAXBClass() {
return jaxbClass;
}
private JAXBCoder(Class<T> jaxbClass) {
this.jaxbClass = jaxbClass;
this.jaxbMarshaller =
new EmptyOnDeserializationThreadLocal<Marshaller>() {
@Override
protected Marshaller initialValue() {
try {
JAXBContext jaxbContext = getContext();
return jaxbContext.createMarshaller();
} catch (JAXBException e) {
throw new RuntimeException("Error when creating marshaller from JAXB Context.", e);
}
}
};
this.jaxbUnmarshaller =
new EmptyOnDeserializationThreadLocal<Unmarshaller>() {
@Override
protected Unmarshaller initialValue() {
try {
JAXBContext jaxbContext = getContext();
return jaxbContext.createUnmarshaller();
} catch (Exception e) {
throw new RuntimeException("Error when creating unmarshaller from JAXB Context.", e);
}
}
};
}
/**View on GitHub (pinned to 12126d8942)