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><ant></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]