/** * jetbrick-template * http://subchen.github.io/jetbrick-template/ * * Copyright 2010-2014 Guoqiang Chen. All rights reserved. * Email: subchen@gmail.com * * 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 jetbrick.template.utils; import java.io.File; import java.io.IOException; import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; import java.util.*; /** * Moved from ClassUtils.java. * * @since 1.2.0 * @author Guoqiang Chen */ public class ClassLoaderUtils { public static final String EXT_CLASS_LOADER_NAME = "sun.misc.Launcher$ExtClassLoader"; public static final String APP_CLASS_LOADER_NAME = "sun.misc.Launcher$AppClassLoader"; private static final Map<String, String> abbreviationMap; /** * Returns current thread's context class loader */ public static ClassLoader getContextClassLoader() { ClassLoader loader = null; try { loader = Thread.currentThread().getContextClassLoader(); } catch (Throwable e) { } if (loader == null) { loader = ClassLoaderUtils.class.getClassLoader(); } return loader; } /** * 根据 classLoader 获取所有的 Classpath URLs. */ public static Collection<URL> getClasspathURLs(final ClassLoader classLoader) { Collection<URL> urls = new LinkedHashSet<URL>(32); ClassLoader loader = classLoader; while (loader != null) { String klassName = loader.getClass().getName(); if (EXT_CLASS_LOADER_NAME.equals(klassName)) { break; } if (loader instanceof URLClassLoader) { for (URL url : ((URLClassLoader) loader).getURLs()) { urls.add(url); } } else if (klassName.startsWith("weblogic.utils.classloaders.")) { // 该死的 WebLogic,只能特殊处理 // GenericClassLoader, FilteringClassLoader, ChangeAwareClassLoader try { Method method = loader.getClass().getMethod("getClassPath"); Object result = method.invoke(loader); if (result != null) { String[] paths = StringUtils.split(result.toString(), File.pathSeparatorChar); for (String path : paths) { urls.add(URLUtils.fromFile(path)); } } } catch (NoSuchMethodException e) { } catch (Exception e) { throw new RuntimeException(e); } } else if (klassName.startsWith("org.jboss.modules.ModuleClassLoader")) { // 该死的 Wildfly 8,只能特殊处理 try { Set<URL> urlSet = WildflyUtils.getClasspathURLs(loader, false); urls.addAll(urlSet); } catch (Exception e) { throw new RuntimeException(e); } } loader = loader.getParent(); } // moved jsp classpath from ServletContext.attributes to System.properties String jsp_classpath = System.getProperty("org.apache.catalina.jsp_classpath"); String classpath = System.getProperty("java.class.path"); classpath = StringUtils.trimToEmpty(classpath) + File.pathSeparatorChar + StringUtils.trimToEmpty(jsp_classpath); if (classpath.length() > 1) { String[] paths = StringUtils.split(classpath, File.pathSeparatorChar); for (String path : paths) { path = path.trim(); if (path.length() > 0) { URL url = URLUtils.fromFile(path); urls.add(url); } } } // 添加包含所有的 META-INF/MANIFEST.MF 的 jar 文件 try { Enumeration<URL> paths = classLoader.getResources("META-INF/MANIFEST.MF"); while (paths.hasMoreElements()) { URL url = paths.nextElement(); File file = URLUtils.toFileObject(url); urls.add(file.toURI().toURL()); } } catch (Exception e) { throw new RuntimeException(e); } // 删除 jdk 自带的 jar Iterator<URL> it = urls.iterator(); while (it.hasNext()) { String path = it.next().getPath(); if (path.contains("/jre/lib/")) { it.remove(); } } return urls; } /** * 根据 classLoader 获取指定 package 对应的 URLs. */ public static Collection<URL> getClasspathURLs(ClassLoader classLoader, String packageName) { if (packageName == null) { throw new IllegalArgumentException("PackageName must be not null."); } Collection<URL> urls = new ArrayList<URL>(); String dirname = packageName.replace('.', '/'); try { Enumeration<URL> dirs = classLoader.getResources(dirname); while (dirs.hasMoreElements()) { urls.add(dirs.nextElement()); } } catch (IOException e) { throw new RuntimeException(e); } return urls; } /** * 使用默认的 ClassLoader 去载入类. * @throws ClassNotFoundException */ public static Class<?> loadClass(final String qualifiedClassName) throws ClassNotFoundException { return loadClass(qualifiedClassName, null); } /** * 使用指定的 ClassLoader 去载入类. * @throws ClassNotFoundException */ public static Class<?> loadClass(final String qualifiedClassName, final ClassLoader classLoader) throws ClassNotFoundException { if (qualifiedClassName == null) { throw new NullPointerException("qualifiedClassName must not be null."); } ClassLoader loader = (classLoader == null) ? getContextClassLoader() : classLoader; // 尝试基本类型 if (abbreviationMap.containsKey(qualifiedClassName)) { String klassName = '[' + abbreviationMap.get(qualifiedClassName); return Class.forName(klassName, false, loader).getComponentType(); } // 尝试用 Class.forName() try { String klassName = getCanonicalClassName(qualifiedClassName); return Class.forName(klassName, false, loader); } catch (ClassNotFoundException e) { } // 尝试当做一个内部类去识别 if (qualifiedClassName.indexOf('$') == -1) { int ipos = qualifiedClassName.lastIndexOf('.'); if (ipos > 0) { try { String klassName = qualifiedClassName.substring(0, ipos) + '$' + qualifiedClassName.substring(ipos + 1); klassName = getCanonicalClassName(klassName); return Class.forName(klassName, false, loader); } catch (ClassNotFoundException e) { } } } throw new ClassNotFoundException("Class not found: " + qualifiedClassName); } /** * 将 Java 类名转为 {@code Class.forName()} 可以载入的类名格式. * <pre> * getCanonicalClassName("int") == "int"; * getCanonicalClassName("int[]") == "[I"; * getCanonicalClassName("java.lang.String") == "java.lang.String"; * getCanonicalClassName("java.lang.String[]") == "[Ljava.lang.String;"; * </pre> */ public static String getCanonicalClassName(String qualifiedClassName) { if (qualifiedClassName == null) { throw new NullPointerException("qualifiedClassName must not be null."); } String name = StringUtils.deleteWhitespace(qualifiedClassName); if (name.endsWith("[]")) { StringBuilder sb = new StringBuilder(); while (name.endsWith("[]")) { name = name.substring(0, name.length() - 2); sb.append('['); } String abbreviation = abbreviationMap.get(name); if (abbreviation != null) { sb.append(abbreviation); } else { sb.append('L').append(name).append(';'); } name = sb.toString(); } return name; } static { abbreviationMap = new HashMap<String, String>(); abbreviationMap.put("boolean", "Z"); abbreviationMap.put("byte", "B"); abbreviationMap.put("short", "S"); abbreviationMap.put("char", "C"); abbreviationMap.put("int", "I"); abbreviationMap.put("long", "J"); abbreviationMap.put("float", "F"); abbreviationMap.put("double", "D"); } }