Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8230094

CCE in createXMLEventWriter(Result) over an arbitrary XMLStreamWriter

    XMLWordPrintable

Details

    • 9
    • b12
    • x86_64
    • linux

    Backports

      Description

        ADDITIONAL SYSTEM INFORMATION :
        The "Operating System" dropdown does not have an "OS independent" option. The links given above to the regressed code are in shared, OS-independent class sources.

        A DESCRIPTION OF THE PROBLEM :
        Through Java 8, it is possible to create an XMLEventWriter over an arbitrary class that implements XMLStreamWriter, by wrapping the XMLStreamWriter instance in a StAXResult and using XMLOutputFactory.createXMLEventWriter(Result).

        Starting with Java 9, the same code produces a ClassCastException trying to cast the XMLStreamWriter instance to an inaccessible internal class XMLStreamWriterBase.

        The pre-Java 9 code:
        http://hg.openjdk.java.net/jdk8u/jdk8u/jaxp/file/2b9fdc450085/src/com/sun/xml/internal/stream/writers/XMLEventWriterImpl.java#l59

        The Java 9 and later code:
        http://hg.openjdk.java.net/jdk9/jdk9/jaxp/file/364631d8ff2e/src/java.xml/share/classes/com/sun/xml/internal/stream/writers/XMLEventWriterImpl.java#l62

        REGRESSION : Last worked in version 8u201

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        Compile the attached source code with javac and run it with

        java EventWriterOverStreamWriter

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        Successful exit with no output
        ACTUAL -
        Exception in thread "main" java.lang.ClassCastException: class EventWriterOverStreamWriter$StreamWriterFilter cannot be cast to class com.sun.xml.internal.stream.writers.XMLStreamWriterBase (EventWriterOverStreamWriter$StreamWriterFilter is in unnamed module of loader 'app'; com.sun.xml.internal.stream.writers.XMLStreamWriterBase is in module java.xml of loader 'bootstrap')
        at java.xml/com.sun.xml.internal.stream.writers.XMLEventWriterImpl.<init>(XMLEventWriterImpl.java:62)
        at java.xml/com.sun.xml.internal.stream.XMLOutputFactoryImpl.createXMLEventWriter(XMLOutputFactoryImpl.java:83)
        at EventWriterOverStreamWriter.main(EventWriterOverStreamWriter.java:15)

        ---------- BEGIN SOURCE ----------
        import javax.xml.namespace.NamespaceContext;

        import javax.xml.stream.XMLOutputFactory;
        import javax.xml.stream.XMLEventWriter;
        import javax.xml.stream.XMLStreamWriter;
        import javax.xml.stream.XMLStreamException;

        import javax.xml.transform.stax.StAXResult;

        public class EventWriterOverStreamWriter
        {
          public static void main(String[] args) throws XMLStreamException
          {
            XMLOutputFactory.newFactory()
              .createXMLEventWriter(new StAXResult(new StreamWriterFilter()));
          }

          static class StreamWriterFilter implements XMLStreamWriter
          {
            @Override
            public void writeStartElement(String localName)
              throws XMLStreamException
            {
            }

            @Override
            public void writeStartElement(String namespaceURI, String localName)
              throws XMLStreamException
            {
            }

            @Override
            public void writeStartElement(
              String prefix, String localName, String namespaceURI)
              throws XMLStreamException
            {
            }

            @Override
            public void writeEmptyElement(String namespaceURI, String localName)
              throws XMLStreamException
            {
            }

            @Override
            public void writeEmptyElement(
              String prefix, String localName, String namespaceURI)
              throws XMLStreamException
            {
            }

            @Override
            public void writeEmptyElement(String localName)
              throws XMLStreamException
            {
            }

            @Override
            public void writeEndElement() throws XMLStreamException
            {
            }

            @Override
            public void writeEndDocument() throws XMLStreamException
            {
            }

            @Override
            public void close() throws XMLStreamException
            {
            }

            @Override
            public void flush() throws XMLStreamException
            {
            }

            @Override
            public void writeAttribute(String localName, String value)
              throws XMLStreamException
            {
            }

            @Override
            public void writeAttribute(
              String prefix, String namespaceURI, String localName, String value)
              throws XMLStreamException
            {
            }

            @Override
            public void writeAttribute(
              String namespaceURI, String localName, String value)
              throws XMLStreamException
            {
            }

            @Override
            public void writeNamespace(String prefix, String namespaceURI)
              throws XMLStreamException
            {
            }

            @Override
            public void writeDefaultNamespace(String namespaceURI)
              throws XMLStreamException
            {
            }

            @Override
            public void writeComment(String data) throws XMLStreamException
            {
            }

            @Override
            public void writeProcessingInstruction(String target)
              throws XMLStreamException
            {
            }

            @Override
            public void writeProcessingInstruction(String target, String data)
              throws XMLStreamException
            {
            }

            @Override
            public void writeCData(String data) throws XMLStreamException
            {
            }

            @Override
            public void writeDTD(String dtd) throws XMLStreamException
            {
            }

            @Override
            public void writeEntityRef(String name) throws XMLStreamException
            {
            }

            @Override
            public void writeStartDocument() throws XMLStreamException
            {
            }

            @Override
            public void writeStartDocument(String version) throws XMLStreamException
            {
            }

            @Override
            public void writeStartDocument(String encoding, String version)
              throws XMLStreamException
            {
            }

            @Override
            public void writeCharacters(String text) throws XMLStreamException
            {
            }

            @Override
            public void writeCharacters(char[] text, int start, int len)
              throws XMLStreamException
            {
            }

            @Override
            public String getPrefix(String uri) throws XMLStreamException
            {
              return null;
            }

            @Override
            public void setPrefix(String prefix, String uri)
              throws XMLStreamException
            {
            }

            @Override
            public void setDefaultNamespace(String uri) throws XMLStreamException
            {
            }

            @Override
            public void setNamespaceContext(NamespaceContext context)
              throws XMLStreamException
            {
            }

            @Override
            public NamespaceContext getNamespaceContext()
            {
              throw new UnsupportedOperationException();
            }

            @Override
            public Object getProperty(String name) throws IllegalArgumentException
            {
              throw new UnsupportedOperationException();
            }
          }
        }

        ---------- END SOURCE ----------

        CUSTOMER SUBMITTED WORKAROUND :
        None as far as I know, other than for the application developer to bundle a complete reimplementation of the pre-Java 9 XMLEventWriterImpl logic when writing to an XMLStreamWriter instance.

        Even after the regression is fixed, developers will have to bundle the duplicated code in order to support non-updated platforms. It might be appropriate for the project to consider making a version of that class's source code available under a nonrestrictive license.

        FREQUENCY : always


        Attachments

          Issue Links

            Activity

              People

                joehw Joe Wang
                webbuggrp Webbug Group
                Votes:
                0 Vote for this issue
                Watchers:
                4 Start watching this issue

                Dates

                  Created:
                  Updated:
                  Resolved: