[jboss-cvs] JBossAS SVN: r91943 - projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Tue Aug 4 00:45:31 EDT 2009


Author: david.lloyd at jboss.com
Date: 2009-08-04 00:45:31 -0400 (Tue, 04 Aug 2009)
New Revision: 91943

Added:
   projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ContextClassLoaderSavingRunnable.java
Modified:
   projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/JBossExecutors.java
Log:
Add task wrapper which copies the creator's context classloader

Added: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ContextClassLoaderSavingRunnable.java
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ContextClassLoaderSavingRunnable.java	                        (rev 0)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ContextClassLoaderSavingRunnable.java	2009-08-04 04:45:31 UTC (rev 91943)
@@ -0,0 +1,44 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads;
+
+class ContextClassLoaderSavingRunnable implements Runnable {
+
+    private final ClassLoader loader;
+    private final Runnable delegate;
+
+    ContextClassLoaderSavingRunnable(final ClassLoader loader, final Runnable delegate) {
+        this.loader = loader;
+        this.delegate = delegate;
+    }
+
+    public void run() {
+        final Thread currentThread = Thread.currentThread();
+        final ClassLoader old = JBossExecutors.getAndSetContextClassLoader(currentThread, loader);
+        try {
+            delegate.run();
+        } finally {
+            JBossExecutors.setContextClassLoader(currentThread, old);
+        }
+    }
+}

Modified: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/JBossExecutors.java
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/JBossExecutors.java	2009-08-04 04:37:41 UTC (rev 91942)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/JBossExecutors.java	2009-08-04 04:45:31 UTC (rev 91943)
@@ -47,6 +47,7 @@
 
     private static final RuntimePermission MODIFY_THREAD_PERMISSION = new RuntimePermission("modifyThread");
     private static final RuntimePermission CREATE_PRIVILEGED_THREAD_PERMISSION = new RuntimePermission("createPrivilegedThreads");
+    private static final RuntimePermission COPY_CONTEXT_CLASSLOADER_PERMISSION = new RuntimePermission("copyClassLoader");
 
     private static final AccessControlContext PRIVILEGED_CONTEXT = AccessController.doPrivileged(new PrivilegedAction<AccessControlContext>() {
         public AccessControlContext run() {
@@ -544,6 +545,82 @@
     }
 
     /**
+     * Create a task that delegates to the given task, preserving the context classloader which was in effect when
+     * this method was invoked.
+     *
+     * @param delegate the delegate runnable
+     * @return the wrapping runnable
+     */
+    public static Runnable classLoaderPreservingTask(final Runnable delegate) {
+        final SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(COPY_CONTEXT_CLASSLOADER_PERMISSION);
+        }
+        final ClassLoader loader = getContextClassLoader(Thread.currentThread());
+        return new ContextClassLoaderSavingRunnable(loader, delegate);
+    }
+
+    /**
+     * Privileged method to get the context class loader of the given thread.
+     *
+     * @param thread the thread to introspect
+     * @return the context class loader
+     */
+    static ClassLoader getContextClassLoader(final Thread thread) {
+        if (System.getSecurityManager() != null) {
+            return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+                public ClassLoader run() {
+                    return thread.getContextClassLoader();
+                }
+            });
+        } else {
+            return thread.getContextClassLoader();
+        }
+    }
+
+    /**
+     * Privileged method to get and set the context class loader of the given thread.
+     *
+     * @param thread the thread to introspect
+     * @param newClassLoader the new context class loader
+     * @return the old context class loader
+     */
+    static ClassLoader getAndSetContextClassLoader(final Thread thread, final ClassLoader newClassLoader) {
+        if (System.getSecurityManager() != null) {
+            return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+                public ClassLoader run() {
+                    final ClassLoader old = thread.getContextClassLoader();
+                    thread.setContextClassLoader(newClassLoader);
+                    return old;
+                }
+            });
+        } else {
+            final ClassLoader old = thread.getContextClassLoader();
+            thread.setContextClassLoader(newClassLoader);
+            return old;
+        }
+    }
+
+    /**
+     * Privileged method to set the context class loader of the given thread.
+     *
+     * @param thread the thread to introspect
+     * @param classLoader the new context class loader
+     */
+    static void setContextClassLoader(final Thread thread, final ClassLoader classLoader) {
+        if (System.getSecurityManager() != null) {
+            AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                public Void run() {
+                    thread.setContextClassLoader(classLoader);
+                    return null;
+                }
+            });
+        } else {
+            thread.setContextClassLoader(classLoader);
+        }
+    }
+
+    /**
      * Create a task that is a composite of several other tasks.
      *
      * @param runnables the tasks




More information about the jboss-cvs-commits mailing list