Author: bodewig
Date: Tue Sep 1 14:56:06 2009
New Revision: 810080
URL: http://svn.apache.org/viewvc?rev=810080&view=rev
Log:
filterchains leak classloaders, PR 45439
Modified:
ant/core/trunk/WHATSNEW
ant/core/trunk/src/main/org/apache/tools/ant/filters/util/ChainReaderHelper.java
Modified: ant/core/trunk/WHATSNEW
URL:
http://svn.apache.org/viewvc/ant/core/trunk/WHATSNEW?rev=810080&r1=810079&r2=810080&view=diff
==============================================================================
--- ant/core/trunk/WHATSNEW (original)
+++ ant/core/trunk/WHATSNEW Tue Sep 1 14:56:06 2009
@@ -474,6 +474,12 @@
it was scanning the same filesets more than once.
Bugzilla Report 43574.
+ * when using custom filterreaders with the <filterreader classname="">
+ syntax Ant could leak memory.
+ The problem didn't occur when using <typedef> or <componentdef> to
+ define the filterreader which is the recommended approach.
+ Bugzilla Report 45439.
+
Other changes:
--------------
Modified:
ant/core/trunk/src/main/org/apache/tools/ant/filters/util/ChainReaderHelper.java
URL:
http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/filters/util/ChainReaderHelper.java?rev=810080&r1=810079&r2=810080&view=diff
==============================================================================
---
ant/core/trunk/src/main/org/apache/tools/ant/filters/util/ChainReaderHelper.java
(original)
+++
ant/core/trunk/src/main/org/apache/tools/ant/filters/util/ChainReaderHelper.java
Tue Sep 1 14:56:06 2009
@@ -22,6 +22,8 @@
import java.io.Reader;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Iterator;
import java.util.Vector;
import org.apache.tools.ant.AntClassLoader;
import org.apache.tools.ant.BuildException;
@@ -120,6 +122,8 @@
Reader instream = primaryReader;
final int filterReadersCount = filterChains.size();
final Vector finalFilters = new Vector();
+ final ArrayList/*<AntClassLoader>*/ classLoadersToCleanUp =
+ new ArrayList/*<AntClassLoader>*/();
for (int i = 0; i < filterReadersCount; i++) {
final FilterChain filterchain =
@@ -152,6 +156,7 @@
AntClassLoader al
= pro.createClassLoader(classpath);
clazz = Class.forName(className, true, al);
+ classLoadersToCleanUp.add(al);
}
if (clazz != null) {
if
(!FilterReader.class.isAssignableFrom(clazz)) {
@@ -204,7 +209,24 @@
}
}
}
- return instream;
+ final Reader finalReader = instream;
+ return classLoadersToCleanUp.size() == 0 ? finalReader
+ : new FilterReader(finalReader) {
+ public void close() throws IOException {
+ FileUtils.close(in);
+ for (Iterator it = classLoadersToCleanUp.iterator();
+ it.hasNext(); ) {
+ ((AntClassLoader) it.next()).cleanup();
+ }
+ }
+ protected void finalize() throws Throwable {
+ try {
+ close();
+ } finally {
+ super.finalize();
+ }
+ }
+ };
}
/**