bitronix.tm.utils.ClassLoaderUtils Maven / Gradle / Ivy
/*
* Copyright (C) 2006-2013 Bitronix Software (http://www.bitronix.be)
*
* 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 bitronix.tm.utils;
import bitronix.tm.internal.LogDebugCheck;
import java.io.InputStream;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Level;
/**
* Static utility methods for loading classes and resources.
*/
public class ClassLoaderUtils
{
private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(ClassLoaderUtils.class.toString());
private ClassLoaderUtils()
{
//Nothing needed
}
/**
* Method getAllInterfaces ...
*
* @param clazz
* of type Class ?
*
* @return Set Class
*/
public static Set> getAllInterfaces(Class> clazz)
{
Set> interfaces = new HashSet<>();
for (Class> intf : clazz.getInterfaces())
{
if (intf.getInterfaces().length > 0)
{
interfaces.addAll(getAllInterfaces(intf));
}
interfaces.add(intf);
}
if (clazz.getSuperclass() != null)
{
interfaces.addAll(getAllInterfaces(clazz.getSuperclass()));
}
if (clazz.isInterface())
{
interfaces.add(clazz);
}
return interfaces;
}
/**
* Get the class loader which can be used to generate proxies without leaking memory.
*
* @return the class loader which can be used to generate proxies without leaking memory.
*/
public static ClassLoader getClassLoader()
{
ClassLoader cl = Thread.currentThread()
.getContextClassLoader();
if (cl != null)
{
return new CascadingClassLoader(cl);
}
return ClassLoaderUtils.class.getClassLoader();
}
/**
* Load a class by name. Tries the current thread's context loader then falls back to {@link Class#forName(String)}.
*
* @param className
* name of the class to load.
*
* @return the loaded class.
*
* @throws ClassNotFoundException
* if the class cannot be found in the classpath.
*/
public static Class loadClass(String className) throws ClassNotFoundException
{
ClassLoader cl = Thread.currentThread()
.getContextClassLoader();
if (cl != null)
{
try
{
return new CascadingClassLoader(cl).loadClass(className);
}
catch (ClassNotFoundException ex)
{
if (LogDebugCheck.isDebugEnabled())
{
log.log(Level.FINER, "context classloader could not find class '" + className + "', trying Class.forName() instead", ex);
}
}
}
return Class.forName(className);
}
/**
* Load a resource from the classpath. Tries the current thread's context loader then falls back to
* {@link ClassLoader#getResourceAsStream(String)} using this class' classloader.
*
* @param resourceName
* the resource name to load.
*
* @return a {@link java.io.InputStream} if the resource could be found, null otherwise.
*/
public static InputStream getResourceAsStream(String resourceName)
{
ClassLoader cl = Thread.currentThread()
.getContextClassLoader();
if (cl != null)
{
return cl.getResourceAsStream(resourceName);
}
return ClassLoaderUtils.class.getClassLoader()
.getResourceAsStream(resourceName);
}
private static class CascadingClassLoader
extends ClassLoader
{
private final ClassLoader contextLoader;
/**
* Constructor CascadingClassLoader creates a new CascadingClassLoader instance.
*
* @param contextLoader
* of type ClassLoader
*/
CascadingClassLoader(ClassLoader contextLoader)
{
this.contextLoader = contextLoader;
}
/**
* Method findClass ...
*
* @param name
* of type String
*
* @return Class>
*
* @throws ClassNotFoundException
* when
*/
@Override
protected Class> findClass(String name) throws ClassNotFoundException
{
try
{
return contextLoader.loadClass(name);
}
catch (ClassNotFoundException cnfe)
{
log.log(Level.FINEST, "Class not found?", cnfe);
return CascadingClassLoader.class.getClassLoader()
.loadClass(name);
}
}
}
}