Improve ClassLoaderUtils.loadClassWithTCCL() 61/70661/1
authorRobert Varga <robert.varga@pantheon.tech>
Mon, 9 Apr 2018 13:38:33 +0000 (15:38 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Mon, 9 Apr 2018 13:46:51 +0000 (15:46 +0200)
There are scenarios when we do not have a Thread Context Class Loader,
such as when executing from Netty's GlobalEventExecutor. When we attempt
to load a class in that scenario, the method will throw a NPE, which
exposes users which can deal with the class not being able to load
to a RuntimeException -- preventing recovery.

Detect the case when TCCL is null and report a failure to load the class,
noting the reason for the failure.

Change-Id: Ia6837ba451d290a2070bc24e9e7088c60275cae0
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
(cherry picked from commit 4a3cc19a42b3740ec518569ca274153b66f2bc82)

common/util/src/main/java/org/opendaylight/yangtools/util/ClassLoaderUtils.java

index 6e65b03658f58b55b3268dd03d9af9fffb49fbc7..b5064080ad93757a026209fdabcb17005af71da9 100644 (file)
@@ -130,14 +130,28 @@ public final class ClassLoaderUtils {
     }
 
     public static Class<?> loadClassWithTCCL(final String name) throws ClassNotFoundException {
-        return loadClass(Thread.currentThread().getContextClassLoader(), name);
+        final Thread thread = Thread.currentThread();
+        final ClassLoader tccl = thread.getContextClassLoader();
+        if (tccl == null) {
+            throw new ClassNotFoundException("Thread " + thread + " does not have a Context Class Loader, cannot load "
+                    + name);
+        }
+        return loadClass(tccl, name);
     }
 
-    public static Class<?> tryToLoadClassWithTCCL(final String fullyQualifiedName) {
+    public static Class<?> tryToLoadClassWithTCCL(final String fullyQualifiedClassName) {
+        final Thread thread = Thread.currentThread();
+        final ClassLoader tccl = thread.getContextClassLoader();
+        if (tccl == null) {
+            LOG.debug("Thread {} does not have a Context Class Loader, not loading class {}", thread,
+                fullyQualifiedClassName);
+            return null;
+        }
+
         try {
-            return loadClassWithTCCL(fullyQualifiedName);
+            return loadClass(tccl, fullyQualifiedClassName);
         } catch (final ClassNotFoundException e) {
-            LOG.debug("Failed to load class {}", fullyQualifiedName, e);
+            LOG.debug("Failed to load class {}", fullyQualifiedClassName, e);
             return null;
         }
     }