From c234e7e18342b186b88cd7ddd65d3cc8c9946fd1 Mon Sep 17 00:00:00 2001 From: Conor MacNeill Date: Tue, 17 Jul 2001 14:19:12 +0000 Subject: [PATCH] Set the thread context class loader when running tasks PR: 1085 git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@269349 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/tools/ant/AntClassLoader.java | 83 ++++++++++++++++++- .../tools/ant/taskdefs/ExecuteJava.java | 9 +- 2 files changed, 87 insertions(+), 5 deletions(-) diff --git a/src/main/org/apache/tools/ant/AntClassLoader.java b/src/main/org/apache/tools/ant/AntClassLoader.java index 42d138d27..d6ff79ccb 100644 --- a/src/main/org/apache/tools/ant/AntClassLoader.java +++ b/src/main/org/apache/tools/ant/AntClassLoader.java @@ -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; diff --git a/src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java b/src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java index f85f5fec9..39854316a 100644 --- a/src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java +++ b/src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java @@ -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(); }