JAXB marshals XML differently to OutputStream vs. StringWriter
Looks like this might be a "bug" in JAXB. Looking at the source, the calls for marshal() create different writers based on the output/writer type parameter:
public void marshal(Object obj, OutputStream out, NamespaceContext inscopeNamespace) throws JAXBException { write(obj, createWriter(out), new StAXPostInitAction(inscopeNamespace,serializer));}public void marshal(Object obj, XMLStreamWriter writer) throws JAXBException { write(obj, XMLStreamWriterOutput.create(writer,context), new StAXPostInitAction(writer,serializer));}
The implementations of the writers is different with regards to how they handle "empty elements". The above code is from:
jaxb-ri\runtime\src\com\sun\xml\bind\v2\runtime\MarshallerImpl.java.
The two writers you are creating are:
jaxb-ri\runtime\src\com\sun\xml\bind\v2\runtime\output\UTF8XmlOutput.java
jaxb-ri\runtime\src\com\sun\xml\bind\v2\runtime\output\XMLStreamWriterOutput.java
The good news is that JAXB is a specification with more than one implementation (just like JPA). If one implementation is not meeting your needs, others are available such as EclipseLink JAXB (MOXy):
I don't know why JAXB is doing this - or even if it is JAXB - if JAXB is outputting XML via a SAXContentHandler for example, then it has no direct control over how close tags are produced.
To get consistent behaviour, you could wrap your OutputStream in a OutputStreamWriter, e.g.
public void marshal(Marshalable obj, OutputStream os) throws XMLMarshalException { try { marshaller.marshal(obj, new OutputStreamWriter(os, "UTF-8")); } catch (JAXBException jaxbe) { throw new XMLMarshalException(jaxbe); } }
Along the same lines, you might see what happens if you wrap the StringWriter in a PrintWriter. Maybe there is some custom code that detects StringWriter
to tries to keep the output short as possible. Sounds unlikely, but I have no other explanation.