package com.revolsys.spring; import java.io.File; import java.io.FilenameFilter; import java.net.URL; import java.net.URLClassLoader; import java.util.Collection; import java.util.LinkedHashSet; import org.springframework.beans.factory.config.AbstractFactoryBean; import com.revolsys.io.FileUtil; import com.revolsys.io.filter.DirectoryFilenameFilter; import com.revolsys.io.filter.ExtensionFilenameFilter; public class ClassLoaderFactoryBean extends AbstractFactoryBean<ClassLoader> { private static final FilenameFilter JAR_FILTER = new ExtensionFilenameFilter("jar", "zip"); public static void addJars(final Collection<URL> urls, final File directory) { if (directory.exists() && directory.isDirectory()) { final File[] libFiles = directory.listFiles(JAR_FILTER); for (final File libFile : libFiles) { urls.add(FileUtil.toUrl(libFile)); } final File[] subDirs = directory.listFiles(new DirectoryFilenameFilter()); for (final File subDir : subDirs) { addJars(urls, subDir); } } } public static URLClassLoader newClassLoader(final ClassLoader parentClassLoader, final Collection<URL> urls) { URL[] urlArray = new URL[urls.size()]; urlArray = urls.toArray(urlArray); return new URLClassLoader(urlArray, parentClassLoader); } public static URLClassLoader newClassLoader(final ClassLoader parentClassLoader, final File file) { final Collection<URL> urls = new LinkedHashSet<>(); if (file.isDirectory()) { addJars(urls, file); } else if (JAR_FILTER.accept(file.getParentFile(), FileUtil.getFileName(file))) { urls.add(FileUtil.toUrl(file)); } return newClassLoader(parentClassLoader, urls); } private Collection<File> libDirectories = new LinkedHashSet<>(); private final Collection<URL> mergedUrls = new LinkedHashSet<>(); private Collection<URL> urls = new LinkedHashSet<>(); @Override protected ClassLoader createInstance() throws Exception { final Class<? extends ClassLoaderFactoryBean> clazz = getClass(); final ClassLoader parentClassLoader = clazz.getClassLoader(); final URLClassLoader classLoader = newClassLoader(parentClassLoader, this.mergedUrls); return classLoader; } public Collection<File> getLibDirectories() { return this.libDirectories; } @Override public Class<ClassLoader> getObjectType() { return ClassLoader.class; } public Collection<URL> getUrls() { return this.urls; } public void setLibDirectories(final Collection<File> libDirectories) { this.libDirectories = libDirectories; for (final File directory : libDirectories) { addJars(this.mergedUrls, directory); } } public void setUrls(final Collection<URL> urls) { this.urls = urls; this.mergedUrls.addAll(urls); } }