/** * Returns default class loader. By default, it is {@link #getContextClassLoader() threads context * class loader}. If this one is <code>null</code>, then class loader of the <b>caller class</b> * is returned. */ public static ClassLoader getDefaultClassLoader() { ClassLoader cl = getContextClassLoader(); if (cl == null) { Class callerClass = ReflectUtil.getCallerClass(2); cl = callerClass.getClassLoader(); } return cl; }
/** * Loads a class with a given name dynamically, more reliable then <code>Class.forName</code>. * * <p>Class will be loaded using class loaders in the following order: * * <ul> * <li>provided class loader (if any) * <li><code>Thread.currentThread().getContextClassLoader()}</code> * <li>caller classloader * <li>using <code>Class.forName</code> * </ul> */ public static Class loadClass(String className, ClassLoader classLoader) throws ClassNotFoundException { className = prepareClassnameForLoading(className); if ((className.indexOf('.') == -1) || (className.indexOf('[') == -1)) { // maybe a primitive int primitiveNdx = getPrimitiveClassNameIndex(className); if (primitiveNdx >= 0) { return PRIMITIVE_TYPES[primitiveNdx]; } } // try #1 - using provided class loader try { if (classLoader != null) { return classLoader.loadClass(className); } } catch (ClassNotFoundException ignore) { } // try #2 - using thread class loader ClassLoader currentThreadClassLoader = Thread.currentThread().getContextClassLoader(); if ((currentThreadClassLoader != null) && (currentThreadClassLoader != classLoader)) { try { return currentThreadClassLoader.loadClass(className); } catch (ClassNotFoundException ignore) { } } // try #3 - using caller classloader, similar as Class.forName() Class callerClass = ReflectUtil.getCallerClass(2); ClassLoader callerClassLoader = callerClass.getClassLoader(); if ((callerClassLoader != classLoader) && (callerClassLoader != currentThreadClassLoader)) { try { return callerClassLoader.loadClass(className); } catch (ClassNotFoundException ignore) { } } // try #4 - using Class.forName(). We must use this since for JDK >= 6 // arrays will be not loaded using classloader, but only with forName. try { return Class.forName(className); } catch (ClassNotFoundException ignore) { } throw new ClassNotFoundException("Class not found: " + className); }
/** * Retrieves given resource as URL. Resource is always absolute and may starts with a slash * character. * * <p>Resource will be loaded using class loaders in the following order: * * <ul> * <li>{@link Thread#getContextClassLoader() Thread.currentThread().getContextClassLoader()} * <li>{@link Class#getClassLoader() ClassLoaderUtil.class.getClassLoader()} * <li>if <code>callingClass</code> is provided: {@link Class#getClassLoader() * callingClass.getClassLoader()} * </ul> */ public static URL getResourceUrl(String resourceName, ClassLoader classLoader) { if (resourceName.startsWith("/")) { resourceName = resourceName.substring(1); } URL resourceUrl; // try #1 - using provided class loader if (classLoader != null) { resourceUrl = classLoader.getResource(resourceName); if (resourceUrl != null) { return resourceUrl; } } // try #2 - using thread class loader ClassLoader currentThreadClassLoader = Thread.currentThread().getContextClassLoader(); if ((currentThreadClassLoader != null) && (currentThreadClassLoader != classLoader)) { resourceUrl = currentThreadClassLoader.getResource(resourceName); if (resourceUrl != null) { return resourceUrl; } } // try #3 - using caller classloader, similar as Class.forName() Class callerClass = ReflectUtil.getCallerClass(2); ClassLoader callerClassLoader = callerClass.getClassLoader(); if ((callerClassLoader != classLoader) && (callerClassLoader != currentThreadClassLoader)) { resourceUrl = callerClassLoader.getResource(resourceName); if (resourceUrl != null) { return resourceUrl; } } return null; }