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
|