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

I am trying to make a Java tool that will scan the structure of a Java application and provide some meaningful information. To do this, I need to be able to scan all of the .class files from the project location (JAR/WAR or just a folder) and use reflection to read about their methods. This is proving to be near impossible.

I can find a lot of solutions based on URLClassloader that allow me to load specific classes from a directory/archive, but none that will allow me to load classes without having any information about the class name or package structure.

EDIT: I think I phrased this poorly. My issue is not that I can't get all of the class files, I can do that with recursion etc. and locate them properly. My issue is obtaining a Class object for each class file.

Answers


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


List All the classes inside jar file.

public static List getClasseNames(String jarName) {
    ArrayList classes = new ArrayList();

    if (debug)
        System.out.println("Jar " + jarName );
    try {
        JarInputStream jarFile = new JarInputStream(new FileInputStream(
                jarName));
        JarEntry jarEntry;

        while (true) {
            jarEntry = jarFile.getNextJarEntry();
            if (jarEntry == null) {
                break;
            }
            if (jarEntry.getName().endsWith(".class")) {
                if (debug)
                    System.out.println("Found "
                            + jarEntry.getName().replaceAll("/", "\\."));
                classes.add(jarEntry.getName().replaceAll("/", "\\."));
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return classes;
}

To do this, I need to be able to scan all of the .class files from the project location (JAR/WAR or just a folder)

Scanning all of the files in a folder is simple. One option is to call File.listFiles() on the File that denotes the folder, then iterate the resulting array. To traverse trees of nested folders, use recursion.

Scanning the files of a JAR file can be done using the JarFile API ... and you don't need to recurse to traverse nested "folders".

Neither of these is particularly complicated. Just read the javadoc and start coding.


Need Your Help

On switching activity I am lossing activity bar

android android-layout android-fragments android-activity

When I am switching from one activity to another I am losing my activity bar in which it should show title of activity.

UITableview items becomes bold after scrolling up

ios uitableview label uilabel tableview

Ok maybe I am being too picky. Apologies in advance if you cannot see it, but in the second pic, the item on the row is pixellated a bit, or as if a word was placed on top of a word. This only happ...