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:
Define a custom
StreamWriter2Delegate
, overridewriteEntityRef()
, 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).
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