Project

Profile

Help

Stax2 exception wrapping BuildingStreamWriter

Added by David Lee over 9 years ago

I ran across an unexpected issue today. I think Saxon is the correct implementation but that doesnt help much with interop. I'm using Saxon HE and PE "9.4.0.3" I am using Woodstox Stax for implementation.

I have succesffuly used this code snippet before to get a XMLStreamWriter interface to a builder.

		Processor proc = ... cached processor
		BuildingStreamWriter bw = proc.newDocumentBuilder().newBuildingStreamWriter();

Today I am experimenting integrating with Jackson XML mapping ... One method (the first I picked of course) expects an XMLStreamWriter, so I used the above code and called it.

Early on it ends up using org.codehaus.stax2.ri.Stax2WriterAdapter() to create a wrapper/delegate to a Stax2 writer. Jacksons code snippit is like this; _xmlWriter = Stax2WriterAdapter.wrapIfNecessary(sw);

Which in Jackson tests if its a an instance of XMLStreamWriter2 and if not creates the adaptor. The constructor is :

protected Stax2WriterAdapter(XMLStreamWriter sw)
{
    super(sw);
    mDelegate = sw;
    Object value = sw.getProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES);            //////////  HERE LIES DRAGONS
    mNsRepairing = (value instanceof Boolean) && ((Boolean) value).booleanValue();
}

This calls net.sf.saxon.event.StreamWriterToReceiver public Object getProperty(String name) throws IllegalArgumentException { throw new IllegalArgumentException(name); }

Boom.

The docs I can find for XMLStreamWriter2 say that your implemention is correct ... thow an exception. But well ... specs and reality ... I loose :(

I "solved" this by writing yet another layer of adaptor delegate which just returns a null and it seems to work.

My questions are:

  1. Have you run into this issue before, and if so how did you solve it
  2. Any recomendations on a better way to solve it (yes, the right way is to nag the authors of Woodstox, which I will .. )
  3. Might a newer version of Saxon magically make the problem go away ? - maybe with support for a XMLStreamWriter2 interface ?

Thanks for any suggestions.

-David


Replies (2)

RE: Stax2 exception wrapping BuildingStreamWriter - Added by Michael Kay over 9 years ago

I think Saxon is the correct implementation but that doesnt help much with interop.

That's not an uncommon state of affairs. As a general principle (which sometimes has to be set to one side) I don't compromise conformance in order to interoperate with non-conformant products; doing so usually causes grief in the end. Usually it's possible to work around the situation by inserting some glue to bridge the gap, and that appears to be what you have done. I think it's the right approach.

I don't have any plans to implement the XMLStreamWriter2 interface. An aspiration that has been on the back burner for a long while is to attempt a closer integration between Saxon and Woodstox. Our recent efforts on XSLT benchmarking published at XML London 2014 show many transformations are limited by parser speed, so this seems the best prospect for getting a few more percentage points of performance improvement. That might or might not mean using such interfaces.

RE: Stax2 exception wrapping BuildingStreamWriter - Added by David Lee over 9 years ago

I fully agree with your philosophy. But I was thinking - maybe theres room for a small change that is in line with both philosophy and reality.

Sticking with "standards" (by which I mean what the Oracle JavaDocs say) XMLStreamWriter seems to be intended to come from an XMLOutputFactory - or behave as if it did.

http://docs.oracle.com/cd/E19159-01/819-3669/bnbff/index.html

"Note that XMLStreamWriter implementations are not required to perform well-formedness or validity checks on input. While some implementations may perform strict error checking, others may not. The rules you implement are applied to properties defined in the XMLOutputFactory class"

Not the most clear of statements ... but leading that train of thought.

XMLOutputFactory : http://docs.oracle.com/javase/7/docs/api/javax/xml/stream/XMLOutputFactory.html

Lists predefined properties. One.

javax.xml.stream.isRepairingNamespaces

It doesn't seem unreasonable to assume an XMLStreamWriter should return a value when requested for this property. One could argue that its required or less strongly that its callers of getProperty() for that property should be able to expect a value (Boolean true or false) for that one property.

And conversely I cant think of an argument that providing value for that property would in any way compromise conformance. The only thing I can think of is if you cant produce a truthful answer ... i.e that neither true nor false is accurate, even so ... to my read it seems more in compliance to provide some answer to this one predefined property for XMLStreamWriter.

Adding support for that single property, by returning something instead of throwing an exception would not only fix this specific problem, possibly fix other code that makes the same assumptions, not violate standards, and depending on interpretation possibly be more conformant.

(I don't if the builder has the concept or not ... so I cant suggest if the result should be true or false or conditional - and I don't know what the results would be of calling code making decisions based on the answer - but I would wager a bar tab that the results would be better then throwing an exception.)

    (1-2/2)

    Please register to reply