JDK-7150637 : No newline emitted after XML decl in XSLT output
  • Type: Bug
  • Component: xml
  • Sub-Component: javax.xml.transform
  • Affected Version: 7,7u4
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: linux,linux_ubuntu
  • CPU: x86
  • Submitted: 2012-03-02
  • Updated: 2014-08-21
  • Resolved: 2012-04-06
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availabitlity Release.

To download the current JDK release, click here.
JDK 7
7u4 b18Fixed
Related Reports
Duplicate :  
Relates :  
Relates :  
Description
Test program:

---%<---
import java.io.StringReader;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
public class JAXP7u4Regression {
    public static void main(String[] args) throws Exception {
        String data =
            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
            "<r>\n" +
            "    <e/>\n" +
            "</r>\n";
        Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(new StringReader(data)));
        TransformerFactory tf = TransformerFactory.newInstance();
        String IDENTITY_XSLT_WITH_INDENT = // #5064280 workaround
            "<xsl:stylesheet version='1.0' " +
            "xmlns:xsl='http://www.w3.org/1999/XSL/Transform' " +
            "xmlns:xalan='http://xml.apache.org/xslt' " +
            "exclude-result-prefixes='xalan'>" +
            "<xsl:output method='xml' indent='yes' xalan:indent-amount='4'/>" +
            "<xsl:template match='@*|node()'>" +
            "<xsl:copy>" +
            "<xsl:apply-templates select='@*|node()'/>" +
            "</xsl:copy>" +
            "</xsl:template>" +
            "</xsl:stylesheet>";
        Transformer t = tf.newTransformer(new StreamSource(new StringReader(IDENTITY_XSLT_WITH_INDENT)));
        t.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
        Source source = new DOMSource(doc);
        Result result = new StreamResult(System.out);
        t.transform(source, result);
    }
    private JAXP7u4Regression() {}
}
---%<---

Output in 7u3  (b04; Ubuntu, 32-bit JVM):

<?xml version="1.0" encoding="UTF-8"?>
<r>
    <e/>
</r>

vs. 7u4 (b14):

<?xml version="1.0" encoding="UTF-8"?><r>
    <e/>
</r>

Note the missing newline between the XML declaration and the root element.

Comments
EVALUATION This is an issue introduced by an Apache update that although technically correct, was nonetheless an incompatible change. As reported in the CR, it caused NetBeans test failures and spurious reformatting of project metadata of users' projects that the version control tool would take as if there were real changes. The incompatible behavior would more than likely cause many problems to users' applications. This patch adds an implementation specific property that can be used to essentially neutralize the Apache change to bring back the original behavior. It has been tested to have resolved the NetBeans issue with minimal effort in the NetBeans' part. The use is: static final String ORACLE_IS_STANDALONE = "http://www.oracle.com/xml/is-standalone"; //catch IllegalArgumentException when running with previous releases try { transformer.setOutputProperty(ORACLE_IS_STANDALONE, "yes"); } catch (IllegalArgumentException e) { //expected for previous releases }
2012-04-06

EVALUATION Yes, it was an update to Apache Xalan 2.7.1.
2012-03-02

PUBLIC COMMENTS Originally discovered as https://netbeans.org/bugzilla/show_bug.cgi?id=208909 Utility code encountering the problem: https://hg.netbeans.org/releases/raw-file/release71_fixes_base/openide.util/src/org/openide/xml/XMLUtil.java and its unit tests https://hg.netbeans.org/releases/raw-file/release71_fixes_base/openide.util/test/unit/src/org/openide/xml/XMLUtilTest.java
2012-03-02

WORK AROUND No simple workaround (not regressing other details checked by XMLUtilTest) yet known. Using simply Transformer t = tf.newTransformer(); without the special identity transformer behaves poorly even on earlier versions of JAXP, hence the #5064280 workaround. Using DOM 3 L&S DOMImplementationLS ls = (DOMImplementationLS) doc.getImplementation().getFeature("LS", "3.0"); LSSerializer ser = ls.createLSSerializer(); ser.getDomConfig().setParameter("format-pretty-print", true); LSOutput out = ls.createLSOutput(); out.setByteStream(System.out); ser.write(doc, out); works nicely in this case but fails in some more advanced cases, such as comments between the XML declaration and the root element.
2012-03-02

EVALUATION Presumably caused by some aspect of the JAXP upgrade (d9891683fc16 & 4a61ac055189).
2012-03-02