Pimp Your GlassFish: Replacing XSL transformer in GF v2ur2
There are times when things hurt so much that you feel urged to blog about them once solved. This is one of them.
Our company is using XSL heavily for reporting (generating vector charts in PDFs on the fly from data analyzed by GlassFish), so it is not very amazing that we found some bugs in the XSL transformer (a.k.a "JAXP Implementation") contained in GlassFish. As we're not so fast as we would like to be, "our" GlassFish (actually there are dozens, as we are an ISV providing GF to our customers) still is v2ur2, but not v3 yet. So it is not surprising that the XSL transformer is not the latest (and such best maintained) one.
But we had been rather astonished by some other things.
First, it is rather strange that Sun's JRE 1.6.0_17 comes with a copy of XALAN that doesn't have the "latest" fixes found on XALAN's web site. In fact, XALAN itself is not very up-to-date, as latest 2.7.1 was release in November 2007 already. So Sun's JRE contains bugs that are actually fixed since more than two years now. Nobody found the time to migrate the fixes into com.sun.org.apache till today. Sad, bute true. I just filed a bug report to get things done (hopefully) soon. Blame it on the Oracle deal, but it's everything but not smart that the most modern JVM comes with a buggy copy while there is a fixed one available for more than two years.
So I put XALAN 2.7.1's JARs into jre6/lib/ext (which is the path of the JVM we're running GF v2ur2's ACC on) but noticed that while the bugs are gone in any standalone program, those still are existing inside of ACC (a.k.a. "Application Client Container"). What the heck...?
After several emails going back and forth with the actually excellently helpful team at Sun (Tim and Kenneth, thanks a lot! Your tip with looking at the Exception saved my day!) I discovered that GF v2ur2 does neither use the automatic JAXP discovery of the JVM, nor the explicit JARs given in ACC's appclient.bat, but in fact are using especially that JAXP factory provided in the middle of a rather lengthy configuration string named "ACTIVATION". Guys, did you really expect somebody notice that hidden place? Rather sad that it's so tricky to find, actually, but more strange it is that GFv2ur2 came with neither the original XALAN nor with a private GlassFish instance of it -- it actually relied on the fact that a Sun JVM was installed! In fact, the factory was set to a fixed class name in the "com.sun.org.apache" package. So I wonder how that was supposed to run on any JVM besides Sun's? I would understand if GF would contain that class -- but it didn't (possibly because somebody noticed that this class is already delivered by the JVM?). Boy, I had a hard time discovering this!
So, until you walk into the same trap, here is what the problems are and how to fix them easily in a minute:
1. <xsl:sort> discarts results
Yes, it sounds scary and it actually is scary.
2. Large XSL stylesheets cannot be loaded, leading to messages like "cannot load translet 'GregorSamsa'".
Don't even think about searching for the name "GregorSamsa" in your XSL - the actual problem is solely the lenght of you XSL.
Both bugs are gone with XALAN 2.7.1, and before they drive you nuts, just do the following:
1. Do NOT change your XSL, it is all right. It is XALAN who's wrong!
2. Put serializer.jar, xml-apis.jar, xalan.jar and xercesImpl.jar into jre6/lib/ext (or whathever your GlassFish's JVM path is)
3. Edit appclient.bat, find the line starting with "set ACTIVATION". Remove setting the TransformerFactory to com.sun.org.apache...
As I said, done in a minute, and keeps you save from driving crazy.