View Javadoc

1   package com.atlassian.plugin.util;
2   
3   import java.util.concurrent.Callable;
4   
5   import static java.util.concurrent.Executors.callable;
6   
7   /**
8    * Utility to run Runnable implementations in a different ClassLoader.
9    *
10   * @since 2.5.0
11   */
12  public class ContextClassLoaderSwitchingUtil
13  {
14      /**
15       * Executes the provided {@link Runnable} implementation in the specified {@link ClassLoader}.
16       * <p/>
17       * Utilises the {@link com.atlassian.plugin.util.ClassLoaderStack#push} method to save the old {@link ClassLoader} and 
18       * set the one specified as <code>newClassLoader</code>. {@link com.atlassian.plugin.util.ClassLoaderStack#pop} is
19       * called in a finally block to ensure the {@link ClassLoader} is set back to the original one.
20       *
21       * @param newClassLoader The {@link ClassLoader} to run the specified {@link Runnable} in.
22       * @param runnable The implementation to be run in the specified {@link ClassLoader}
23       */
24      public static void runInContext(ClassLoader newClassLoader, Runnable runnable)
25      {
26          try
27          {
28              runInContext(newClassLoader, callable(runnable));
29          }
30          catch (RuntimeException re)
31          {
32              throw re;
33          }
34          catch (Exception e)
35          {
36              // Do nothing, this can't happen
37          }
38      }
39      
40      /**
41       * Executes the provided {@link Callable} implementation in the specified {@link ClassLoader}.
42       * <p/>
43       * Utilises the {@link com.atlassian.plugin.util.ClassLoaderStack#push} method to save the old {@link ClassLoader} and
44       * set the one specified as <code>newClassLoader</code>. {@link com.atlassian.plugin.util.ClassLoaderStack#pop} is
45       * called in a finally block to ensure the {@link ClassLoader} is set back to the original one.
46       *
47       * @param newClassLoader The {@link ClassLoader} to run the specified {@link Runnable} in.
48       * @param callable The implementation to be run in the specified {@link ClassLoader}
49       * @return the result of the {@link Callable}
50       * @since 2.7.0
51       */
52      public static <T> T runInContext(ClassLoader newClassLoader, Callable<T> callable) throws Exception
53      {
54          ClassLoaderStack.push(newClassLoader);
55          try
56          {
57              return callable.call();
58          }
59          finally
60          {
61              ClassLoaderStack.pop();
62          }
63      }
64  }