
org.globus.util.ClassLoaderUtils Maven / Gradle / Ivy
/*
* Copyright 1999-2010 University of Chicago
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is
* distributed on an "AS IS" BASIS,WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied.
*
* See the License for the specific language governing permissions and limitations under the License.
*/
package org.globus.util;
import java.io.InputStream;
/**
* Various classloader utils. Extends the standard ways of loading classes or
* resources with a fallback mechanism to the thread context classloader.
*/
public class ClassLoaderUtils {
private static DummySecurityManager MANAGER = new DummySecurityManager();
private static class DummySecurityManager extends SecurityManager {
public Class[] getClassContext() {
return super.getClassContext();
}
}
/**
* Returns the current execution stack as an array of classes.
*
* The length of the array is the number of methods on the execution stack.
* The element at index 0
is the class of the currently
* executing method, the element at index 1
is the class of
* that method's caller, and so on.
*
* @return the execution stack.
*/
public static Class[] getClassContext() {
return MANAGER.getClassContext();
}
/**
* Returns a class at specified depth of the current execution stack.
*
* @return the class at the specified depth of the current execution stack.
* Migth return null if depth is out of range.
*/
public static Class getClassContextAt(int i) {
Class[] classes = MANAGER.getClassContext();
if (classes != null && classes.length > i) {
return classes[i];
}
return null;
}
/**
* Returns a classloader at specified depth of the current execution stack.
*
* @return the classloader at the specified depth of the current execution
* stack. Migth return null if depth is out of range.
*/
public static ClassLoader getClassLoaderContextAt(int i) {
Class[] classes = MANAGER.getClassContext();
if (classes != null && classes.length > i) {
return classes[i].getClassLoader();
}
return null;
}
/**
* Gets an InputStream to a resource of a specified name. First, the
* caller's classloader is used to load the resource and if it fails the
* thread's context classloader is used to load the resource.
*/
public static InputStream getResourceAsStream(String name) {
// try with caller classloader
ClassLoader loader = getClassLoaderContextAt(3);
InputStream in = (loader == null) ? null : loader.getResourceAsStream(name);
if (in == null) {
// try with context classloader if set & different
ClassLoader contextLoader = Thread.currentThread().getContextClassLoader();
if (contextLoader != null && contextLoader != loader) {
in = contextLoader.getResourceAsStream(name);
}
}
return in;
}
/**
* Loads a specified class. First, the caller's classloader is used to load
* the class and if it fails the thread's context classloader is used to
* load the specified class.
*/
public static Class forName(String name) throws ClassNotFoundException {
// try with caller classloader
ClassLoader loader = getClassLoaderContextAt(3);
try {
return Class.forName(name, true, loader);
} catch (ClassNotFoundException e) {
// try with context classloader if set & different
ClassLoader contextLoader = Thread.currentThread().getContextClassLoader();
if (contextLoader == null || contextLoader == loader) {
throw e;
} else {
return Class.forName(name, true, contextLoader);
}
}
}
public static Class> loadClass(String className, Class> callingClass) throws ClassNotFoundException {
try {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
if (cl != null) {
return cl.loadClass(className);
}
} catch (ClassNotFoundException e) {
// ignore
}
return loadClass2(className, callingClass);
}
private static Class> loadClass2(String className, Class> callingClass) throws ClassNotFoundException {
try {
return Class.forName(className);
} catch (ClassNotFoundException ex) {
try {
if (ClassLoaderUtils.class.getClassLoader() != null) {
return ClassLoaderUtils.class.getClassLoader().loadClass(className);
}
} catch (ClassNotFoundException exc) {
if (callingClass != null && callingClass.getClassLoader() != null) {
return callingClass.getClassLoader().loadClass(className);
}
}
throw ex;
}
}
}