[Geoserver-devel] The Java 1.5 issue

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

--

I would just vote to include the xalan.jar in the distribution. Makes things simplest for users. I dont think that 1.8M will really make or break anybody.

The flexibility to pass in a different XSLT processor is nice, but I doubt most people will use it. I think having geoserver run "out of the box" is more important.

Justin

Chris Holmes wrote:

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

--
Justin Deoliveira
The Open Planning Project
http://topp.openplans.org

On Mon, 14 Nov 2005, Justin Deoliveira wrote:

I would just vote to include the xalan.jar in the distribution. Makes
things simplest for users. I dont think that 1.8M will really make or
break anybody.

The flexibility to pass in a different XSLT processor is nice, but I
doubt most people will use it. I think having geoserver run "out of the
box" is more important.

I wasn't talking about passing in different xslt processors, it's more
about making use of the standard xslt processor, which in the case of java
1.5 is not xalan, and I think there are good reasons they went to xsltc -
namely that it's what the apache community, who also made xalan, has
chosen as their official one.

Actually, I think the answer should be to use XSLTC on java 1.4 as well,
though it may be that java 1.4 only has the interpretive processor, so
we'd have to include the xalan.jar as well. Probably the only way around
would be to figure out internally which version of Java was being run, and
have geoserver set the interpretor then. Or to just use the default,
as it may be at the point that most xslt processors support everything
now, and we can get rid of our hack.

Chris

Justin

Chris Holmes wrote:
> 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
>

--