bodewig     2004/06/24 04:16:41

  Modified:    src/main/org/apache/tools/ant AntClassLoader.java
                        Project.java
               src/main/org/apache/tools/ant/taskdefs Ant.java
                        Recorder.java RecorderEntry.java
  Added:       src/main/org/apache/tools/ant SubBuildListener.java
  Log:
  Follow Conor's and Jose Alberto's advice - improved fix for PR 8689
  
  Revision  Changes    Path
  1.83      +40 -15    ant/src/main/org/apache/tools/ant/AntClassLoader.java
  
  Index: AntClassLoader.java
  ===================================================================
  RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/AntClassLoader.java,v
  retrieving revision 1.82
  retrieving revision 1.83
  diff -u -r1.82 -r1.83
  --- AntClassLoader.java       20 Apr 2004 13:25:08 -0000      1.82
  +++ AntClassLoader.java       24 Jun 2004 11:16:40 -0000      1.83
  @@ -44,7 +44,7 @@
    * class will then use this loader rather than the system class loader.
    *
    */
  -public class AntClassLoader extends ClassLoader implements BuildListener {
  +public class AntClassLoader extends ClassLoader implements SubBuildListener {
   
       private static final FileUtils fileUtils = FileUtils.newFileUtils();
   
  @@ -118,7 +118,7 @@
           private void findNextResource() {
               URL url = null;
               while ((pathElementsIndex < pathComponents.size())
  -                    && (url == null)) {
  +                   && (url == null)) {
                   try {
                       File pathComponent
                           = (File) pathComponents.elementAt(pathElementsIndex);
  @@ -222,7 +222,7 @@
               Class protectionDomain
                   = Class.forName("java.security.ProtectionDomain");
               Class[] args = new Class[] {String.class, byte[].class,
  -                Integer.TYPE, Integer.TYPE, protectionDomain};
  +                                        Integer.TYPE, Integer.TYPE, 
protectionDomain};
               defineClassProtectionDomain
                   = ClassLoader.class.getDeclaredMethod("defineClass", args);
           } catch (Exception e) {
  @@ -392,9 +392,9 @@
           if (project != null) {
               project.log(message, priority);
           }
  -//         else {
  -//             System.out.println(message);
  -//         }
  +        //         else {
  +        //             System.out.println(message);
  +        //         }
       }
   
       /**
  @@ -442,7 +442,7 @@
       public void addPathElement(String pathElement) throws BuildException {
           File pathComponent
               = project != null ? project.resolveFile(pathElement)
  -                              : new File(pathElement);
  +            : new File(pathElement);
           try {
               addPathFile(pathComponent);
           } catch (IOException e) {
  @@ -582,7 +582,7 @@
        *                                   on this loader's classpath.
        */
       public Class forceLoadClass(String classname)
  -         throws ClassNotFoundException {
  +        throws ClassNotFoundException {
           log("force loading " + classname, Project.MSG_DEBUG);
   
           Class theClass = findLoadedClass(classname);
  @@ -611,7 +611,7 @@
        * on this loader's classpath.
        */
       public Class forceLoadSystemClass(String classname)
  -         throws ClassNotFoundException {
  +        throws ClassNotFoundException {
           log("force system loading " + classname, Project.MSG_DEBUG);
   
           Class theClass = findLoadedClass(classname);
  @@ -815,7 +815,7 @@
           URL url = null;
           if (isParentFirst(name)) {
               url = (parent == null) ? super.getResource(name)
  -                                   : parent.getResource(name);
  +                : parent.getResource(name);
           }
   
           if (url != null) {
  @@ -907,7 +907,7 @@
                   if (entry != null) {
                       try {
                           return new URL("jar:" + fileUtils.getFileURL(file)
  -                            + "!/" + entry);
  +                                       + "!/" + entry);
                       } catch (MalformedURLException ex) {
                           return null;
                       }
  @@ -941,7 +941,7 @@
        * classpath.
        */
       protected synchronized Class loadClass(String classname, boolean resolve)
  -         throws ClassNotFoundException {
  +        throws ClassNotFoundException {
           // 'sync' is needed - otherwise 2 threads can load the same class
           // twice, resulting in LinkageError: duplicated class definition.
           // findLoadedClass avoids that, but without sync it won't work.
  @@ -1059,8 +1059,8 @@
        * reading the class from the stream.
        */
       private Class getClassFromStream(InputStream stream, String classname,
  -                                       File container)
  -                throws IOException, SecurityException {
  +                                     File container)
  +        throws IOException, SecurityException {
           ByteArrayOutputStream baos = new ByteArrayOutputStream();
           int bytesRead = -1;
           byte[] buffer = new byte[BUFFER_SIZE];
  @@ -1120,7 +1120,7 @@
        * on this loader's classpath.
        */
       private Class findClassInComponents(String name)
  -         throws ClassNotFoundException {
  +        throws ClassNotFoundException {
           // we need to search the components of the path to see if
           // we can find the class we want.
           InputStream stream = null;
  @@ -1217,6 +1217,31 @@
        */
       public void buildFinished(BuildEvent event) {
           cleanup();
  +    }
  +
  +    /**
  +     * Cleans up any resources held by this classloader at the end of
  +     * a subbuild if it has been created for the subbuild's project
  +     * instance.
  +     *
  +     * @param event the buildFinished event
  +     *
  +     * @since Ant 1.6.2
  +     */
  +    public void subBuildFinished(BuildEvent event) {
  +        if (event.getProject() == project) {
  +            cleanup();
  +        }
  +    }
  +
  +    /**
  +     * Empty implementation to satisfy the BuildListener interface.
  +     *
  +     * @param event the buildStarted event
  +     *
  +     * @since Ant 1.6.2
  +     */
  +    public void subBuildStarted(BuildEvent event) {
       }
   
       /**
  
  
  
  1.169     +38 -1     ant/src/main/org/apache/tools/ant/Project.java
  
  Index: Project.java
  ===================================================================
  RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/Project.java,v
  retrieving revision 1.168
  retrieving revision 1.169
  diff -u -r1.168 -r1.169
  --- Project.java      1 Jun 2004 14:51:55 -0000       1.168
  +++ Project.java      24 Jun 2004 11:16:40 -0000      1.169
  @@ -1790,6 +1790,43 @@
           }
       }
   
  +    /**
  +     * Sends a "subbuild started" event to the build listeners for
  +     * this project.
  +     *
  +     * @since Ant 1.6.2
  +     */
  +    public void fireSubBuildStarted() {
  +        BuildEvent event = new BuildEvent(this);
  +        Iterator iter = listeners.iterator();
  +        while (iter.hasNext()) {
  +            Object listener = iter.next();
  +            if (listener instanceof SubBuildListener) {
  +                ((SubBuildListener) listener).subBuildStarted(event);
  +            }
  +        }
  +    }
  +
  +    /**
  +     * Sends a "subbuild finished" event to the build listeners for
  +     * this project.
  +     * @param exception an exception indicating a reason for a build
  +     *                  failure. May be <code>null</code>, indicating
  +     *                  a successful build.
  +     *
  +     * @since Ant 1.6.2
  +     */
  +    public void fireSubBuildFinished(Throwable exception) {
  +        BuildEvent event = new BuildEvent(this);
  +        event.setException(exception);
  +        Iterator iter = listeners.iterator();
  +        while (iter.hasNext()) {
  +            Object listener = iter.next();
  +            if (listener instanceof SubBuildListener) {
  +                ((SubBuildListener) listener).subBuildFinished(event);
  +            }
  +        }
  +    }
   
       /**
        * Sends a "target started" event to the build listeners for this 
project.
  
  
  
  1.1                  ant/src/main/org/apache/tools/ant/SubBuildListener.java
  
  Index: SubBuildListener.java
  ===================================================================
  /*
   * Copyright  2004 The Apache Software Foundation
   *
   *  Licensed under the Apache License, Version 2.0 (the "License");
   *  you may not use this file except in compliance with the License.
   *  You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   *  Unless required by applicable law or agreed to in writing, software
   *  distributed under the License is distributed on an "AS IS" BASIS,
   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   *  See the License for the specific language governing permissions and
   *  limitations under the License.
   *
   */
  
  package org.apache.tools.ant;
  
  /**
   * Instances of classes that implement this interface can register
   * to be also notified when things happened during a subbuild.
   *
   * <p>A subbuild is a separate project instance created by the
   * <code>&lt;ant&gt;</code> task family.  These project instances will
   * never fire the buildStarted and buildFinished events, but they will
   * fire subBuildStarted/ and subBuildFinished.  The main project
   * instance - the one created by running Ant in the first place - will
   * never invoke one of the methods of this interface.</p>
   *
   * @see BuildEvent
   * @see Project#addBuildListener(BuildListener)
   *
   * @since Ant 1.6.2
   */
  public interface SubBuildListener extends BuildListener {
  
      /**
       * Signals that a subbuild has started. This event
       * is fired before any targets have started.
       *
       * @param event An event with any relevant extra information.
       *              Must not be <code>null</code>.
       */
      void subBuildStarted(BuildEvent event);
  
      /**
       * Signals that the last target has finished. This event
       * will still be fired if an error occurred during the build.
       *
       * @param event An event with any relevant extra information.
       *              Must not be <code>null</code>.
       *
       * @see BuildEvent#getException()
       */
      void subBuildFinished(BuildEvent event);
  }
  
  
  
  1.102     +7 -17     ant/src/main/org/apache/tools/ant/taskdefs/Ant.java
  
  Index: Ant.java
  ===================================================================
  RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/Ant.java,v
  retrieving revision 1.101
  retrieving revision 1.102
  diff -u -r1.101 -r1.102
  --- Ant.java  23 Jun 2004 14:08:26 -0000      1.101
  +++ Ant.java  24 Jun 2004 11:16:41 -0000      1.102
  @@ -379,32 +379,22 @@
               addReferences();
   
               if (target != null && !"".equals(target)) {
  +                Throwable t = null;
                   try {
                       log("Entering " + antFile + "...", Project.MSG_VERBOSE);
  +                    newProject.fireSubBuildStarted();
                       newProject.executeTarget(target);
                   } catch (BuildException ex) {
  -                    throw ProjectHelper.addLocationToBuildException(
  -                        ex, getLocation());
  -              } finally {
  +                    t = ProjectHelper
  +                        .addLocationToBuildException(ex, getLocation());
  +                    throw (BuildException) t;
  +                } finally {
                       log("Exiting " + antFile + ".", Project.MSG_VERBOSE);
  +                    newProject.fireSubBuildFinished(t);
                   }
               }
           } finally {
               // help the gc
  -            Iterator iter = getBuildListeners();
  -            while (iter.hasNext()) {
  -                newProject.removeBuildListener((BuildListener) iter.next());
  -            }
  -            iter = newProject.getBuildListeners().iterator();
  -            while (iter.hasNext()) {
  -                Object o = iter.next();
  -                if (o instanceof RecorderEntry) {
  -                    ((RecorderEntry) o).close();
  -                } else if (o instanceof AntClassLoader) {
  -                    ((AntClassLoader) o).cleanup();
  -                }
  -            }
  -            
               newProject = null;
               Enumeration e = properties.elements();
               while (e.hasMoreElements()) {
  
  
  
  1.21      +1 -1      ant/src/main/org/apache/tools/ant/taskdefs/Recorder.java
  
  Index: Recorder.java
  ===================================================================
  RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/Recorder.java,v
  retrieving revision 1.20
  retrieving revision 1.21
  diff -u -r1.20 -r1.21
  --- Recorder.java     9 Mar 2004 16:48:06 -0000       1.20
  +++ Recorder.java     24 Jun 2004 11:16:41 -0000      1.21
  @@ -211,7 +211,7 @@
                   throw new BuildException("Problems creating a recorder 
entry",
                       ioe);
               }
  -            proj.addBuildListener(entry);
  +            entry.setProject(proj);
               recorderEntries.put(name, entry);
           } else {
               entry = (RecorderEntry) o;
  
  
  
  1.18      +49 -3     
ant/src/main/org/apache/tools/ant/taskdefs/RecorderEntry.java
  
  Index: RecorderEntry.java
  ===================================================================
  RCS file: 
/home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/RecorderEntry.java,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- RecorderEntry.java        23 Jun 2004 14:08:26 -0000      1.17
  +++ RecorderEntry.java        24 Jun 2004 11:16:41 -0000      1.18
  @@ -21,6 +21,7 @@
   import org.apache.tools.ant.BuildLogger;
   import org.apache.tools.ant.DefaultLogger;
   import org.apache.tools.ant.Project;
  +import org.apache.tools.ant.SubBuildListener;
   import org.apache.tools.ant.util.StringUtils;
   
   /**
  @@ -30,7 +31,7 @@
    * @version 0.5
    * @since Ant 1.4
    */
  -public class RecorderEntry implements BuildLogger {
  +public class RecorderEntry implements BuildLogger, SubBuildListener {
   
       //////////////////////////////////////////////////////////////////////
       // ATTRIBUTES
  @@ -47,6 +48,8 @@
       private long targetStartTime = 0L;
       /** Strip task banners if true.  */
       private boolean emacsMode = false;
  +    /** project instance the recorder is associated with */
  +    private Project project;
   
       //////////////////////////////////////////////////////////////////////
       // CONSTRUCTORS / INITIALIZERS
  @@ -99,7 +102,32 @@
                    + StringUtils.LINE_SEP);
               error.printStackTrace(out);
           }
  -        close();
  +        cleanup();
  +    }
  +
  +    /**
  +     * Cleans up any resources held by this recorder entry at the end
  +     * of a subbuild if it has been created for the subbuild's project
  +     * instance.
  +     *
  +     * @param event the buildFinished event
  +     *
  +     * @since Ant 1.6.2
  +     */
  +    public void subBuildFinished(BuildEvent event) {
  +        if (event.getProject() == project) {
  +            cleanup();
  +        }
  +    }
  +
  +    /**
  +     * Empty implementation to satisfy the BuildListener interface.
  +     *
  +     * @param event the buildStarted event
  +     *
  +     * @since Ant 1.6.2
  +     */
  +    public void subBuildStarted(BuildEvent event) {
       }
   
   
  @@ -209,11 +237,29 @@
       }
   
       /**
  +     * Set the project associated with this recorder entry.
  +     *
  +     * @param project the project instance
  +     *
        * @since 1.6.2
        */
  -    public void close() {
  +    public void setProject(Project project) {
  +        this.project = project;
  +        if (project != null) {
  +            project.addBuildListener(this);
  +        }
  +    }
  +
  +    /**
  +     * @since 1.6.2
  +     */
  +    public void cleanup() {
           out.flush();
           out.close();
  +        if (project != null) {
  +            project.removeBuildListener(this);
  +        }
  +        project = null;
       }
   }
   
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to