Removing xalan.jar
dimitris Feb 23, 2006 4:56 AM(I'm copying the discussion from the dev-list here for reference)
"dimitris@jboss.org" wrote:
I tried to remove lib/endorsed/xalan.jar in 4.0.x and the situation is as follows:
Works fine under jdk1.5, but breaks under jdk5 when the XSLSubDeployer does a
TransformerFactory tf = TransformerFactory.newInstance();
The problem is lib/endorsed/xml-apis.jar includes a javax.xml.transform.TransformerFactory that simply points to org.apache.xalan.processor.TransformerFactoryImpl, if the javax.xml.transform.TransformerFactory property is not set!
And that overrides the jdk5 javax.xml.transform.TransformerFactory that points to com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl.
If (when run under jdk5) I set
-Djavax.xml.transform.TransformerFactory=com.sun.org.apache.xalan.intern
al.xsltc.trax.TransformerFactoryImpl, but I don't know if this should work with all jdk5 jdks.
What options do we have? Hack xml-apis to remove the offending javax.xml.transform.TransformerFactory class?
"scott.stark@jboss.org" wrote:
The question is where the the xml-apis.jar come from then? It should not include a TransformerFactory if its not from the xalan distribution which is what I suspect. The origin of the xml jars needs to be validated and if the xerces distribution defaults to configuring a TransformerFactory, that should be removed.
The xml parser is needed to override the buggy jdk version.
"dimitris@jboss.org" wrote:
I traced this down to a TranformerFactory included in the xml-apis.jar that comes with xerces tools (e.g. Xerces-J-tools.2.7.1.zip).
This is tagged as 1.3.02 and in turn originates from http://xml.apache.org/commons/
The xml-commons hadn't had any releases for some time, so the tagged xml-apis.jar comes directly from their cvs.
I think I will remove all javax.xml.transform.** from xml-apis.jar to create a new xml-apis-no-transform.jar and include this instead.
From a quick test it seems to be working with both jdk1.4 and jdk5.
"scott.stark@jboss.org" wrote:
This is probably a jaxp requirement to not subset the apis. The next question is whether the xml-apis.jar is needed. Is jdk1.4.x at jaxp 1.2?
The xerces 2.7.x release supports jaxp 1.3.
The potential problem with doing this is are there dependencies between the javax.xml.transform.* classes and the other javax.xml.* classes.
The more I think about it the more I doubt this is legal for a java ee distribution. If we are bundling jaxp 1.3, we need it to be the complete
1.3 set of apis and we would just have to patch the TranformerFactory to do the right thing, whatever that is.
"dimitris@jboss.org" wrote:
It all boils down to here:
...
return (TransformerFactory) FactoryFinder.find(
/* The default property name according to the JAXP spec */
"javax.xml.transform.TransformerFactory",
/* The fallback implementation class name */
"org.apache.xalan.processor.TransformerFactoryImpl");
...
I don't see how we can patch the TF to return a proper fallback implementation name, because we just don't know what that is.
On Sun jdk1.4 it would be
org.apache.xalan.processor.TransformerFactoryImpl
On Sun jdk5 it would be
com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl
But on other vendor jdks, whats the correct value?
And if it is just a question of setting a sensible default value, we could do just the same setting the javax.xml.transform.TransformerFactory property.
But isn't this exactly the role of the TransformerFactory offered by the jdk vendor?
I think the best compromise is to just remove javax.xml.transform.TransformerFactory from xml-apis.jar (replace with xml-apis-notf.jar ?) to let the vendor supplied default apply.
"scott.stark@jboss.org" wrote:
Setting this via a system property cannot be done as this is a global override. We could simply externalize the default factory name to an attribute of the jboss server info mbean and fallback to the jdk default if it cannot be found. I don't know if an extension class can get access to a class from the jdk rt.jar via the ClassLoader.getSystemClassLoader().
"dimitris@jboss.org" wrote:
I don't follow why this is necessary. If we just remove javax.xml.transform.TransformerFactory from xml-apis.jar then the jdk bundled TransformerFactory will be used to choose the correct implementation.
A user can always drop his own xalan.jar to lib/endorsed (for jdk1.4/5), or server/xxx/lib for jdk5, or use a scoped xalan.jar to override the jdk version, since xalan.jar contains:
META-INF/services/javax.xml.transform.TransformerFactory file containing the class name of its implementation.
"scott.stark@jboss.org" wrote:
Its not clear that removal of the javax.xml.transform.* is safe. There are references to org.w3c.dom.* from the javax.xml.transform.dom for example. We cannot simply remove just the javax.xml.transform.TransformerFactory. It would have to be all
javax.xml.transform.* classes.
The presence of the javax.xml.transform.TransformerFactory should not affect a user being able to override the transformer by dropping in an xsl jar with a META-INF/services/javax.xml.transform.TransformerFactory
entry as this takes precedence over the TransformerFactory defaults.
"dimitris@jboss.org" wrote:
Removing javax.xml.transform.TransformerFactory or patching it to try invoke the underlying TransformerFactory (if this is possible) which is essentially the same thing, is undesirable because you'll end up with a transformer API and an underlying implementation that may not match
(correct?)
Removing javax.xml.transform.* is not clear that is safe (I guess because you might have incompatible parser api+impl <-> transformer
api+impl interactions?)
Ok, we are doomed :)
"scott.stark@jboss.org" wrote:
> Removing javax.xml.transform.TransformerFactory or patching it to try
> invoke the underlying TransformerFactory (if this is possible) which
> is essentially the same thing, is undesirable because you'll end up
> with a transformer API and an underlying implementation that may not
> match
> (correct?)
>
This is always the case though. Any attempt to override the xsl factory will be subject to matching the javax.xml.transform.* in effect.
> Removing javax.xml.transform.* is not clear that is safe (I guess
> because you might have incompatible parser api+impl <-> transformer
> api+impl interactions?)
>
> Ok, we are doomed :)
There are some xml parser class dependencies in the
javax.xml.transform.dom and javax.xml.transform.sax packages. I just
don't know if the javax.xml.transform.* in jaxp 1.3 can use the 1.2 xml
parsers.
It's a tradeoff between introducing a xsl parser dependency that the
user may not want vs modifying the TransformerFactory to be more
flexible at the cost of the user potentially have to configure the
TransformerFactory default. I think modifying the TransformerFactory is
the most flexible, but maybe just bundling the xsl parser is the
simplest.