Ok, just spent an hour investigating getting GeoServer without those
annoying xalan errors when 1.5 is being run, and without including the
silly 1.8 meg xalan jar in the installation.
So the issue runs something like this:
We use SAX producers to very efficiently serialize java objects to XML.
The GetFeature and GetCaps responses work this way. To do this one must
make use of an XSL transformer like xalan. If I remember correctly,
initially we just used whatever default xslt implementation was on the
classpath. This caused errors on some servlet containers, that had
alternative, and presumably lighter weight, implementations of the
jaxp/xslt stuff. So we included xalan.jar and set the factory
implementation (in the code -
System.setProperty(.javax.xml.transform.TransformerFactory.,
.org.apache....), you could also do this by passing in a command line arg)
to always use the xalan jar. Then we realized that java actually always
comes with xalan.jar, so there was no reason for us to include it, and
it's a nice win, since it's probably the largest outside jar we use
(excluding gt2, but those aren't really 'outside'). All we had to was set
in the code the use of the xalan factory, instead of using whatever was on
the path. This was a great solution, cured everything, though it was a
bit of a hack, but a safe one with 1.4.
When 1.5 entered the scene, however, it started breaking things. It
doesn't include xalan.jar, and if one runs geoserver, it won't work, since
it'll get a null pointer trying to find the factory implementation that we
set. Today I dug into the causes of this, since basically it didn't make
sense to me that they no longer include an implementation of the xslt
stuff, there must be _something_ we can use. And lo and behold, they
swapped out xalan for xsltc (info:
http://java.sun.com/j2se/1.5.0/compatibility.html and
http://java.sun.com/j2se/1.5.0/docs/guide/xml/jaxp/JAXP-Compatibility_150.html).
Testing on my machine against Jetty, if you don't explicitly set the
factory (comment out the System.setProperty line) things seem to work
fine.
Though digging into the code a bit, trying to actually compile without
xalan, exposes a few problems. Half the errors are in the zserver code I
wrote ages ago, we can kill that, since it's not being used and it's jars
are no longer included. The other half are a hack in WMSCapsTransformer
to do comments, that look for the TranformerIdentityImpl and use it
directly to write comments.
It's too bad we didn't look into this earlier, since I think the ideal
solution would be to stop using the xalan.jar, just rely on the
interfaces, and then give the user community appropriate time to test on a
variety of servlet containers. If there are errors we just ask them to
pass in either the xalan or xslt implementation on the command line, so
that it gets called first. Before it made sense to do this
programmatically, for everyone, but with 1.5, it just doesn't, since we
likely are fixing it for a smaller number of users than the current java
1.5 users. We could still go that route, but we'd like to go 1.3.0
relatively soon, so there may not be enough time for sufficient community
feedback. Though it still may be the best answer, the greatest utility
for the greatest number.
The other possibility is to include xalan.jar in the distribution. This
shouldn't hurt anyone, except me with my desires for slimmer downloads.
But it sounds like XSLTC has a 'major performance benefit' for large
datasets, and returning GML is definitely a large dataset, though I'm
unsure if we actually get the benefit of that...
So thoughts? I think having Java 1.5 working without having to download
an extra jar is pretty important for 1.3.0. I think going all interfaces,
not setting the system property, is by far the best answer in the long
run. Perhaps we could put out the next RC with it, and if anyone
complains we can just roll back and include the big xalan jar? I think
the slimmer download, potential performance boost, and long term
adaptability to change (in case they were to switch it up again), make it
the winner in my mind. The only downside is some servlet containers may
have to pass in an argument to make sure we use a good transformer
implementation.
Chris
--