Bug 46172

Summary: xslt task's factory attribute broken: TraXLiaison uses incorrect class loader.
Product: Ant Reporter: Dawid Weiss <dawid.weiss>
Component: Core tasksAssignee: Ant Notifications List <notifications>
Status: RESOLVED FIXED    
Severity: normal CC: jez, notifications, trevor
Priority: P2    
Version: 1.7.0   
Target Milestone: 1.8.0   
Hardware: All   
OS: All   
Attachments: A diff against ANT_17_BRANCH

Description Dawid Weiss 2008-11-09 12:25:57 UTC
Created attachment 22845 [details]
A diff against ANT_17_BRANCH

XSLT processing tasks allows one to specify custom transformer factory, including  a custom class path for this factory's classes. This is very handy as it allows custom XSLT processor to be embedded in the project. However, when used, it throws ClassNotFoundExceptions from TraXLiaison (1.6.x, 1.7.x, head).

The bug is caused by the following snippet in TraXLiaison:

private TransformerFactory getFactory() throws BuildException {
  // ... [SNIP]
            try {
                Class clazz = Class.forName(factoryName);
                tfactory = (TransformerFactory) clazz.newInstance();
            } catch (Exception e) {
  // ... [SNIP]

XSLT task sets a custom context class loader, but it is not used here, because Class.forName(String) is equivalent to calling:

Class.forName(String, definingClass.getClassLoader());

In other words, ANT's class loader is used to look up the class where context class loader should be used (this is a common mistake). This can be fixed in a number of ways -- by using Class.forName(String, Thread.currentThread().getContextClassLoader()) or by using the context class loader explicitly (as in the attached patch).
Comment 1 Stefan Bodewig 2008-11-24 08:13:23 UTC
*** Bug 41314 has been marked as a duplicate of this bug. ***
Comment 2 Stefan Bodewig 2008-11-24 08:29:49 UTC
*** Bug 29596 has been marked as a duplicate of this bug. ***
Comment 3 Stefan Bodewig 2008-11-26 01:21:28 UTC
svn revision 720773 uses the thread context classloader but falls back to Class.forName with no args if the factory cannot be found in the thread context loader.