How to get names of classes inside a jar file?
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 .class
es 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 class
es,
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
sticksu
Updated on August 21, 2020Comments
-
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 over 10 yearsThanks. This answers the "just get a class listing" part of the OP that wasn't asked.
-
Juru over 9 yearsAdd some specific example on an example jar to your answer.
-
providencemac over 9 yearsthis was exactly what I needed, even if the question owner needed a code-based solution. Thanks!
-
sigpwned about 9 yearsYou can also use
unzip -l jarfile.jar
in a pinch. A JAR file is just a zip file with a manifest! -
Richard Duerr almost 8 yearsThe 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 over 7 yearsWhilst 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 over 6 yearsReflections doesn't work if run from an executable jar either.
-
Luke over 6 yearsA Spring solution working from executable jars: stackoverflow.com/a/21430849/4265610.
-
Philip Rego almost 5 yearsJust use. jar tvf jarfile.jar. Why are you doing all this for.
-
Zihao Zhao over 3 yearsThis is great! And I found the office doc here. docs.oracle.com/javase/tutorial/deployment/jar/view.html
-
searchengine27 almost 3 yearsAlso, this won't allow you to inspect annotations, which is likely something you'll want to do if you're scanning classes at runtime.