Created
February 2, 2018 09:15
-
-
Save josepaiva94/0ed1c548fb1b8c57401b01b216b8962d to your computer and use it in GitHub Desktop.
Utility to load classes from a JAR file
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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