Here's another old post that corroborates the one I linked to: http://www.mail-archive.com/user@ant.apache.org/msg22871.html
This poster isolated the problem with the base class of ClassPathXmlApplicationContext, org.springframework.core.io.DefaultResourceLoader. And I notice that DefaultResourceLoader does have a setClassLoader method: http://static.springsource.org/spring/docs/3.0.x/api/org/springframework/core/io/DefaultResourceLoader.html#setClassLoader%28java.lang.ClassLoader%29 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 <mgit...@gmail.com> 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: > http://www.mail-archive.com/dev@ant.apache.org/msg07704.html > > 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. >