LordDoskias
LordDoskias

Reputation: 3191

How can I get Class object for every class in a jar

I have a jar file with 30 or so classes. What I want is that at the beginning of the main method I invoke a class from within this jar which using Java's reflection capabilities gets Class references to each class in the jar. My ultimate goal is to perform some sort of operation, querying a variable which is defined for every class. Basically I'm looking for something like. Is there an easy way to do this using the standard reflection APIs or it will be too much of a hassle to make a working solution?

List l = Reflection.getAllClasses();
String var;
foreach(Class c : l) { 
    var = c.getField("fieldname");
    doSomething(var);
}

Edit:

Just to make it clear: The code will be executed from withing the inspected jar.

Upvotes: 9

Views: 5893

Answers (3)

Michael Borgwardt
Michael Borgwardt

Reputation: 346466

Listing all classes in a JAR file is not something that can be done with reflection.

However, it can be done using a JarInputStream.

Upvotes: 2

ALM
ALM

Reputation: 2705

The following solution will work with a jar that is in your classpath or outside your classpath.

 try {
        File pathToJar = new File("C:/some.jar");

        JarFile 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('/', '.');
            System.out.println("Checking for class " + className);
            Class c = cl.loadClass(className);


            System.out.println("Class object " + c.getName());

        }
    } catch (IOException | ClassNotFoundException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

Upvotes: 1

dagnelies
dagnelies

Reputation: 5329

This does the trick for me:

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;


public class ClassFinder
{
    public static void main(String[] args) throws IOException
    {
    Collection<Class<?>> classes = new ArrayList<Class<?>>();

    JarFile jar = new JarFile("/home/nono/yamts/yamts.jar");
    for (Enumeration<JarEntry> entries = jar.entries() ; entries.hasMoreElements() ;)
    {
        JarEntry entry = entries.nextElement();
        String file = entry.getName();
        if (file.endsWith(".class"))
        {
            String classname = file.replace('/', '.').substring(0, file.length() - 6);
            try 
            {
                Class<?> c = Class.forName(classname);
                classes.add(c);
            }
            catch (Throwable e) 
            {
                System.out.println("WARNING: failed to instantiate " + classname + " from " + file);
            }
        }
    }

    for (Class<?> c : classes)
        System.out.println(c);
    }
}

Upvotes: 10

Related Questions