Latest Open JDK 8 JAXB library fails to unmarshal objects with properties that contain new line characters

In my case, I'm using JAXB to convert a few objects into XML and serialise them to a file, via StAX/WoodStox. I've managed to fix the problem at issue by filtering the XML that is being serialised. In detail, the approach is like:

  1. Define a custom StreamWriter2Delegate, override writeEntityRef(), so that, when this method receives the wrong entity code (#xd or #xa), it invokes its delegate to actually write back the original character (i.e., \n or \r), which doesn't actually need to be escaped:

    @Override
    public void writeEntityRef ( String eref ) throws XMLStreamException
    {
        if ( eref == null || !eref.startsWith ( "#x" ) ) {
            super.writeEntityRef ( eref );
            return;
        }
        String hex = eref.substring ( 2 );
        for ( char c: new char[] { '\r', '\n' } )
            if ( Integer.toHexString ( c ).equals ( hex ) ) {
                this.writeCharacters ( Character.toString ( c ) );
                return;
        }
        super.writeEntityRef ( eref );
    }
    

This is equivalent (apart from some overhead) to the fix they've already filed for this problem, which should be available with JDK8u192 (and should already be in JDK 9/10).

  1. Wrap your XMLStreamWriter2 with the above filter, for instance:

    FileOutputStream fout = new FileOutputStream ( "test.xml" );
    WstxOutputFactory wsof = (WstxOutputFactory) WstxOutputFactory.newInstance();
    XMLStreamWriter2 xmlOut = (XMLStreamWriter2) wsof.createXMLStreamWriter ( fout, CharsetNames.CS_UTF8 );
    xmlOut = new NewLineFixWriterFilter ( xmlOut );
    // Now write into xmlOut, directly or via JAXB
    

The complete/production code is here. It shouldn't be difficult to adapt the same approach to similar pipelines (in general, the problem occurs because com.sun.xml.internal.bind.v2.runtime.output.XMLStreamWriterOutput escapes \n and \r the wrong way, so the trick is to hijack this wrong encoding from the upper levels).


Geoff S,

I tried to comment on the existing post but I quickly found out that you need to have “50 reputations” which I do not have.

It appears that I am experiencing a similar issue when we moved to JDK 1.8.0_161 and 1.8.0_162 some of our SOAP services started throwing the exceptions below

Feb 28, 2018 8:34:12 AM com.sun.xml.internal.messaging.saaj.soap.SOAPDocumentImpl createEntityReference
SEVERE: SAAJ0543: Entity References are not allowed in SOAP documents
SEVERE: java.lang.UnsupportedOperationException: Entity References are not allowed in SOAP documents
javax.xml.ws.WebServiceException: java.lang.UnsupportedOperationException: Entity References are not allowed in SOAP documents
    at com.sun.xml.internal.ws.handler.ClientSOAPHandlerTube.callHandlersOnRequest(ClientSOAPHandlerTube.java:135)
    at com.sun.xml.internal.ws.handler.HandlerTube.processRequest(HandlerTube.java:112)
    at com.sun.xml.internal.ws.api.pipe.Fiber.__doRun(Fiber.java:1121)
    at com.sun.xml.internal.ws.api.pipe.Fiber._doRun(Fiber.java:1035)
    at com.sun.xml.internal.ws.api.pipe.Fiber.doRun(Fiber.java:1004)
    at com.sun.xml.internal.ws.api.pipe.Fiber.runSync(Fiber.java:862)
    at com.sun.xml.internal.ws.client.Stub.process(Stub.java:448)
    at com.sun.xml.internal.ws.client.sei.SEIStub.doProcess(SEIStub.java:178)
    at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:93)
    at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:77)
    at com.sun.xml.internal.ws.client.sei.SEIStub.invoke(SEIStub.java:147)
    at com.sun.proxy.$Proxy38.getUserProfile(Unknown Source)

As indicated by the above question and other threads:

  • https://bugs.openjdk.java.net/browse/JDK-8196491
  • https://bugs.java.com/view_bug.do?bug_id=8196491

It has something to do with newlines in the payload. For example some of our payloads include XML strings that have new lines which cause the issue. however if the newlines are removed prior to calling the service then it works. See immediately below:

Fail

<?xml version="1.0" encoding="UTF-8"?>
<user>
<userId>XXXX</userId>
<name>XXXXXX, XXXXXX</name>
<phone>(xxx)xxx-xxxx</phone>
<title><![CDATA[MY TITLE]]></title>
<mail>[email protected]</mail>
</user>

Works

<?xml version="1.0" encoding="UTF-8"?><user><userId>XXXX</userId><name>XXXXXX, XXXXXX</name><phone>(xxx)xxx-xxxx</phone><title><![CDATA[MY TITLE]]></title><mail>[email protected]</mail></user>

Do you or anyone else know if there is workaround other than stripping the payload from “new lines”, and is this considered a bug in the latest Oracle JDK and are there any plans to rectify the behavior.

Thanks

max