Browse Source

Set the thread context class loader when running <java> tasks

PR:	1085


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@269349 13f79535-47bb-0310-9956-ffa450edef68
master
Conor MacNeill 24 years ago
parent
commit
c234e7e183
2 changed files with 87 additions and 5 deletions
  1. +80
    -3
      src/main/org/apache/tools/ant/AntClassLoader.java
  2. +7
    -2
      src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java

+ 80
- 3
src/main/org/apache/tools/ant/AntClassLoader.java View File

@@ -203,20 +203,32 @@ public class AntClassLoader extends ClassLoader implements BuildListener {
* The parent class loader, if one is given or can be determined
*/
private ClassLoader parent = null;

/**
* The context loader saved when setting the thread's current context loader.
*/
private ClassLoader savedContextLoader = null;
private boolean isContextLoaderSaved = false;
private static Method getProtectionDomain = null;
private static Method defineClassProtectionDomain = null;
private static Method getContextClassLoader = null;
private static Method setContextClassLoader = null;
static {
try {
getProtectionDomain = Class.class.getMethod("getProtectionDomain", new Class[0]);
Class protectionDomain = Class.forName("java.security.ProtectionDomain");
Class[] args = new Class[] {String.class, byte[].class, Integer.TYPE, Integer.TYPE, protectionDomain};
defineClassProtectionDomain = ClassLoader.class.getDeclaredMethod("defineClass", args);
getContextClassLoader = Thread.class.getMethod("getContextClassLoader", new Class[0]);
args = new Class[] {ClassLoader.class};
setContextClassLoader = Thread.class.getMethod("setContextClassLoader", args);
}
catch (Exception e) {}
}

/**
* Create a classloader for the given project using the classpath given.
*
@@ -246,8 +258,12 @@ public class AntClassLoader extends ClassLoader implements BuildListener {
/**
* Create a classloader for the given project using the classpath given.
*
* @param parent the parent classloader to which unsatisfied loading attempts
* are delgated
* @param project the project to which this classloader is to belong.
* @param classpath the classpath to use to load the classes.
* @param parentFirst if true indicates that the parent classloader should be consulted
* before trying to load the a class through this loader.
*/
public AntClassLoader(ClassLoader parent, Project project, Path classpath,
boolean parentFirst) {
@@ -261,8 +277,13 @@ public class AntClassLoader extends ClassLoader implements BuildListener {
}

/**
* Create an empty class loader
* Create an empty class loader. The classloader should be configured with path elements
* to specify where the loader is to look for classes.
*
* @param parent the parent classloader to which unsatisfied loading attempts
* are delgated
* @param parentFirst if true indicates that the parent classloader should be consulted
* before trying to load the a class through this loader.
*/
public AntClassLoader(ClassLoader parent, boolean parentFirst) {
if (parent != null) {
@@ -275,6 +296,12 @@ public class AntClassLoader extends ClassLoader implements BuildListener {
this.parentFirst = parentFirst;
}
/**
* Log a message through the project object if one has been provided.
*
* @param message the message to log
* @param priority the logging priority of the message
*/
protected void log(String message, int priority) {
if (project != null) {
project.log(message, priority);
@@ -284,6 +311,55 @@ public class AntClassLoader extends ClassLoader implements BuildListener {
// }
}

/**
* Set the current thread's context loader to this classloader, storing the current
* loader value for later resetting
*/
public void setThreadContextLoader() {
if (isContextLoaderSaved) {
throw new BuildException("Context loader has not been reset");
}
if (getContextClassLoader != null && setContextClassLoader != null) {
try {
savedContextLoader
= (ClassLoader)getContextClassLoader.invoke(Thread.currentThread(), new Object[0]);
Object[] args = new Object[] {this};
setContextClassLoader.invoke(Thread.currentThread(), args);
isContextLoaderSaved = true;
}
catch (InvocationTargetException ite) {
Throwable t = ite.getTargetException();
throw new BuildException(t.toString());
}
catch (Exception e) {
throw new BuildException(e.toString());
}
}
}
/**
* Reset the current thread's context loader to its original value
*/
public void resetThreadContextLoader() {
if (isContextLoaderSaved &&
getContextClassLoader != null && setContextClassLoader != null) {
try {
Object[] args = new Object[] {savedContextLoader};
setContextClassLoader.invoke(Thread.currentThread(), args);
savedContextLoader = null;
isContextLoaderSaved = false;
}
catch (InvocationTargetException ite) {
Throwable t = ite.getTargetException();
throw new BuildException(t.toString());
}
catch (Exception e) {
throw new BuildException(e.toString());
}
}
}
/**
* Add an element to the classpath to be searched
*
@@ -869,7 +945,8 @@ public class AntClassLoader extends ClassLoader implements BuildListener {
}
}

public void buildStarted(BuildEvent event) {}
public void buildStarted(BuildEvent event) {
}

public void buildFinished(BuildEvent event) {
pathComponents = null;


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

@@ -104,6 +104,8 @@ public class ExecuteJava {

final String classname = javaCommand.getExecutable();
final Object[] argument = { javaCommand.getArguments() };

AntClassLoader loader = null;
try {
if (sysProperties != null) {
sysProperties.setSystem();
@@ -119,9 +121,9 @@ public class ExecuteJava {
if (classpath == null) {
target = Class.forName(classname);
} else {
AntClassLoader loader
= new AntClassLoader(project.getSystemLoader(), project, classpath, false);
loader = new AntClassLoader(project.getSystemLoader(), project, classpath, false);
loader.setIsolated(true);
loader.setThreadContextLoader();
target = loader.forceLoadClass(classname);
AntClassLoader.initializeClass(target);
}
@@ -142,6 +144,9 @@ public class ExecuteJava {
} catch (Exception e) {
throw new BuildException(e);
} finally {
if (loader != null) {
loader.resetThreadContextLoader();
}
if (sysProperties != null) {
sysProperties.restoreSystem();
}


Loading…
Cancel
Save