Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
net.gdface.utils.ClassLoaderUtils Maven / Gradle / Ivy
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();
}
}