Hi Max, not surprising.
getProject().createClassLoader(classPath) creates a new AntClassLoader with the given classpath and set CoreLoader (which is usually null) as it's parent(Same as <taskdef ... classpath="..."/>). AntClassLoader uses System.getClassloader() as it's default parent unless you set another parent loader explicitely. So you have initially two parallel child loaders of the system loader. If you want your "local" classloader a childloader of the task's loader you should - as of less classpath overhead - simply code new URLClassloader(this.getClass().getClassloader(),localClasspath) (and set it as ThreadContextClassloader) unless you want to support things like "isolate"... LoadProperties checks, whether it needs to set up a new classloader or can use it's own classloader which is ant's project classloader (normally also a child of system loader). (Creating an AntClassloader implicitely adds the lib jars to this classloader.) CoreLoader is a relict. It's not really used in ant itself but supported by most classloader creations. Maybe it is used by some IDEs or other frameworks. (I don't know any example.) Hope that helps a little bit Cheers Rainer > -----Original Message----- > From: Max Rydahl Andersen [mailto:[EMAIL PROTECTED] > Sent: Saturday, June 18, 2005 11:44 PM > To: dev@ant.apache.org > Subject: ant tasks creation of classloaders > > > Hi guys, > > Having some "fun" issues with classloading these days. > > I have a task (HibernateTool) that is used like this: > > <taskdef name="hibernatetool" > classname="org.hibernate.tool.ant.HibernateToolTask"> > <classpath path="[necessary hibernate libs]"> > </taskdef> > > > <target name="exportddl" depends="compiletest" > description="Export the > DDL to caveatemptor.ddl and DB"> > <hibernatetool destdir="${build.dir}"> > <classpath path="etc;${build.dir}/classes"/> > <annotationconfiguration > configurationfile="${classes.dir}/hibernate.cfg.xml"/> > <hbm2ddl export="false" console="false" drop="false" > create="true" outputfilename="caveatemptor.ddl" delimiter=";"/> > </hibernatetool> > </target> > > > Notice that the classpath of the taskdef and hibernatetool have no > overlaps. > > Until today I had the following code in the HibernateToolTask > for creating > the classloader: > > AntClassLoader loader = getProject().createClassLoader(classPath); > loader.setParent(getProject().getCoreLoader()); > loader.setThreadContextLoader(); > > But when I run this stuff with the task above I get > ClassNotFoundErrors > for annotations defined in hibernate. > > This occurs because with the above classloader setup I > effectively goes > around the <taskdef> classpath - it > will instead first look in the parent of the AntClassLoader I > created and > this will be the system classloader which > of course know nothing about the hibernate specific classloaders. > > Know my current work around for this is to do: > > AntClassLoader loader = getProject().createClassLoader(classPath); > loader.setParent(this.getClass().getClassLoader()); <-- this is the > HibernateToolTask instance > loader.setThreadContextLoader(); > > This will setup the right classloading sequence. > > But i'm just curious of why this does not seem to be the > default way of > doing things in the existing ant tasks ? > > e.g. in LoadProperties is: > ClassLoader cL = (classpath != null) > ? getProject().createClassLoader(classpath) > : LoadProperties.class.getClassLoader(); > > which for me says "ignore LoadProperties own classloader if i have a > <classpath>" > > and most other places they *only* uses the core task loader > which for me > seems kinda strange (as it can give funny > sideeffects if not all classes used by the <taskdef> isn't loaded yet) > > So, am I missing some crucial insight or is it just "random" how the > current ant tasks setup their classloaders :) ? > > Anyone which can think up any bad things with the classloader > setup I did > here ? > > /max > > > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] > --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]