How to Load Classes at Runtime from a Folder or Jar

How to load Classes at runtime from a folder or JAR?

The following code loads all classes from a JAR file. It does not need to know anything about the classes. The names of the classes are extracted from the JarEntry.

JarFile jarFile = new JarFile(pathToJar);
Enumeration<JarEntry> e = jarFile.entries();

URL[] urls = { new URL("jar:file:" + pathToJar+"!/") };
URLClassLoader cl = URLClassLoader.newInstance(urls);

while (e.hasMoreElements()) {
JarEntry je = e.nextElement();
if(je.isDirectory() || !je.getName().endsWith(".class")){
continue;
}
// -6 because of .class
String className = je.getName().substring(0,je.getName().length()-6);
className = className.replace('/', '.');
Class c = cl.loadClass(className);

}

edit:

As suggested in the comments above, javassist would also be a possibility.
Initialize a ClassPool somewhere before the while loop form the code above, and instead of loading the class with the class loader, you could create a CtClass object:

ClassPool cp = ClassPool.getDefault();
...
CtClass ctClass = cp.get(className);

From the ctClass, you can get all methods, fields, nested classes, ....
Take a look at the javassist api:
https://jboss-javassist.github.io/javassist/html/index.html

How to load JAR files dynamically at Runtime?

The reason it's hard is security. Classloaders are meant to be immutable; you shouldn't be able to willy-nilly add classes to it at runtime. I'm actually very surprised that works with the system classloader. Here's how you do it making your own child classloader:

URLClassLoader child = new URLClassLoader(
new URL[] {myJar.toURI().toURL()},
this.getClass().getClassLoader()
);
Class classToLoad = Class.forName("com.MyClass", true, child);
Method method = classToLoad.getDeclaredMethod("myMethod");
Object instance = classToLoad.newInstance();
Object result = method.invoke(instance);

Painful, but there it is.

Loading all classes in an external JAR using NIO

I stumbled across this List of files inside a zip folder and its subfolder. What I initially missed with this approach was not to call Files.walkFileTree(Path, FileVisitor) with the jar path from the folder, but rather use the root path of the FileSystem created (using FileSystem.getPath("/")). This works perfectly for me.

How to load a class from a Jar file at runtime with the Java Debug Interface

Often, agents shade all of their dependencies into a single jar. This can still be problematic. Byte Buddy is a rather common dependency, it night already be on the class path but in a different version. To avoid this, many agents shade their dependency into a different namespace.

How to load jar files at runtime from a folder & instantiate classes in JBoss EAP 6.0.1

Your method should works on JBossEAP 6, that's what I did on JBossAS7.1.

class YourClassLoader extends URLClassLoader {
...
public YourClassLoader() {
this(YourClassLoader.class.getClassLoader());
...
this.addURL(jarfile.toURI().toURL());
...
}
...
}

Class<?> yourClass = yourClassLoader.loadClass(className);
YourClassInterface yourClassInterface = null;
yourClassInterface = (YourClassInterface ) yourClass.newInstance();

And please try load the interfaces jar by the same one URLClassLoader.



Related Topics



Leave a reply



Submit