Uploaded image for project: 'Red Hat Fuse'
  1. Red Hat Fuse
  2. ENTESB-4487

ContextClassLoaderUtils class from pax-swissbox-core should reset TCCL back even though original value is null in it's doWithClassLoader() function

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Done
    • Icon: Major Major
    • jboss-fuse-6.1-patches
    • jboss-fuse-6.1
    • Karaf
    • None
    • % %

      In the implementation of pax-swissbox-core org.ops4j.pax.swissbox.core.ContextClassLoaderUtils.java class doWithClassLoader() function, the TCCL is only reset if "backupClassLoader" is non null.

      public static <V> V doWithClassLoader(final ClassLoader classLoader, 
                                            final Callable<V> callable ) 
                                            throws Exception {
          Thread currentThread = null;
          ClassLoader backupClassLoader = null;
          try {
              if( classLoader != null ) {
                  currentThread = Thread.currentThread();
                  backupClassLoader = currentThread.getContextClassLoader();
                  currentThread.setContextClassLoader( classLoader );
              }
              return callable.call();
          } finally {
              if( backupClassLoader != null ) { //--> THIS IS BAD !
                  currentThread.setContextClassLoader( backupClassLoader );
              }
          }
      }
      

      From the JavaDoc of Thread.getContextClassLoader():
      http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#getContextClassLoader()

      Returns:
      the context ClassLoader for this Thread, or null indicating the system class loader (or, failing that, the bootstrap class loader)

      It does support returning a NULL TCCL and we should reset TCCL to it's original value regardless whether it is null or not. Otherwise, in case that the "backupClassLoader " is null, it will just keep the other class loader "classLoader " as it's TCCL. Suggested code change should look like :

      public static <V> V doWithClassLoader( final ClassLoader classLoader, final Callable<V> callable )
                  throws Exception {
              
              if (classLoader != null) {
                  Thread currentThread = Thread.currentThread();
                  ClassLoader backupClassLoader = currentThread.getContextClassLoader();
                  currentThread.setContextClassLoader(classLoader);
                  try {
                      return callable.call();
                  } finally {
                      currentThread.setContextClassLoader(backupClassLoader);
                  }
              } else {
                  return callable.call();
              }
          }
      

      Note, you might also need to take care of checking the "classLoader" to see if it is a null in order to avoid NPE if you only want to change the finally block.

      In addition, the org.ops4j.pax.swissbox.core.ContextClassLoaderUtils class is compiled into many different projects as part of the bundle, such as pax-swiss-box-core-1.6.0.jar, pax-web-runtime-3.0.6.jar, pax-web-spi-3.0.6.jar, pax-web-extender-war-3.0.6.jar, pax-web-extender-whiteboard-3.0.6.jar, pax-web-jsp-3.0.6.jar.... for instance:

      jluo@/apps/jboss/fuse/6.1/orig/jboss-fuse-6.1.0.redhat-379/system/org/ops4j/pax/web/pax-web-runtime/3.0.6
      jluomac$ jar tvf pax-web-runtime-3.0.6.jar |grep org/ops4j/pax/swissbox/core
           0 Sun Jan 12 19:36:40 GMT 2014 org/ops4j/pax/swissbox/core/
        1151 Wed Dec 26 20:02:00 GMT 2012 org/ops4j/pax/swissbox/core/BundleClassLoader$1.class
        1250 Wed Dec 26 20:02:00 GMT 2012 org/ops4j/pax/swissbox/core/BundleClassLoader$EmptyEnumeration.class
        4410 Wed Dec 26 20:02:00 GMT 2012 org/ops4j/pax/swissbox/core/BundleClassLoader.class
        3022 Wed Dec 26 20:02:00 GMT 2012 org/ops4j/pax/swissbox/core/BundleUtils.class
        1285 Wed Dec 26 20:02:00 GMT 2012 org/ops4j/pax/swissbox/core/ContextClassLoaderUtils.class
      

      Once we fixed pax-swissbox-core bundle for the org.ops4j.pax.swissbox.core.ContextClassLoaderUtils.java class, we will need to rebuild all of those projects in order to pick up the change.

              ggrzybek Grzegorz Grzybek
              rhn-support-qluo Joe Luo
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

                Created:
                Updated:
                Resolved: