Search code examples
javafileclassjarclassloader

How to get names of classes inside a jar file?


I have a JAR file and I need to get the name of all classes inside this JAR file. How can I do that?

I googled it and saw something about JarFile or Java ClassLoader but I have no idea how to do it.


Solution

  • Unfortunately, Java doesn't provide an easy way to list classes in the "native" JRE. That leaves you with a couple of options: (a) for any given JAR file, you can list the entries inside that JAR file, find the .class files, and then determine which Java class each .class file represents; or (b) you can use a library that does this for you.

    Option (a): Scanning JAR files manually

    In this option, we'll fill classNames with the list of all Java classes contained inside a jar file at /path/to/jar/file.jar.

    List<String> classNames = new ArrayList<String>();
    ZipInputStream zip = new ZipInputStream(new FileInputStream("/path/to/jar/file.jar"));
    for (ZipEntry entry = zip.getNextEntry(); entry != null; entry = zip.getNextEntry()) {
        if (!entry.isDirectory() && entry.getName().endsWith(".class")) {
            // This ZipEntry represents a class. Now, what class does it represent?
            String className = entry.getName().replace('/', '.'); // including ".class"
            classNames.add(className.substring(0, className.length() - ".class".length()));
        }
    }
    

    Option (b): Using specialized reflections libraries

    Guava

    Guava has had ClassPath since at least 14.0, which I have used and liked. One nice thing about ClassPath is that it doesn't load the classes it finds, which is important when you're scanning for a large number of classes.

    ClassPath cp=ClassPath.from(Thread.currentThread().getContextClassLoader());
    for(ClassPath.ClassInfo info : cp.getTopLevelClassesRecurusive("my.package.name")) {
        // Do stuff with classes here...
    }
    

    Reflections

    I haven't personally used the Reflections library, but it seems well-liked. Some great examples are provided on the website like this quick way to load all the classes in a package provided by any JAR file, which may also be useful for your application.

    Reflections reflections = new Reflections("my.project.prefix");
    
    Set<Class<? extends SomeType>> subTypes = reflections.getSubTypesOf(SomeType.class);
    
    Set<Class<?>> annotated = reflections.getTypesAnnotatedWith(SomeAnnotation.class);