From 89be1f7237277d4038660913259a8965c33c4011 Mon Sep 17 00:00:00 2001 From: Jarek Jarcec Cecho Date: Mon, 5 Oct 2015 16:15:04 -0700 Subject: [PATCH] SQOOP-2602: Sqoop2: Static initialization of ClassUtils defaultClassloader is fragile (Abraham Fine via Jarek Jarcec Cecho) --- .../org/apache/sqoop/utils/ClassUtils.java | 24 ++++++++----------- .../apache/sqoop/utils/TestClassUtils.java | 3 +-- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/common/src/main/java/org/apache/sqoop/utils/ClassUtils.java b/common/src/main/java/org/apache/sqoop/utils/ClassUtils.java index ca438486..ed689884 100644 --- a/common/src/main/java/org/apache/sqoop/utils/ClassUtils.java +++ b/common/src/main/java/org/apache/sqoop/utils/ClassUtils.java @@ -50,14 +50,6 @@ public final class ClassUtils { private static final Class NEGATIVE_CACHE_SENTINEL = NegativeCacheSentinel.class; - private static ClassLoader defaultClassLoader; - static { - defaultClassLoader = Thread.currentThread().getContextClassLoader(); - if (defaultClassLoader == null) { - defaultClassLoader = ClassUtils.class.getClassLoader(); - } - } - /** * A unique class which is used as a sentinel value in the caching * for loadClass. @@ -74,7 +66,7 @@ private static abstract class NegativeCacheSentinel {} * @return Class instance or NULL */ public static Class loadClass(String className) { - return loadClassWithClassLoader(className, defaultClassLoader); + return loadClassWithClassLoader(className, getClassLoader()); } /** @@ -139,7 +131,7 @@ public static Class loadClassWithClassLoader(String className, ClassLoader lo * @return Instance of new class or NULL in case of any error */ public static Object instantiate(String className, Object ... args) { - return instantiateWithClassLoader(className, defaultClassLoader, args); + return instantiateWithClassLoader(className, getClassLoader(), args); } /** @@ -196,7 +188,7 @@ public static Object instantiate(Class klass, Object ... args) { * @return Path on local filesystem to jar where given jar is present */ public static String jarForClass(String className) { - return jarForClassWithClassLoader(className, defaultClassLoader); + return jarForClassWithClassLoader(className, getClassLoader()); } /** @@ -223,7 +215,7 @@ public static String jarForClass(Class klass) { String jarPath = null; String class_file = klass.getName().replaceAll("\\.", "/") + ".class"; try { - URL url = defaultClassLoader.getResource(class_file); + URL url = getClassLoader().getResource(class_file); String path = url.getPath(); path = URLDecoder.decode(path, "UTF-8"); if ("jar".equals(url.getProtocol())) { @@ -271,8 +263,12 @@ public static void clearCache() { CACHE_CLASSES.clear(); } - public static void setDefaultClassLoader(ClassLoader classLoader) { - defaultClassLoader = classLoader; + public static ClassLoader getClassLoader() { + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + if (classLoader == null) { + classLoader = ClassUtils.class.getClassLoader(); + } + return classLoader; } private ClassUtils() { diff --git a/common/src/test/java/org/apache/sqoop/utils/TestClassUtils.java b/common/src/test/java/org/apache/sqoop/utils/TestClassUtils.java index 8851440c..674ae6a5 100644 --- a/common/src/test/java/org/apache/sqoop/utils/TestClassUtils.java +++ b/common/src/test/java/org/apache/sqoop/utils/TestClassUtils.java @@ -60,10 +60,10 @@ public void captureClassLoader() throws Exception { File jarFile = compileAJar(); URL[] urlArray = { jarFile.toURI().toURL() }; URLClassLoader newClassLoader = new URLClassLoader(urlArray, classLoader); - ClassUtils.setDefaultClassLoader(newClassLoader); testAClass = newClassLoader.loadClass("A"); testParentClass = newClassLoader.loadClass("Parent"); testChildClass = newClassLoader.loadClass("Child"); + Thread.currentThread().setContextClassLoader(newClassLoader); } private File compileAJar() throws Exception{ @@ -159,7 +159,6 @@ private void addFileToJar(File source, JarOutputStream target) throws Exception @AfterMethod public void restoreClassLoader() { Thread.currentThread().setContextClassLoader(classLoader); - ClassUtils.setDefaultClassLoader(classLoader); } @Test