ant-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Rainer Noack" <>
Subject RE: custom classloader for a task
Date Wed, 31 Aug 2005 22:52:18 GMT
Hi Jochen,

unfortunately, the displayed delegation hierarchy is typically not correct.
oata.AntClassLoader allways returns the System Classloader (class
sun.misc.Launcher$AppClassLoader) as its
If you run ant from it's shell script you will have typically the following
delegation hierarchy:
* class (loads a task explicitely
defined by taskdef, contains the jars/dirs defined in taskdefs classpath
* class   (created by Launcher, Classloader of
oata.Project, default tasks and most of the other ant stuff; typically
contains your classpath, the jars in $ANT_HOME/lib and the jdk's tools.jar)
* class sun.misc.Launcher$AppClassLoader (known as System-, Application- or
User- Classloader, that only loads the oata.launch.* classes, normally only
contains ant-launcher.jar)
* class sun.misc.Launcher$ExtClassLoader (Extension classloader, typically
contains the jars in $JRE_HOME/lib/ext)
* null (bootstrap classloader for all the jdk stuff, typically contains the
jars in $JRE_HOME/lib resp. $JDK_HOME/lib)

To find out the delegation hierarchy in maven you have to change your code
to something like this (not clean but should work, assumed your task extends

public void execute() throws BuildException {
    ClassLoader loader = this.getClass().getClassLoader();
    if (loader instanceof AntClassLoader) {
        loader = getProject().getCoreloader();
        if (loader == null)
            loader = Project.class.getClassLoader();
    while (loader!=null) {
        loader = loader.getParent();

In the next weeks, I will publish a new patch (and a ready-to-use trial
version) for the proposed <classloader> and <classloaderreport> task (see that gives a more
solution for this problem.

Once knowing the environment's delegation hierarchy you have to decide
whether it is really possible to create a consistent second delegation
hierarchy for the conflicting jars or not. (This could be done by the
proposed <classloader> task).

However, if you want to run your task in very different environments (in
terms of classloading), I think forking is the cleanest solution. (BTW,
forking of compile tasks is IMHO mostly allways the best solution).



> -----Original Message-----
> From: Jochen Theodorou [] 
> Sent: Tuesday, August 30, 2005 10:49 AM
> To: Ant Users List
> Subject: Re: custom classloader for a task
> Conor MacNeill schrieb:
> > 
> > Jochen Theodorou wrote:
> > 
> >>Hi all,
> >>
> >>Te problem I have is a little complex but I hope you can help me. 
> >>Groovy has an ant task to compile groovy classes and a task to use 
> >>groovy from within ant see 
> >>for details. But in some enviroments such as in maven with certain 
> >>plugins we have conflicting jars. I mean jars of a 
> different version 
> >>than needed by groovy. For example antlr or asm.
> >>
> >>Our current workaround for the compile task (groovyc) is to 
> fork the 
> >>VM. But this can't be the solution? I mean isn't there a 
> possibility 
> >>to load a task through a custom classloader? It's no 
> problem for me to 
> >>write such a loader, but where to wire it in? I know about the 
> >>loaderref attribute, but as far as I understand this 
> attribute is for 
> >>reusing a classloader. A normal classloader can't be used since a 
> >>normal classloader looks for a class first in the parent and if the 
> >>parent knows the conflicting jar/class then we have the 
> same problem 
> >>as before.
> > 
> > Since you are passing a classpath to the taskdef above, Ant will 
> > create a classloader to load this task's classes. What classes this 
> > classloader can see will depend on the classloader hierarchy under 
> > Maven. I have no idea what that will be.
> classloader hirarchy for the task class without loaderref:
> class
> class sun.misc.Launcher$AppClassLoader
> class sun.misc.Launcher$ExtClassLoader
> printed by a task:
>      public void execute() throws BuildException {
>          ClassLoader loader = this.getClass().getClassLoader();
>          while (loader!=null) {
>              System.out.println(loader.getClass());
>              loader = loader.getParent();
>          }
>      }
> so it seems maven does not change the hirarchy...
> > It is possible to specify a reverseloader="true" attribute 
> on an Ant 
> > taskdef. It is highly deprecated, unsupported, bad things 
> happen, etc. 
> > It will cause the classloader to consult it's jars first, 
> before those 
> > of its parent.
> well, reverseloader=true might be the thing I am searching for, and a 
> test shows it works then... But these deprecated warnings are 
> annoying. 
> No way to work around this problem?
> >>I heard that when you do loaderref="root" in a maven 
> project you get 
> >>the ant-loader, but that will be no help if the normal classpath 
> >>contains a conflicting jar for another task. Maybe someone 
> can explain 
> >>me if a classpath from a taskdef is added to the loader reffered by 
> >>loaderref. If so the ant-loader will be polluted too.
> > 
> > No, this does not happen - loaderref and classpath are exclusive, I 
> > think.
> my tests are showing that with a loaderref I hae a different 
> AntClassLoader, than the normal Classloader, but I have still the 
> conflicting jar. When I enable reverseloader, then it's ok. 
> So the new 
> Loader has to share some classpath parts with the normal antloader 
> somewhere, because I am sure the sun.misc.Launcher does not caontain 
> that jar.
> by blackdrag
> ---------------------------------------------------------------------
> To unsubscribe, e-mail:
> For additional commands, e-mail:

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

View raw message