From 0d63880cccc77def418c52f41cfdef4f57a8c5fe Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Tue, 1 Sep 2009 14:56:06 +0000 Subject: [PATCH] filterchains leak classloaders, PR 45439 git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@810080 13f79535-47bb-0310-9956-ffa450edef68 --- WHATSNEW | 6 +++++ .../ant/filters/util/ChainReaderHelper.java | 24 ++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/WHATSNEW b/WHATSNEW index 3ae4a3c08..2bcb7e727 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -474,6 +474,12 @@ Fixed bugs: it was scanning the same filesets more than once. Bugzilla Report 43574. + * when using custom filterreaders with the + syntax Ant could leak memory. + The problem didn't occur when using or to + define the filterreader which is the recommended approach. + Bugzilla Report 45439. + Other changes: -------------- diff --git a/src/main/org/apache/tools/ant/filters/util/ChainReaderHelper.java b/src/main/org/apache/tools/ant/filters/util/ChainReaderHelper.java index aa76c2ffe..068a5580b 100644 --- a/src/main/org/apache/tools/ant/filters/util/ChainReaderHelper.java +++ b/src/main/org/apache/tools/ant/filters/util/ChainReaderHelper.java @@ -22,6 +22,8 @@ import java.io.IOException; 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 @@ public final class ChainReaderHelper { Reader instream = primaryReader; final int filterReadersCount = filterChains.size(); final Vector finalFilters = new Vector(); + final ArrayList/**/ classLoadersToCleanUp = + new ArrayList/**/(); for (int i = 0; i < filterReadersCount; i++) { final FilterChain filterchain = @@ -152,6 +156,7 @@ public final class ChainReaderHelper { 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 @@ public final class ChainReaderHelper { } } } - 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(); + } + } + }; } /**