Skip to content

Instantly share code, notes, and snippets.

@josepaiva94
Created February 2, 2018 09:15
Show Gist options
  • Save josepaiva94/0ed1c548fb1b8c57401b01b216b8962d to your computer and use it in GitHub Desktop.
Save josepaiva94/0ed1c548fb1b8c57401b01b216b8962d to your computer and use it in GitHub Desktop.
Utility to load classes from a JAR file
/**
* Utility to load classes from a JAR file
*/
public class JarFileClassLoader {
private static Map<String, JarFileClassLoaderCacheItem> urlClassLoadersCache = new HashMap<>();
@SuppressWarnings("unchecked")
public static <T> T initializeClassFromJar(String jarPath, String className)
throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
JarFileClassLoaderCacheItem cacheItem = null;
if ((cacheItem = urlClassLoadersCache.get(jarPath)) == null || cacheItem.isExpired()) {
cacheItem = new JarFileClassLoaderCacheItem(jarPath);
urlClassLoadersCache.put(jarPath, cacheItem);
}
URLClassLoader urlClassLoader = cacheItem.getUrlClassLoader();
T inst = null;
try (JarFile jarFile = new JarFile(jarPath)) {
Enumeration<JarEntry> jarEntries = jarFile.entries();
while (jarEntries.hasMoreElements()) {
JarEntry jarEntry = jarEntries.nextElement();
if (jarEntry.isDirectory() || !jarEntry.getName().endsWith(".class"))
continue;
String tmpClassName = jarEntry.getName().substring(0, jarEntry.getName().length() - 6);
tmpClassName = tmpClassName.replace('/', '.');
if (tmpClassName.equals(className)) {
Class<?> clazz = urlClassLoader.loadClass(tmpClassName);
Object object = clazz.newInstance();
inst = (T) object;
}
}
}
if (inst == null)
throw new ClassNotFoundException("Class " + className + " was not found in " + jarPath);
return inst;
}
/**
* Cached jar-file class loader item
*/
static class JarFileClassLoaderCacheItem {
String filePath = null;
URLClassLoader urlClassLoader = null;
FileTime time = null;
JarFileClassLoaderCacheItem(String filePath) throws IOException {
this.filePath = filePath;
URL[] urls = { new URL("jar:file:" + filePath + "!/") };
this.urlClassLoader = URLClassLoader.newInstance(urls);
this.time = Files.getLastModifiedTime(Paths.get(filePath));
}
/**
* @return the urlClassLoader
*/
public URLClassLoader getUrlClassLoader() {
return urlClassLoader;
}
/**
* Is this item expired?
*
* @return <code>true</code> if the item has expired, <code>false</code>
* otherwise
* @throws IOException
*/
boolean isExpired() {
try {
return time.compareTo(Files.getLastModifiedTime(Paths.get(filePath))) < 0;
} catch (IOException e) {
return true;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment