mirror of
https://github.com/apache/sqoop.git
synced 2025-05-21 11:21:39 +08:00
SQOOP-2602: Sqoop2: Static initialization of ClassUtils defaultClassloader is fragile
(Abraham Fine via Jarek Jarcec Cecho)
This commit is contained in:
parent
a0ebf8f299
commit
89be1f7237
@ -50,14 +50,6 @@ public final class ClassUtils {
|
|||||||
private static final Class<?> NEGATIVE_CACHE_SENTINEL =
|
private static final Class<?> NEGATIVE_CACHE_SENTINEL =
|
||||||
NegativeCacheSentinel.class;
|
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
|
* A unique class which is used as a sentinel value in the caching
|
||||||
* for loadClass.
|
* for loadClass.
|
||||||
@ -74,7 +66,7 @@ private static abstract class NegativeCacheSentinel {}
|
|||||||
* @return Class instance or NULL
|
* @return Class instance or NULL
|
||||||
*/
|
*/
|
||||||
public static Class<?> loadClass(String className) {
|
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
|
* @return Instance of new class or NULL in case of any error
|
||||||
*/
|
*/
|
||||||
public static Object instantiate(String className, Object ... args) {
|
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
|
* @return Path on local filesystem to jar where given jar is present
|
||||||
*/
|
*/
|
||||||
public static String jarForClass(String className) {
|
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 jarPath = null;
|
||||||
String class_file = klass.getName().replaceAll("\\.", "/") + ".class";
|
String class_file = klass.getName().replaceAll("\\.", "/") + ".class";
|
||||||
try {
|
try {
|
||||||
URL url = defaultClassLoader.getResource(class_file);
|
URL url = getClassLoader().getResource(class_file);
|
||||||
String path = url.getPath();
|
String path = url.getPath();
|
||||||
path = URLDecoder.decode(path, "UTF-8");
|
path = URLDecoder.decode(path, "UTF-8");
|
||||||
if ("jar".equals(url.getProtocol())) {
|
if ("jar".equals(url.getProtocol())) {
|
||||||
@ -271,8 +263,12 @@ public static void clearCache() {
|
|||||||
CACHE_CLASSES.clear();
|
CACHE_CLASSES.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setDefaultClassLoader(ClassLoader classLoader) {
|
public static ClassLoader getClassLoader() {
|
||||||
defaultClassLoader = classLoader;
|
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
|
||||||
|
if (classLoader == null) {
|
||||||
|
classLoader = ClassUtils.class.getClassLoader();
|
||||||
|
}
|
||||||
|
return classLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClassUtils() {
|
private ClassUtils() {
|
||||||
|
@ -60,10 +60,10 @@ public void captureClassLoader() throws Exception {
|
|||||||
File jarFile = compileAJar();
|
File jarFile = compileAJar();
|
||||||
URL[] urlArray = { jarFile.toURI().toURL() };
|
URL[] urlArray = { jarFile.toURI().toURL() };
|
||||||
URLClassLoader newClassLoader = new URLClassLoader(urlArray, classLoader);
|
URLClassLoader newClassLoader = new URLClassLoader(urlArray, classLoader);
|
||||||
ClassUtils.setDefaultClassLoader(newClassLoader);
|
|
||||||
testAClass = newClassLoader.loadClass("A");
|
testAClass = newClassLoader.loadClass("A");
|
||||||
testParentClass = newClassLoader.loadClass("Parent");
|
testParentClass = newClassLoader.loadClass("Parent");
|
||||||
testChildClass = newClassLoader.loadClass("Child");
|
testChildClass = newClassLoader.loadClass("Child");
|
||||||
|
Thread.currentThread().setContextClassLoader(newClassLoader);
|
||||||
}
|
}
|
||||||
|
|
||||||
private File compileAJar() throws Exception{
|
private File compileAJar() throws Exception{
|
||||||
@ -159,7 +159,6 @@ private void addFileToJar(File source, JarOutputStream target) throws Exception
|
|||||||
@AfterMethod
|
@AfterMethod
|
||||||
public void restoreClassLoader() {
|
public void restoreClassLoader() {
|
||||||
Thread.currentThread().setContextClassLoader(classLoader);
|
Thread.currentThread().setContextClassLoader(classLoader);
|
||||||
ClassUtils.setDefaultClassLoader(classLoader);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
Loading…
Reference in New Issue
Block a user