leaqui leaqui - 2 months ago 12x
Java Question

Is SAAJ compatible with MTOM + XOP?

I´m trying to use MTOM + XOP to return a byte[] in a Spring Web Service but when marshalling result it throws a SAXParseException with message:

cvc-type.3.1.2: Element 'dataHandler' is a simple type, so it must have no element information item [children].

It seems that after writing XOP tag, validator meet with it instead of the byte[] content that it expects and throws a SAXParseException with FATAL level that stops the process.

I´m using:

  • JDK 1.7

  • SAAJ 1.3

  • SOAP 1.1

  • Spring 4.1.4.RELEASE

  • Spring WS 2.2.0.RELEASE

Thanks in advance


I´ve found two workarounds for my situation:

  1. Not setting the xmlschema to marshaller.

  2. Setting a ValidationEventHandler to marshaller that skips XOP failures.

This is an example of setting a ValidationEventHandler to marshaller that skips XOP failures:

Abstract superclass:

import javax.xml.bind.ValidationEvent;
import javax.xml.bind.ValidationEventHandler;

abstract class XopAwareValidationEventHandler implements ValidationEventHandler {

  private static final String CVC_TYPE_3_1_2 = "cvc-type.3.1.2";

  private ValidationEventHandler realHandler;

  XopAwareValidationEventHandler(final ValidationEventHandler handler) {

  public boolean handleEvent(final ValidationEvent event) {
    final boolean result = this.getRealHandler().handleEvent(event);
    if (!result) {
      if (event.getMessage() != null && event.getMessage().startsWith(CVC_TYPE_3_1_2)) {
        if (this.isXopEvent(event)) {
          return true;
    return result;

  abstract boolean isXopEvent(ValidationEvent validationEvent);

  private ValidationEventHandler getRealHandler() {
    return realHandler;

  private void setRealHandler(final ValidationEventHandler realHandler) {
    this.realHandler = realHandler;

Concrete class for unmarshaller:

import javax.xml.bind.ValidationEvent;
import javax.xml.bind.ValidationEventHandler;

class XopAwareUnmarshallingValidationEventHandler extends XopAwareValidationEventHandler {

  private static final String XOP_INCLUDE = "xop:Include";

  XopAwareUnmarshallingValidationEventHandler(final ValidationEventHandler handler) {

  boolean isXopEvent(final ValidationEvent validationEvent) {
    final ValidationEventLocator locator = validationEvent.getLocator();
    return locator != null && locator.getNode() != null &&
        locator.getNode().getFirstChild() != null &&

For marshaller I´m searching for the condition that identifies the case, because the ValidationEventLocator only have the Object set and it could be whatever.