ant-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Antoine Levy-Lambert <>
Subject Re: Ant + Spring = classpath purgatory
Date Tue, 01 Feb 2011 15:04:55 GMT
I think it is log4j which wants to look for config files on the thread 
context loader.



On 1/29/2011 1:27 PM, Mitch Gitman wrote:
> Here's the solution that finally worked for me, and that includes locating
> the log4j class. This is all in my Ant task:
>          ClassPathXmlApplicationContext applicationContext = new
> ClassPathXmlApplicationContext();
>          applicationContext.setClassLoader(this.getClass().getClassLoader());
>          applicationContext
>                  .setConfigLocation("com/foo/ApplicationContext.xml");
>          applicationContext.refresh();
> I'm going to clean this up to make the application layer initialize its own
> ApplicationContext internally. The caller/consumer of the application will
> just be responsible for passing a ClassLoader to the application layer. To
> my mind, having to supply a ClassLoader is the least evil--the smallest
> concession to the need for this application to be run by an Ant task as
> opposed to some other execution environment.
> Still, I'm curious why an executing task uses the ClassLoader obtained by
> LoaderUtils.getContextClassLoader() rather than the task's own
> AntClassLoader.
> On Sat, Jan 29, 2011 at 12:26 AM, Mitch Gitman<>  wrote:
>> Here's another old post that corroborates the one I linked to:
>> This poster isolated the problem with the base class of
>> ClassPathXmlApplicationContext,
>> And I notice that
>> DefaultResourceLoader does have a setClassLoader method:
>> This has the makings of a possibly more elegant solution. So I get:
>>          AntClassLoader taskloader = (AntClassLoader)
>> this.getClass().getClassLoader();
>> And then I pass this this AntClassLoader to
>> DefaultResourceLoader.setClassLoader. I'll give this a shot. Might solve my
>> log4j problem in the process.
>> I'm still curious why this classloader isn't used in the first place and
>> what the default one, as obtained by LoaderUtils.getContextClassLoader(),
>> represents. This goes back to my observation that this sort of problem
>> doesn't arise elsewhere.
>> Note. I'm using Ant 1.7.1.
>> On Fri, Jan 28, 2011 at 11:33 PM, Mitch Gitman<>  wrote:
>>> I have a Spring-based application that I'm exposing through an Ant task,
>>> among other interfaces.
>>> The moment where I run into trouble is when the application tries to use
>>> Spring's ClassLoader-based code to load a Spring application context:
>>>          ApplicationContext applicationContext = new
>>> ClassPathXmlApplicationContext(
>>>                  "/com/foo/ApplicationContext.xml");
>>> I see an error that the resource com/foo/ApplicationContext.xml cannot be
>>> found on the classpath. The XML file, together with the application code,
>>> happen to be in the same JAR as the task itself.
>>> Now, I came across this very, very old post on the ant-dev list that gave
>>> me the makings of a solution:
>>> So at the start of my task, I would do this:
>>>          AntClassLoader taskloader = (AntClassLoader)
>>> this.getClass().getClassLoader();
>>>          taskloader.setThreadContextLoader();
>>> And at the close of my task, I would do this:
>>>          taskloader.resetThreadContextLoader();
>>> This works actually.*
>>> I'm leery though of having to resort to this fix. Does anyone know of a
>>> "better" way to get Spring to use the right ClassLoader or just in general
>>> to fool task-invoked application code that might play fast and loose with
>>> classloaders? I haven't delved into the Spring source myself. What's odd is
>>> that this problem doesn't arise in other classloading containers in which a
>>> Spring-based application might be running. For example, a web container
>>> would be loading a web application with a child classloader, and yet that
>>> works fine.
>>> Thanks.
>>> * Rather, this almost works. Almost in that Spring tries to configure its
>>> logging through log4j, but it can't find the class
>>> org.apache.log4j.Category. I've verified that the log4j JAR is in my
>>> classpath. The quick fix is to stick the log4j JAR in the Ant lib directory.
>>> Obviously, that is not a sustainable solution. I'm still trying to get to
>>> the bottom of this and might have to write a follow-up message.

To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message