Browse Source

plug some more classloader leaks and mark those places where a leak remains and I don't see an obvious way to fix it

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@811435 13f79535-47bb-0310-9956-ffa450edef68
master
Stefan Bodewig 16 years ago
parent
commit
e931e7bad1
20 changed files with 116 additions and 23 deletions
  1. +7
    -2
      src/main/org/apache/tools/ant/taskdefs/Property.java
  2. +18
    -1
      src/main/org/apache/tools/ant/taskdefs/Rmic.java
  3. +8
    -2
      src/main/org/apache/tools/ant/taskdefs/WhichResource.java
  4. +1
    -0
      src/main/org/apache/tools/ant/taskdefs/compilers/CompilerAdapterFactory.java
  5. +9
    -4
      src/main/org/apache/tools/ant/taskdefs/condition/HasMethod.java
  6. +21
    -4
      src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java
  7. +1
    -0
      src/main/org/apache/tools/ant/taskdefs/optional/ejb/GenericDeploymentTool.java
  8. +9
    -1
      src/main/org/apache/tools/ant/taskdefs/optional/ejb/JonasDeploymentTool.java
  9. +9
    -5
      src/main/org/apache/tools/ant/taskdefs/optional/ejb/WebsphereDeploymentTool.java
  10. +8
    -1
      src/main/org/apache/tools/ant/taskdefs/optional/javacc/JavaCC.java
  11. +1
    -0
      src/main/org/apache/tools/ant/taskdefs/optional/javah/JavahAdapterFactory.java
  12. +9
    -1
      src/main/org/apache/tools/ant/taskdefs/optional/jsp/JspC.java
  13. +1
    -0
      src/main/org/apache/tools/ant/taskdefs/optional/jsp/compilers/JspCompilerAdapterFactory.java
  14. +8
    -1
      src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java
  15. +1
    -0
      src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/Native2AsciiAdapterFactory.java
  16. +1
    -0
      src/main/org/apache/tools/ant/taskdefs/rmic/RmicAdapterFactory.java
  17. +1
    -0
      src/main/org/apache/tools/ant/types/Mapper.java
  18. +1
    -1
      src/main/org/apache/tools/ant/types/XMLCatalog.java
  19. +1
    -0
      src/main/org/apache/tools/ant/types/selectors/ExtendSelector.java
  20. +1
    -0
      src/main/org/apache/tools/ant/types/selectors/modifiedselector/ModifiedSelector.java

+ 7
- 2
src/main/org/apache/tools/ant/taskdefs/Property.java View File

@@ -30,6 +30,7 @@ import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.Vector; import java.util.Vector;


import org.apache.tools.ant.AntClassLoader;
import org.apache.tools.ant.BuildException; import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project; import org.apache.tools.ant.Project;
import org.apache.tools.ant.PropertyHelper; import org.apache.tools.ant.PropertyHelper;
@@ -558,10 +559,11 @@ public class Property extends Task {
Properties props = new Properties(); Properties props = new Properties();
log("Resource Loading " + name, Project.MSG_VERBOSE); log("Resource Loading " + name, Project.MSG_VERBOSE);
InputStream is = null; InputStream is = null;
ClassLoader cL = null;
boolean cleanup = false;
try { try {
ClassLoader cL = null;

if (classpath != null) { if (classpath != null) {
cleanup = true;
cL = getProject().createClassLoader(classpath); cL = getProject().createClassLoader(classpath);
} else { } else {
cL = this.getClass().getClassLoader(); cL = this.getClass().getClassLoader();
@@ -589,6 +591,9 @@ public class Property extends Task {
// ignore // ignore
} }
} }
if (cleanup && cL != null) {
((AntClassLoader) cL).cleanup();
}
} }
} }




+ 18
- 1
src/main/org/apache/tools/ant/taskdefs/Rmic.java View File

@@ -21,6 +21,7 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.rmi.Remote; import java.rmi.Remote;
import java.util.Vector; import java.util.Vector;
import org.apache.tools.ant.AntClassLoader;
import org.apache.tools.ant.BuildException; import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Project; import org.apache.tools.ant.Project;
@@ -104,7 +105,7 @@ public class Rmic extends MatchingTask {


private Vector compileList = new Vector(); private Vector compileList = new Vector();


private ClassLoader loader = null;
private AntClassLoader loader = null;


private FacadeTaskHelper facade; private FacadeTaskHelper facade;
/** unable to verify message */ /** unable to verify message */
@@ -581,6 +582,7 @@ public class Rmic extends MatchingTask {
* if there's a problem with baseDir or RMIC * if there's a problem with baseDir or RMIC
*/ */
public void execute() throws BuildException { public void execute() throws BuildException {
try {
compileList.clear(); compileList.clear();


File outputDir = getOutputDir(); File outputDir = getOutputDir();
@@ -659,6 +661,21 @@ public class Rmic extends MatchingTask {
} }
} }
} }
} finally {
cleanup();
}
}

/**
* Cleans up resources.
*
* @since Ant 1.8.0
*/
protected void cleanup() {
if (loader != null) {
loader.cleanup();
loader = null;
}
} }


/** /**


+ 8
- 2
src/main/org/apache/tools/ant/taskdefs/WhichResource.java View File

@@ -126,15 +126,16 @@ public class WhichResource extends Task {
public void execute() throws BuildException { public void execute() throws BuildException {
validate(); validate();
if (classpath != null) { if (classpath != null) {
classpath = classpath.concatSystemClasspath("ignore");
getProject().log("using user supplied classpath: " + classpath, getProject().log("using user supplied classpath: " + classpath,
Project.MSG_DEBUG); Project.MSG_DEBUG);
classpath = classpath.concatSystemClasspath("ignore");
} else { } else {
classpath = new Path(getProject()); classpath = new Path(getProject());
classpath = classpath.concatSystemClasspath("only"); classpath = classpath.concatSystemClasspath("only");
getProject().log("using system classpath: " + classpath, Project.MSG_DEBUG); getProject().log("using system classpath: " + classpath, Project.MSG_DEBUG);
} }
AntClassLoader loader;
AntClassLoader loader = null;
try {
loader = AntClassLoader.newAntClassLoader(getProject().getCoreLoader(), loader = AntClassLoader.newAntClassLoader(getProject().getCoreLoader(),
getProject(), getProject(),
classpath, false); classpath, false);
@@ -160,6 +161,11 @@ public class WhichResource extends Task {
loc = url.toExternalForm(); loc = url.toExternalForm();
getProject().setNewProperty(property, loc); getProject().setNewProperty(property, loc);
} }
} finally {
if (loader != null) {
loader.cleanup();
}
}
} }


/** /**


+ 1
- 0
src/main/org/apache/tools/ant/taskdefs/compilers/CompilerAdapterFactory.java View File

@@ -152,6 +152,7 @@ public final class CompilerAdapterFactory {
return new Sj(); return new Sj();
} }
return resolveClassName(compilerType, return resolveClassName(compilerType,
// Memory-Leak in line below
task.getProject().createClassLoader(classpath)); task.getProject().createClassLoader(classpath));
} }




+ 9
- 4
src/main/org/apache/tools/ant/taskdefs/condition/HasMethod.java View File

@@ -110,7 +110,6 @@ public class HasMethod extends ProjectComponent implements Condition {
loader = getProject().createClassLoader(classpath); loader = getProject().createClassLoader(classpath);
loader.setParentFirst(false); loader.setParentFirst(false);
loader.addJavaLibraries(); loader.addJavaLibraries();
if (loader != null) {
try { try {
return loader.findClass(classname); return loader.findClass(classname);
} catch (SecurityException se) { } catch (SecurityException se) {
@@ -118,11 +117,9 @@ public class HasMethod extends ProjectComponent implements Condition {
// actually the case we're looking for in JDK 1.3+, // actually the case we're looking for in JDK 1.3+,
// so catch the exception and return // so catch the exception and return
return null; return null;
}
} else {
return null;
} }
} else if (loader != null) { } else if (loader != null) {
// How do we ever get here?
return loader.loadClass(classname); return loader.loadClass(classname);
} else { } else {
ClassLoader l = this.getClass().getClassLoader(); ClassLoader l = this.getClass().getClassLoader();
@@ -148,6 +145,8 @@ public class HasMethod extends ProjectComponent implements Condition {
if (classname == null) { if (classname == null) {
throw new BuildException("No classname defined"); throw new BuildException("No classname defined");
} }
ClassLoader preLoadClass = loader;
try {
Class clazz = loadClass(classname); Class clazz = loadClass(classname);
if (method != null) { if (method != null) {
return isMethodFound(clazz); return isMethodFound(clazz);
@@ -156,6 +155,12 @@ public class HasMethod extends ProjectComponent implements Condition {
return isFieldFound(clazz); return isFieldFound(clazz);
} }
throw new BuildException("Neither method nor field defined"); throw new BuildException("Neither method nor field defined");
} finally {
if (preLoadClass != loader && loader != null) {
loader.cleanup();
loader = null;
}
}
} }


private boolean isFieldFound(Class clazz) { private boolean isFieldFound(Class clazz) {


+ 21
- 4
src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java View File

@@ -103,6 +103,8 @@ public class XMLValidateTask extends Task {
public static final String MESSAGE_FILES_VALIDATED public static final String MESSAGE_FILES_VALIDATED
= " file(s) have been successfully validated."; = " file(s) have been successfully validated.";


private AntClassLoader readerLoader = null;

/** /**
* Specify how parser error are to be handled. * Specify how parser error are to be handled.
* Optional, default is <code>true</code>. * Optional, default is <code>true</code>.
@@ -285,7 +287,7 @@ public class XMLValidateTask extends Task {
* @throws BuildException if <code>failonerror</code> is true and an error happens * @throws BuildException if <code>failonerror</code> is true and an error happens
*/ */
public void execute() throws BuildException { public void execute() throws BuildException {
try {
int fileProcessed = 0; int fileProcessed = 0;
if (file == null && (filesets.size() == 0)) { if (file == null && (filesets.size() == 0)) {
throw new BuildException( throw new BuildException(
@@ -321,6 +323,9 @@ public class XMLValidateTask extends Task {
} }
} }
onSuccessfulValidation(fileProcessed); onSuccessfulValidation(fileProcessed);
} finally {
cleanup();
}
} }


/** /**
@@ -389,9 +394,9 @@ public class XMLValidateTask extends Task {
try { try {
// load the parser class // load the parser class
if (classpath != null) { if (classpath != null) {
AntClassLoader loader =
getProject().createClassLoader(classpath);
readerClass = Class.forName(readerClassName, true, loader);
readerLoader = getProject().createClassLoader(classpath);
readerClass = Class.forName(readerClassName, true,
readerLoader);
} else { } else {
readerClass = Class.forName(readerClassName); readerClass = Class.forName(readerClassName);
} }
@@ -431,6 +436,18 @@ public class XMLValidateTask extends Task {
return newReader; return newReader;
} }


/**
* Cleans up resources.
*
* @since Ant 1.8.0
*/
protected void cleanup() {
if (readerLoader != null) {
readerLoader.cleanup();
readerLoader = null;
}
}

/** /**
* *
* @return * @return


+ 1
- 0
src/main/org/apache/tools/ant/taskdefs/optional/ejb/GenericDeploymentTool.java View File

@@ -929,6 +929,7 @@ public class GenericDeploymentTool implements EJBDeploymentTool {
if (combinedClasspath == null) { if (combinedClasspath == null) {
classpathLoader = getClass().getClassLoader(); classpathLoader = getClass().getClassLoader();
} else { } else {
// Memory leak in line below
classpathLoader classpathLoader
= getTask().getProject().createClassLoader(combinedClasspath); = getTask().getProject().createClassLoader(combinedClasspath);
} }


+ 9
- 1
src/main/org/apache/tools/ant/taskdefs/optional/ejb/JonasDeploymentTool.java View File

@@ -679,7 +679,10 @@ public class JonasDeploymentTool extends GenericDeploymentTool {
log("Looking for GenIC class in classpath: " log("Looking for GenIC class in classpath: "
+ classpath.toString(), Project.MSG_VERBOSE); + classpath.toString(), Project.MSG_VERBOSE);


AntClassLoader cl = classpath.getProject().createClassLoader(classpath);
AntClassLoader cl = null;

try {
cl = classpath.getProject().createClassLoader(classpath);


try { try {
cl.loadClass(JonasDeploymentTool.GENIC_CLASS); cl.loadClass(JonasDeploymentTool.GENIC_CLASS);
@@ -716,6 +719,11 @@ public class JonasDeploymentTool extends GenericDeploymentTool {
+ "' not found in classpath.", + "' not found in classpath.",
Project.MSG_VERBOSE); Project.MSG_VERBOSE);
} }
} finally {
if (cl != null) {
cl.cleanup();
}
}
return null; return null;
} }




+ 9
- 5
src/main/org/apache/tools/ant/taskdefs/optional/ejb/WebsphereDeploymentTool.java View File

@@ -27,6 +27,7 @@ import java.util.Iterator;
import java.util.jar.JarEntry; import java.util.jar.JarEntry;
import java.util.jar.JarFile; import java.util.jar.JarFile;
import java.util.jar.JarOutputStream; import java.util.jar.JarOutputStream;
import org.apache.tools.ant.AntClassLoader;
import org.apache.tools.ant.BuildException; import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project; import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Java; import org.apache.tools.ant.taskdefs.Java;
@@ -589,11 +590,9 @@ public class WebsphereDeploymentTool extends GenericDeploymentTool {
classpath = getCombinedClasspath(); classpath = getCombinedClasspath();
} }


javaTask.setFork(true);
if (classpath != null) { if (classpath != null) {
javaTask.setClasspath(classpath); javaTask.setClasspath(classpath);
javaTask.setFork(true);
} else {
javaTask.setFork(true);
} }


log("Calling websphere.ejbdeploy for " + sourceJar.toString(), log("Calling websphere.ejbdeploy for " + sourceJar.toString(),
@@ -684,6 +683,7 @@ public class WebsphereDeploymentTool extends GenericDeploymentTool {
JarFile wasJar = null; JarFile wasJar = null;
File newwasJarFile = null; File newwasJarFile = null;
JarOutputStream newJarStream = null; JarOutputStream newJarStream = null;
ClassLoader genericLoader = null;


try { try {
log("Checking if websphere Jar needs to be rebuilt for jar " log("Checking if websphere Jar needs to be rebuilt for jar "
@@ -713,7 +713,7 @@ public class WebsphereDeploymentTool extends GenericDeploymentTool {
} }


//Cycle Through generic and make sure its in websphere //Cycle Through generic and make sure its in websphere
ClassLoader genericLoader = getClassLoaderFromJar(genericJarFile);
genericLoader = getClassLoaderFromJar(genericJarFile);


for (Enumeration e = genericEntries.keys(); e.hasMoreElements();) { for (Enumeration e = genericEntries.keys(); e.hasMoreElements();) {
String filepath = (String) e.nextElement(); String filepath = (String) e.nextElement();
@@ -861,6 +861,11 @@ public class WebsphereDeploymentTool extends GenericDeploymentTool {
rebuild = true; rebuild = true;
} }
} }
if (genericLoader != null
&& genericLoader instanceof AntClassLoader) {
AntClassLoader loader = (AntClassLoader) genericLoader;
loader.cleanup();
}
} }


return rebuild; return rebuild;
@@ -889,4 +894,3 @@ public class WebsphereDeploymentTool extends GenericDeploymentTool {
return getTask().getProject().createClassLoader(lookupPath); return getTask().getProject().createClassLoader(lookupPath);
} }
} }


+ 8
- 1
src/main/org/apache/tools/ant/taskdefs/optional/javacc/JavaCC.java View File

@@ -411,7 +411,9 @@ public class JavaCC extends Task {
String packagePrefix = null; String packagePrefix = null;
String mainClass = null; String mainClass = null;


AntClassLoader l =
AntClassLoader l = null;
try {
l =
AntClassLoader.newAntClassLoader(null, null, AntClassLoader.newAntClassLoader(null, null,
path path
.concatSystemClasspath("ignore"), .concatSystemClasspath("ignore"),
@@ -483,6 +485,11 @@ public class JavaCC extends Task {
throw new BuildException("unknown task type " + type); throw new BuildException("unknown task type " + type);
} }
return packagePrefix + mainClass; return packagePrefix + mainClass;
} finally {
if (l != null) {
l.cleanup();
}
}
} }


/** /**


+ 1
- 0
src/main/org/apache/tools/ant/taskdefs/optional/javah/JavahAdapterFactory.java View File

@@ -86,6 +86,7 @@ public class JavahAdapterFactory {
return new SunJavah(); return new SunJavah();
} else if (choice != null) { } else if (choice != null) {
return resolveClassName(choice, return resolveClassName(choice,
// Memory leak in line below
log.getProject() log.getProject()
.createClassLoader(classpath)); .createClassLoader(classpath));
} }


+ 9
- 1
src/main/org/apache/tools/ant/taskdefs/optional/jsp/JspC.java View File

@@ -22,6 +22,7 @@ import java.io.File;
import java.util.Date; import java.util.Date;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.Vector; import java.util.Vector;
import org.apache.tools.ant.AntClassLoader;
import org.apache.tools.ant.BuildException; import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Project; import org.apache.tools.ant.Project;
@@ -436,10 +437,12 @@ public class JspC extends MatchingTask {


File dest = getActualDestDir(); File dest = getActualDestDir();


AntClassLoader al = null;
try {
//bind to a compiler //bind to a compiler
JspCompilerAdapter compiler = JspCompilerAdapter compiler =
JspCompilerAdapterFactory.getCompiler(compilerName, this, JspCompilerAdapterFactory.getCompiler(compilerName, this,
getProject().createClassLoader(compilerClasspath));
al = getProject().createClassLoader(compilerClasspath));


//if we are a webapp, hand off to the compiler, which had better handle it //if we are a webapp, hand off to the compiler, which had better handle it
if (webApp != null) { if (webApp != null) {
@@ -503,6 +506,11 @@ public class JspC extends MatchingTask {
log("all files are up to date", Project.MSG_VERBOSE); log("all files are up to date", Project.MSG_VERBOSE);
} }
} }
} finally {
if (al != null) {
al.cleanup();
}
}
} }


/** /**


+ 1
- 0
src/main/org/apache/tools/ant/taskdefs/optional/jsp/compilers/JspCompilerAdapterFactory.java View File

@@ -54,6 +54,7 @@ public final class JspCompilerAdapterFactory {
public static JspCompilerAdapter getCompiler(String compilerType, Task task) public static JspCompilerAdapter getCompiler(String compilerType, Task task)
throws BuildException { throws BuildException {
return getCompiler(compilerType, task, return getCompiler(compilerType, task,
// Memory-Leak in line below
task.getProject().createClassLoader(null)); task.getProject().createClassLoader(null));
} }




+ 8
- 1
src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java View File

@@ -1108,7 +1108,9 @@ public class JUnitTask extends Task {
if (!cmd.haveClasspath()) { if (!cmd.haveClasspath()) {
return; return;
} }
AntClassLoader loader = AntClassLoader.newAntClassLoader(null,
AntClassLoader loader = null;
try {
loader = AntClassLoader.newAntClassLoader(null,
getProject(), cmd.createClasspath(getProject()), getProject(), cmd.createClasspath(getProject()),
true); true);
String projectResourceName = LoaderUtils.classNameToResource( String projectResourceName = LoaderUtils.classNameToResource(
@@ -1131,6 +1133,11 @@ public class JUnitTask extends Task {
} catch (Exception ex) { } catch (Exception ex) {
// Ignore exception // Ignore exception
} }
} finally {
if (loader != null) {
loader.cleanup();
}
}
} }


/** /**


+ 1
- 0
src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/Native2AsciiAdapterFactory.java View File

@@ -86,6 +86,7 @@ public class Native2AsciiAdapterFactory {
return new SunNative2Ascii(); return new SunNative2Ascii();
} else if (choice != null) { } else if (choice != null) {
return resolveClassName(choice, return resolveClassName(choice,
// Memory leak in line below
log.getProject() log.getProject()
.createClassLoader(classpath)); .createClassLoader(classpath));
} }


+ 1
- 0
src/main/org/apache/tools/ant/taskdefs/rmic/RmicAdapterFactory.java View File

@@ -118,6 +118,7 @@ public final class RmicAdapterFactory {
} }
//no match? ask for the non-lower-cased type //no match? ask for the non-lower-cased type
return resolveClassName(rmicType, return resolveClassName(rmicType,
// Memory leak in line below
task.getProject().createClassLoader(classpath)); task.getProject().createClassLoader(classpath));
} }




+ 1
- 0
src/main/org/apache/tools/ant/types/Mapper.java View File

@@ -261,6 +261,7 @@ public class Mapper extends DataType implements Cloneable {


ClassLoader loader = (classpath == null) ClassLoader loader = (classpath == null)
? getClass().getClassLoader() ? getClass().getClassLoader()
// Memory leak in line below
: getProject().createClassLoader(classpath); : getProject().createClassLoader(classpath);


return Class.forName(cName, true, loader); return Class.forName(cName, true, loader);


+ 1
- 1
src/main/org/apache/tools/ant/types/XMLCatalog.java View File

@@ -500,7 +500,7 @@ public class XMLCatalog extends DataType
if (catalogResolver == null) { if (catalogResolver == null) {


AntClassLoader loader = null; AntClassLoader loader = null;
// Memory-Leak in line below
loader = getProject().createClassLoader(Path.systemClasspath); loader = getProject().createClassLoader(Path.systemClasspath);


try { try {


+ 1
- 0
src/main/org/apache/tools/ant/types/selectors/ExtendSelector.java View File

@@ -65,6 +65,7 @@ public class ExtendSelector extends BaseSelector {
if (classpath == null) { if (classpath == null) {
c = Class.forName(classname); c = Class.forName(classname);
} else { } else {
// Memory-Leak in line below
AntClassLoader al AntClassLoader al
= getProject().createClassLoader(classpath); = getProject().createClassLoader(classpath);
c = Class.forName(classname, true, al); c = Class.forName(classname, true, al);


+ 1
- 0
src/main/org/apache/tools/ant/types/selectors/modifiedselector/ModifiedSelector.java View File

@@ -646,6 +646,7 @@ public class ModifiedSelector extends BaseExtendSelector
// the usual classloader // the usual classloader
? getClass().getClassLoader() ? getClass().getClassLoader()
// additional use the provided classpath // additional use the provided classpath
// Memory leak in line below
: getProject().createClassLoader(classpath); : getProject().createClassLoader(classpath);
} }
return myClassLoader; return myClassLoader;


Loading…
Cancel
Save