apache/beam · error · RuntimeException

Error binding classes to a JAXB Context.

Error message

Error binding classes to a JAXB Context.

What it means

XmlIO's expand() validates at pipeline-construction time that the configured record class can be bound to a JAXBContext by calling JAXBContext.newInstance(getRecordClass()). If the class is not a valid JAXB type (missing annotations, invalid mappings), the JAXBException is rethrown as this RuntimeException, failing pipeline construction early instead of failing later during execution.

Solutions

  1. Annotate the record class correctly (@XmlRootElement, @XmlAccessorType) so JAXB can bind it.
  2. Run JAXBContext.newInstance(recordClass) locally to see the underlying JAXBException detail.
  3. Replace unsupported field types in the record class with JAXB-compatible types.
  4. Ensure a JAXB implementation is on the runtime classpath on Java 11+.

Example fix

// before
public class Record { public String name; }
// after
@XmlRootElement(name = "record")
@XmlAccessorType(XmlAccessType.FIELD)
public class Record { public String name; }
Defensive patterns

Strategy: validation

Validate before calling

try { JAXBContext.newInstance(Record.class); } catch (JAXBException e) { throw new IllegalArgumentException("Record class cannot be bound to JAXB: " + Record.class, e); }

Type guard

boolean isJaxbBindable(Class<?> c) { try { JAXBContext.newInstance(c); return true; } catch (JAXBException e) { return false; } }

Try / catch

try { result = input.apply(XmlIO.<Record>write().withRecordClass(Record.class)...); } catch (RuntimeException e) { LOG.error("XmlIO record class invalid: {}", e.getMessage(), e); throw e; }

Prevention

When it happens

Trigger: Calling XmlIO.<T>write()/read().withRecordClass(SomeClass.class).expand(input) where SomeClass cannot be bound by JAXB (e.g. no @XmlRootElement or unsupported field types).

Common situations: Users passing plain POJOs without JAXB annotations; switching record classes after upgrading JAXB versions; typos resulting in the wrong record class.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/e7d82e1d81f0397a. Report an issue: GitHub.

Appendix: source

Thrown at sdks/java/io/xml/src/main/java/org/apache/beam/sdk/io/xml/XmlIO.java:529

    public Write<T> withRootElement(String rootElement) {
      return toBuilder().setRootElement(rootElement).build();
    }

    /** Sets the charset used to write the file. */
    public Write<T> withCharset(Charset charset) {
      return toBuilder().setCharset(charset.name()).build();
    }

    @Override
    public PDone expand(PCollection<T> input) {
      checkArgument(getRecordClass() != null, "withRecordClass() is required");
      checkArgument(getRootElement() != null, "withRootElement() is required");
      checkArgument(getFilenamePrefix() != null, "to() is required");
      checkArgument(getCharset() != null, "withCharset() is required");
      try {
        JAXBContext.newInstance(getRecordClass());
      } catch (JAXBException e) {
        throw new RuntimeException("Error binding classes to a JAXB Context.", e);
      }

      ResourceId prefix =
          FileSystems.matchNewResource(getFilenamePrefix(), false /* isDirectory */);
      input.apply(
          FileIO.<T>write()
              .via(
                  sink(getRecordClass())
                      .withCharset(Charset.forName(getCharset()))
                      .withRootElement(getRootElement()))
              .to(prefix.getCurrentDirectory().toString())
              .withPrefix(prefix.getFilename())
              .withSuffix(".xml")
              .withIgnoreWindowing());
      return PDone.in(input.getPipeline());
    }

    @Override

View on GitHub (pinned to 12126d8942)