package backtype.storm.utils; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.apache.log4j.Logger; public class WorkerClassLoader extends URLClassLoader { public static Logger LOG = Logger.getLogger(WorkerClassLoader.class); private ClassLoader defaultClassLoader; private ClassLoader JDKClassLoader; protected static WorkerClassLoader instance; protected static boolean enable; protected static Map<Thread, ClassLoader> threadContextCache; protected WorkerClassLoader(URL[] urls, ClassLoader defaultClassLoader, ClassLoader JDKClassLoader) { super(urls, defaultClassLoader); this.defaultClassLoader = defaultClassLoader; this.JDKClassLoader = JDKClassLoader; // TODO Auto-generated constructor stub } @Override public Class<?> loadClass(String name) throws ClassNotFoundException { Class<?> result = null; result = this.findLoadedClass(name); if (result != null && result.getClassLoader() == this) { return result; } else { result = null; } try { result = JDKClassLoader.loadClass(name); if (result != null) return result; } catch (Exception e) { } try { if (name.startsWith("org.slf4j") == false && name.startsWith("org.apache.log4j") == false && name.startsWith("ch.qos.logback") == false && name.startsWith("backtype.storm") == false && name.startsWith("org.act.tstream.") == false) { result = findClass(name); if (result != null) { return result; } } } catch (Exception e) { } return defaultClassLoader.loadClass(name); } public static WorkerClassLoader mkInstance(URL[] urls, ClassLoader DefaultClassLoader, ClassLoader JDKClassLoader, boolean enable) { WorkerClassLoader.enable = enable; if (enable == false) { LOG.info("Don't enable UserDefine ClassLoader"); return null; } synchronized (WorkerClassLoader.class) { if (instance == null) { instance = new WorkerClassLoader(urls, DefaultClassLoader, JDKClassLoader); threadContextCache = new ConcurrentHashMap<Thread, ClassLoader>(); } } LOG.info("Successfully create classloader " + mk_list(urls)); return instance; } public static WorkerClassLoader getInstance() { return instance; } public static boolean isEnable() { return enable; } public static void switchThreadContext() { if (enable == false) { return; } Thread thread = Thread.currentThread(); ClassLoader oldClassLoader = thread.getContextClassLoader(); threadContextCache.put(thread, oldClassLoader); thread.setContextClassLoader(instance); } public static void restoreThreadContext() { if (enable == false) { return; } Thread thread = Thread.currentThread(); ClassLoader oldClassLoader = threadContextCache.get(thread); if (oldClassLoader != null) { thread.setContextClassLoader(oldClassLoader); } else { LOG.info("No context classloader of " + thread.getName()); } } private static <V> List<V> mk_list(V... args) { ArrayList<V> rtn = new ArrayList<V>(); for (V o : args) { rtn.add(o); } return rtn; } }