ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Kerns, Bob" <>
Subject RE: [PATCH] build listener class loading
Date Mon, 31 Dec 2001 10:31:35 GMT
I was sort of wondering why these cleanups exist. It looks to me like
perhaps there's some premature optimization going on here, and some
poorly-allocated division of responsibility.

While closing the zipfiles is certainly important, that's a cache; it'll
reopen as necessary. But clearing out project & pathComponents? I'm guessing
that's the proximal cause of the "unusuable state" you find the loader in --
unnecessary "optimization" as far as I can tell.

And why isn't the creator of the AntClassLoader responsible for cleaning it
up? e.g., refactoring the code in

    protected AntClassLoader getClassLoader(ClassLoader systemClassLoader,
File antHome) {
        // We now create the class loader with which we are going to launch
        AntClassLoader antLoader = new AntClassLoader(systemClassLoader,

        // need to find tools.jar
        // add everything in the lib directory to this classloader
        File libDir = new File(antHome, "lib");
        addDirJars(antLoader, libDir);
        File optionalDir = new File(antHome, "lib/optional");
        addDirJars(antLoader, optionalDir);
        return antLoader;

    protected File findAntHome(ClassLoader systemClassLoader) {
        if (systemClassLoader == null) {
            antHome = determineAntHome11();
        else {
            antHome = determineAntHome(systemClassLoader);
        if (antHome == null) {
            System.err.println("Unable to determine ANT_HOME");
        System.out.println("ANT_HOME is " + antHome);
        return antHome;

    public static void main(String[] args) {
        ClassLoader systemClassLoader = Launcher.class.getClassLoader();
        File antHome = findAntHome(systemClassLoader);

        Properties launchProperties = new Properties();
        launchProperties.put("ant.home", antHome.getAbsolutePath());        
        AntClassLoader antLoader = getClassLoader(systemClassLoader,
        try {
            Class mainClass =
            final Class[] param = {Class.forName("[Ljava.lang.String;"),
                                   Properties.class, ClassLoader.class};
            final Method startMethod = mainClass.getMethod("start", param);
            final Object[] argument = {args, launchProperties,
            startMethod.invoke(null, argument);
        catch (Exception e) {
            System.out.println("Exception running Ant: " +
e.getClass().getName() + ": " + e.getMessage());
        finally {
            antLoader.cleanup(); // I would call this 'close()'

I can find even less justification for the IntrospectionHelper's use of this
event. Wouldn't it be simpler to just move the
IntrospectionHelper.getHelper() method to Project as a non-static? And thus
have IntrospectionHelper.helpers be an instance field of Project, and thus
be GC'd when the Project is GC'd?

All this manual managing of resources makes me queasy -- and apparently
leads to bugs.

-----Original Message-----
From: Adam Murdoch []
Sent: Saturday, December 29, 2001 4:02 PM
Subject: [PATCH] build listener class loading


This patch fixes an odd class loading problem, where the classes used by a
BuildListener's buildFinished() method cannot be loaded.  This is how the
problem happens:

- The task is loaded via an AntClassLoader (e.g. using <taskdef> with a
classpath specified).

- The AntClassLoader adds a BuildListener to the project, so that it can
clean up when the build finishes.

- When the task executes, it adds a BuildListener to its project.

- The build finishes, and a build finished event is fired.

- The AntClassLoader's buildFinished() method is called.  The class loader
cleans itself up.

- The task's buildFinished() method is called.  If this method uses classes
which have not been loaded, the AntClassLoader's findClass() method is

- The AntClassLoader is in an unusable state, and a NPE is thrown.

This patch defers AntClassLoader (and IntrospectionHelper) cleanup until
after the build finished event has been handled by all build listeners.


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

View raw message