All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.gdface.utils.ClassLoaderUtils Maven / Gradle / Ivy

There is a newer version: 3.2.1
Show newest version
package net.gdface.utils;

import java.io.File;
import java.io.FileFilter;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

/**
 * 根据指定的libdirs,classpath创建{@link URLClassLoader}的工具类
* classpath中{@value #TOOLS_JAR}代表 {@code $java_home/lib/tools.jar}
* 参见 {@link #toJarURLs(String...)} * @author guyadong * */ public class ClassLoaderUtils { public static final String TOOLS_JAR="${jdk_tools_jar}"; /** * {@code parent}为{@code null}时策略
* {@code defaultParentLoader} 使用default parent class loader,参见{@link URLClassLoader#newInstance(URL[])}
* {@code threadContextLoader} 使用当前线程的Thread Context ClassLoader作为parent,参见{@link Thread#getContextClassLoader()}
* {@code currentClassLoader} 使用当前类({@link ClassLoaderUtils})的class loader
* @author guyadong * */ public static enum ParentStrategy{ defaultParentLoader, threadContextLoader,currentClassLoader } /** * 默认值 {@link ParentStrategy#currentClassLoader } * @see {@link ParentStrategy} */ private static final ThreadLocal parentLoaderStrategy = new ThreadLocal(){ @Override protected ParentStrategy initialValue() { return ParentStrategy.currentClassLoader; }}; private static final boolean addIfJar(Collection out, File file) { if (file.isFile() && file.getName().endsWith(".jar")) { out.add(toURL(file)); return true; } return false; } private static final URL toURL(File file) { try { return file.toURI().toURL(); } catch (MalformedURLException e) { throw new RuntimeException(e); } } /** * 返回文件{@link URL}集合
* 如果 {@code file} 是文件夹,则文件夹所有jar包文件生成{@link URL} 集合
* 如果{@code file}是jar,则将返回包含该jar的{@link URL} 集合
* 如果不是jar抛出异常 * * @param file * 不存在时抛出异常 * @param recursive * 为 {@code true}时递归搜索子目录,{@code file}为文件夹时有效 * @return */ private static final Set toJarURLs(File file, final boolean recursive) { final HashSet out = new HashSet(); if (!file.exists()) throw new IllegalArgumentException(" not exists:" + file.toString()); if (file.isFile()) { if (!addIfJar(out, file)) throw new IllegalArgumentException(" not jar:" + file.toString()); } if (file.isDirectory()) { file.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { if (!addIfJar(out, pathname) && pathname.isDirectory() && recursive) { out.addAll(toJarURLs(pathname, recursive)); } return false; } }); return out; } throw new IllegalArgumentException(" invalid file:" + file.toString()); } private final static Set toJarURLs(String path, final boolean recursive) { if (null == path || 0 == path.length()) throw new IllegalArgumentException("path must not be null or empty "); return toJarURLs(new File(path), recursive); } private final static Set toJarURLs(final boolean recursive, String... paths) { if (null == paths) throw new NullPointerException("paths is null"); HashSet out = new HashSet(); for (String path : paths) { out.addAll(toJarURLs(path, recursive)); } return out; } private final static Set toJarURLs(String... classpath) { if (null == classpath) throw new NullPointerException("classpaths is null"); final HashSet out = new HashSet(); for (String path : classpath) { if (null == path || 0 == path.length()) throw new IllegalArgumentException("classPaths have null or empty element"); if(path.equals(TOOLS_JAR)){ path = getJdkToolsJar(); } File file = new File(path); if (!file.exists()) throw new IllegalArgumentException("no exists : " + file); if (file.isFile()) { if (!addIfJar(out, file)) throw new IllegalArgumentException("not jar:" + file); } else if (file.isDirectory()) out.add(toURL(file)); } return out; } private final static Set toJarURLs(boolean recursive, String[] libdirs, String[] classpath) { HashSet out = new HashSet(); if (null != libdirs) { out.addAll(toJarURLs(recursive, libdirs)); } if (null != classpath) out.addAll(toJarURLs(classpath)); return out; } /** @see #makeURLClassLoader(ClassLoader, boolean, String[], String[]) */ public final static URLClassLoader makeURLClassLoader(ClassLoader parent, String... classpath) { return makeURLClassLoader(parent, false, null, classpath); } /** @see #makeURLClassLoader(ClassLoader, boolean, String[], String[]) */ public final static URLClassLoader makeURLClassLoader(ClassLoader parent, boolean recursive, String... libdirs) { return makeURLClassLoader(parent, recursive, libdirs, null); } /** * 根据{@code libdirs}提供的lib路径和{@code classpath}创建{@link URLClassLoader}实例
* 如果所有的参数中都没有找URL(jar或class 文件夹),则抛出异常 * @param parent 指定父类加载器,为null时根据{@link #parentLoaderStrategy}决定parent * @param recursive * 指示是否递归搜索文件夹,对 {@code libdirs}有效,see also * {@link #toJarURLs(File, boolean)} * @param libdirs * path列表,path为jar包或jar所在文件夹(such as 'lib') * @param classpath * jar包或class文件夹路径 * * @return {@link URLClassLoader}实例 * @see URLClassLoader#newInstance(URL[],ClassLoader) * @see Thread#getContextClassLoader() */ public final static URLClassLoader makeURLClassLoader(ClassLoader parent, boolean recursive, String[] libdirs, String[] classpath) { Set out = toJarURLs(recursive, libdirs, classpath); if (out.isEmpty()) throw new IllegalArgumentException("empty libdirs and classpath"); if(null == parent){ switch(parentLoaderStrategy.get()){ case defaultParentLoader: return URLClassLoader.newInstance(out.toArray(new URL[out.size()])); case threadContextLoader: parent = Thread.currentThread().getContextClassLoader(); break; case currentClassLoader: parent = ClassLoaderUtils.class.getClassLoader(); break; } } return URLClassLoader.newInstance(out.toArray(new URL[out.size()]),parent); } /** @see #makeURLClassLoader(ClassLoader, boolean, String[], String[]) */ public final static URLClassLoader makeURLClassLoader(ClassLoader parent, boolean recursive, Collection libdirs, Collection classpath) { return makeURLClassLoader(parent, recursive, null == libdirs ? null : libdirs.toArray(new String[0]), null == classpath ? null : classpath.toArray(new String[0])); } /** * @param parentLoaderStrategy if null,{@link ParentStrategy#currentClassLoader} instead * @see #makeURLClassLoader(ClassLoader, boolean, String[], String[]) * @see #parentLoaderStrategy */ public final static void setParentLoaderStrategy(ParentStrategy parentLoaderStrategy){ ClassLoaderUtils.parentLoaderStrategy.set(null == parentLoaderStrategy ?ParentStrategy.currentClassLoader :parentLoaderStrategy); } /** @see #setParentLoaderStrategy(ParentStrategy) */ public final static void setParentLoaderStrategy(String parentLoaderStrategy){ setParentLoaderStrategy(ParentStrategy.valueOf(parentLoaderStrategy)); } /** 返回 jdk/lib/tools.jar路径 */ public static String getJdkToolsJar(){ StringBuffer buffer = new StringBuffer(); buffer.append(System.getProperty("java.home")).append(File.separatorChar); if(System.getProperty("os.name").indexOf("Mac OS")<0){ buffer.append("..").append(File.separatorChar).append("lib").append(File.separatorChar).append("tools.jar"); }else buffer.append("../Classes/classes.jar"); return buffer.toString(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy