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

  1. Inspect the chained JAXBException cause for the real problem and fix the annotated classes accordingly.
  2. Ensure all classes passed to JAXBCoder/XMLIO are valid JAXB-annotated classes.
  3. On Java 11+, add an explicit JAXB implementation dependency (e.g. org.glassfish.jaxb:jaxb-runtime) and align versions.
  4. 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

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


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)