Bug 29596 - XSLT task ignores classpath element/attribute when looking up transformer
Summary: XSLT task ignores classpath element/attribute when looking up transformer
Status: RESOLVED DUPLICATE of bug 46172
Alias: None
Product: Ant
Classification: Unclassified
Component: Core tasks (show other bugs)
Version: 1.6.5
Hardware: Other other
: P3 enhancement with 3 votes (vote)
Target Milestone: ---
Assignee: Ant Notifications List
URL:
Keywords:
: 39248 (view as bug list)
Depends on:
Blocks:
 
Reported: 2004-06-16 10:50 UTC by Jez Higgins
Modified: 2008-11-24 08:29 UTC (History)
1 user (show)



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jez Higgins 2004-06-16 10:50:55 UTC
Ant manual for XSLT task says

classpath  	the classpath to use when looking up the XSLT processor.

The XSLT task uses the defined classpath to look up the XSLTLiason class. 
Historically, this made sense.  Now, Trax is standard and the XSL:P and Xalan
liasons are deprecated.  It would seem to make sense to allow the TraXLiason to
use the defined classpath to look up the transformer to use.  The factory
element allows you to specify the precise transformer class to use, but if that
class isn't on the default classpath you're sunk.  If TraXLiason could use the
XSLTProcess' classpath, you can ship your processor of choice in your build
configuration and the problem is solved.
Comment 1 Jez Higgins 2004-06-16 10:56:44 UTC
Proposed patches to implement -

diff -u -r1.85 XSLTProcess.java
--- XSLTProcess.java    16 Apr 2004 09:59:02 -0000      1.85
+++ XSLTProcess.java    16 Jun 2004 10:53:00 -0000
@@ -414,7 +414,7 @@
      * @return the requested class.
      * @exception Exception if the class could not be loaded.
      */
-    private Class loadClass(String classname) throws Exception {
+    public Class loadClass(String classname) throws Exception {
         if (classpath == null) {
             return Class.forName(classname);
         } else {

diff -u -r1.35 TraXLiaison.java
--- TraXLiaison.java    9 Mar 2004 16:48:15 -0000       1.35
+++ TraXLiaison.java    16 Jun 2004 10:53:49 -0000
@@ -66,6 +66,9 @@
      */
     private String factoryName = null;

+    /** the owning XSLT task */
+    private XSLTProcess xsltTask = null;
+
     /** The trax TransformerFactory */
     private TransformerFactory tfactory = null;

@@ -259,7 +262,7 @@
             tfactory = TransformerFactory.newInstance();
         } else {
             try {
-                Class clazz = Class.forName(factoryName);
+                Class clazz = xsltTask.loadClass(factoryName);
                 tfactory = (TransformerFactory) clazz.newInstance();
             } catch (Exception e) {
                 throw new BuildException(e);
@@ -401,6 +404,8 @@
      *        is to be configured.
      */
     public void configure(XSLTProcess xsltTask) {
+        this.xsltTask = xsltTask;
+
         XSLTProcess.Factory factory = xsltTask.getFactory();
         if (factory != null) {
             setFactory(factory.getName());
@@ -413,6 +418,8 @@
                 setAttribute(attr.getName(), attr.getValue());
             }
         }
+
+

         XMLCatalog xmlCatalog = xsltTask.getXMLCatalog();
         // use XMLCatalog as the entity resolver and URI resolver
Comment 2 Stefan Bodewig 2004-06-28 08:02:04 UTC
Ant 1.6.2 will set the context classloader for the current thread since the
TransformerFactory will use that.  This is probably going to help with your issue.

Any chance you could try a hand-crafted build of Ant's CVS HEAD?

If not, please revisit this bug once Ant 1.6.2 has been released as beta (shouldn't
be too long from now).
Comment 3 Silver Surfer 2006-04-08 11:24:19 UTC
*** Bug 39248 has been marked as a duplicate of this bug. ***
Comment 4 Silver Surfer 2006-04-09 10:45:32 UTC
Not solved in 1.6.5 see duplicate BUG 39248 !!!

Greetings Surfer 
Comment 5 Kai Fan 2006-04-11 16:17:12 UTC
neither the classpath element/attribute nor the classpathref attribute works
Comment 6 Silver Surfer 2006-04-11 16:49:03 UTC
Fixed it for me i just use the contextClassLoader in Class.forName because there
is nothing to change in calling class:

TraXLiaison.java

try {
    final Class clazz = Class.forName(factoryName, true, 
                        Thread.currentThread().getContextClassLoader());
    tfactory = (TransformerFactory) clazz.newInstance();
} catch (Exception e) {
    throw new BuildException(e);
}

Surfer
Comment 7 Steve Loughran 2006-04-11 17:18:18 UTC
well, we have two options here. the original patch or the context class loader.

I'm not overhappy with the second, even though it does work, because I dont like
context class loaders -they are a bit of a hack. Can we be 100% sure that it
will always be set and valid?
Comment 8 Silver Surfer 2006-04-11 17:54:12 UTC
So the TraXLiaison is only called from XSLTProcess and if there is a defined
classpath the contextclassloader is set and valid. But if there is no defined
classpath i knew the contextclassloader must also be set but not if it is valid
- in the current meaning. In my environment i only work with a defined
classpath. So what about mixing the two options... first try to load in the
original way and if not found try to load from contextloader. Then it should
work as expected...

Class clazz = null;
try {
  clazz = Class.forName(factoryName); 
} catch(...) {
  try {
    clazz = Class.forName(factoryName, true, 
                        Thread.currentThread().getContextClassLoader());
  } catch ...

Comment 9 Stefan Bodewig 2008-11-24 08:29:49 UTC

*** This bug has been marked as a duplicate of bug 46172 ***