How to get names of classes inside a jar file?

157,006

Solution 1

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);

Solution 2

You can use Java jar tool. List the content of jar file in a txt file and you can see all the classes in the jar.

jar tvf jarfile.jar

-t list table of contents for archive

-v generate verbose output on standard output

-f specify archive file name

Solution 3

Maybe you are looking for jar command to get the list of classes in terminal,

$ jar tf ~/.m2/repository/org/apache/spark/spark-assembly/1.2.0-SNAPSHOT/spark-assembly-1.2.0-SNAPSHOT-hadoop1.0.4.jar 
META-INF/
META-INF/MANIFEST.MF
org/
org/apache/
org/apache/spark/
org/apache/spark/unused/
org/apache/spark/unused/UnusedStubClass.class
META-INF/maven/
META-INF/maven/org.spark-project.spark/
META-INF/maven/org.spark-project.spark/unused/
META-INF/maven/org.spark-project.spark/unused/pom.xml
META-INF/maven/org.spark-project.spark/unused/pom.properties
META-INF/NOTICE

where,

-t  list table of contents for archive
-f  specify archive file name

Or, just grep above result to see .classes only

$ jar tf ~/.m2/repository/org/apache/spark/spark-assembly/1.2.0-SNAPSHOT/spark-assembly-1.2.0-SNAPSHOT-hadoop1.0.4.jar | grep .class
org/apache/spark/unused/UnusedStubClass.class

To see number of classes,

jar tvf launcher/target/usergrid-launcher-1.0-SNAPSHOT.jar | grep .class | wc -l
61079

Solution 4

This is a hack I'm using:

You can use java's autocomplete like this:

java -cp path_to.jar <Tab>

This will give you a list of classes available to pass as the starting class. Of course, trying to use one that has no main file will not do anything, but you can see what java thinks the classes inside the .jar are called.

Solution 5

You can try:

jar tvf jarfile.jar 

This will be helpful only if your jar is executable i.e. in manifest you have defined some class as main class

Share:
157,006
sticksu
Author by

sticksu

Updated on August 21, 2020

Comments

  • sticksu
    sticksu almost 4 years

    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.

  • octopusgrabbus
    octopusgrabbus over 10 years
    Thanks. This answers the "just get a class listing" part of the OP that wasn't asked.
  • Juru
    Juru over 9 years
    Add some specific example on an example jar to your answer.
  • providencemac
    providencemac over 9 years
    this was exactly what I needed, even if the question owner needed a code-based solution. Thanks!
  • sigpwned
    sigpwned about 9 years
    You can also use unzip -l jarfile.jar in a pinch. A JAR file is just a zip file with a manifest!
  • Richard Duerr
    Richard Duerr almost 8 years
    The issue is that he likely wanted to get the class files inside a jar at runtime, given a classloader instance (likely to see what classes are loaded inside that specific jar).
  • Toby Speight
    Toby Speight over 7 years
    Whilst this code snippet is welcome, and may provide some help, it would be greatly improved if it included an explanation of how and why this solves the problem. Remember that you are answering the question for readers in the future, not just the person asking now! Please edit your answer to add explanation, and give an indication of what limitations and assumptions apply.
  • Luke
    Luke over 6 years
    Reflections doesn't work if run from an executable jar either.
  • Luke
    Luke over 6 years
    A Spring solution working from executable jars: stackoverflow.com/a/21430849/4265610.
  • Philip Rego
    Philip Rego almost 5 years
    Just use. jar tvf jarfile.jar. Why are you doing all this for.
  • Zihao Zhao
    Zihao Zhao over 3 years
    This is great! And I found the office doc here. docs.oracle.com/javase/tutorial/deployment/jar/view.html
  • searchengine27
    searchengine27 almost 3 years
    Also, this won't allow you to inspect annotations, which is likely something you'll want to do if you're scanning classes at runtime.