Bug 49271 - xslt task no longer heeds classpath attribute
Summary: xslt task no longer heeds classpath attribute
Alias: None
Product: Ant
Classification: Unclassified
Component: Core tasks (show other bugs)
Version: 1.8.1
Hardware: All All
: P2 regression with 2 votes (vote)
Target Milestone: 1.8.2
Assignee: Ant Notifications List
: 50289 (view as bug list)
Depends on:
Reported: 2010-05-11 10:05 UTC by bas@x-hive.com
Modified: 2014-02-17 13:55 UTC (History)
4 users (show)


Note You need to log in before you can comment on or make changes to this bug.
Description bas@x-hive.com 2010-05-11 10:05:01 UTC
The xslt task no longer heeds the classpath property. The reason is that in XSLTProcess.java, the resolveProcessor method does not (in the default case) call the loadClass method and therefore the thread context class loader is not set.

This is a regression from 1.8.0.
Comment 1 bas@x-hive.com 2010-05-11 10:16:01 UTC
As a workaround, you can explicitly specify
as an attribute of the xslt task.
Comment 2 Stefan Bodewig 2010-05-11 11:17:19 UTC
fixed with svn revision 943143
Comment 3 Jesse Glick 2010-05-11 14:14:56 UTC
The fix looks wrong to me. TraXLiaison is part of primary Ant sources, so we should not be loading *it* using some special class loader - unnecessary and risks weird CCEs.

The use of getContextClassLoader in TraXLiaison.getFactory is also strange, because it relies on some undocumented side effects from the task. It seems XSLTProcess sets and restores the thread's CCL - but it only sets it in loadClass. 943143 works only because loadClass is called at all - it could throw away the result! Also, using Class.forName(String) from TraXLiaison.getFactory is probably unnecessary and wrong.

Perhaps the proper fix is as follows:

1. Back out 943143; as part of assuming JDK 1.4+ I intentionally loaded TraXLiaison directly, since it does not depend on anything outside the JRE.

2. Simplify TraXLiaison.getFactory to not call Class.forName(String). It can continue to use TransformerFactory.newInstance for an unspecified factory; or Class.forName with CCL on a specified factory. (Note that if you are bothering to specify a classpath for the processor, you should very likely be specifying the factory too - else how do you know for sure what you are getting? You could be getting some unrelated factory that happened to be elsewhere in the classpath.)

3. Make XSLTProcess.execute always create loader and call setThreadContextLoader in case classpath != null; do not do this logic in loadClass.
Comment 4 Stefan Bodewig 2010-05-17 05:29:30 UTC
I agree with all of your points.
Comment 5 Stefan Bodewig 2010-08-05 14:50:57 UTC
svn revision 982729 is along the lines of point 1 and 3 of comment #3

I extracted the loader creation into a method that is invoked from execute as
well as loadClass since loadClass may be invoked via the protected getLiaison
method and there wouldn't be any guarantee that execute has been called at all.

I've skipped point 2 since I don't think falling back to Class.forName(string)
likely doesn't do any harm (we shouldn't be getting there anyway).
Comment 6 Stefan Bodewig 2010-10-26 09:00:39 UTC
I think it is fixed again and assume Jesse can live with the current trunk code.
Comment 7 Jesse Glick 2010-10-26 12:43:00 UTC
Looked OK last I checked.
Comment 8 Jesse Glick 2010-11-18 10:03:36 UTC
*** Bug 50289 has been marked as a duplicate of this bug. ***