Find a class somewhere inside dozens of JAR files?
I don’t know about any of these answers, but what works for me if you see the class used in a working project with numerous JAR files is to put your cursor on the class name, right click on it, and click Open Declaration (F3); then it should list the JAR file at the top of the new tab.
35 Answers 35
Unix
On Linux, other Unix variants, Git Bash on Windows, or Cygwin, use the jar (or unzip -v ), grep , and find commands.
The following lists all class files that match a given name:
for i in *.jar; do jar -tvf "$i" | grep -Hsi ClassName && echo "$i"; done
If you know the entire list of Java archives you want to search, you could place them all in the same directory using (symbolic) links.
Or use find (case sensitively) to find the JAR file that contains a given class name:
find path/to/libs -name '*.jar' -exec grep -Hls ClassName <> \;
For example, to find the name of the archive containing IdentityHashingStrategy :
$ find . -name '*.jar' -exec grep -Hsli IdentityHashingStrategy <> \; ./trove-3.0.3.jar
If the JAR could be anywhere in the system and the locate command is available:
for i in $(locate "*.jar"); do echo "$i"; jar -tvf "$i" | grep -Hsi ClassName; done
find path/to/libs -name '*.jar' -print | \ while read i; do jar -tvf "$i" | grep -Hsi ClassName && echo "$i"; done
Windows
Open a command prompt, change to the directory (or ancestor directory) containing the JAR files, then:
for /R %G in (*.jar) do @jar -tvf "%G" | find "ClassName" > NUL && echo %G
- for /R %G in (*.jar) do — loop over all JAR files, recursively traversing directories; store the file name in %G .
- @jar -tvf «%G» | — run the Java Archive command to list all file names within the given archive, and write the results to standard output; the @ symbol suppresses printing the command’s invocation.
- find «ClassName» > NUL — search standard input, piped from the output of the jar command, for the given class name; this will set ERRORLEVEL to 1 iff there’s a match (otherwise 0).
- && echo %G — iff ERRORLEVEL is non-zero, write the Java archive file name to standard output (the console).
Use a search engine that scans JAR files.
By far the best approach: all command line. Worked simply by pasting on a Windows Bash shell, found what I was looking for.
Brilliant — Just used the first one in Windows GitBash to locate two classes in an unknown jar file (I needed as I was getting stacktraces at SpringBoot jar launch) in a collection of 1580 third party JAR files in a directory!
Eclipse can do it, just create a (temporary) project and put your libraries on the projects classpath. Then you can easily find the classes.
Another tool, that comes to my mind, is Java Decompiler. It can open a lot of jars at once and helps to find classes as well.
some time ago, I wrote a program just for that: https://github.com/javalite/jar-explorer
Finds any type of file, not just classes. Double-click to see file contents. Yay, now I can spot all my spring-schemas.
gives you the name of the jar
find . -name "*.jar" -exec jar -t -f <> \; | grep "classname"
gives you the package of the class
#!/bin/bash pattern=$1 shift for jar in $(find $* -type f -name "*.jar") do match=`jar -tvf $jar | grep $pattern` if [ ! -z "$match" ] then echo "Found in: $jar" echo "$match" fi done
Great ! I had to use it on a system that didn’t have jar (not in the path, that is), so I replaced jar -tvf with unzip -l .
To locate jars that match a given string:
find . -name \*.jar -exec grep -l YOUR_CLASSNAME <> \;
I didn’t know of a utility to do it when I came across this problem, so I wrote the following:
public class Main < /** * */ private static String CLASS_FILE_TO_FIND = "class.to.find.Here"; private static ListfoundIn = new LinkedList(); /** * @param args the first argument is the path of the file to search in. The second may be the * class file to find. */ public static void main(String[] args) < if (!CLASS_FILE_TO_FIND.endsWith(".class")) < CLASS_FILE_TO_FIND = CLASS_FILE_TO_FIND.replace('.', '/') + ".class"; >File start = new File(args[0]); if (args.length > 1) < CLASS_FILE_TO_FIND = args[1]; >search(start); System.out.println("------RESULTS------"); for (String s : foundIn) < System.out.println(s); >> private static void search(File start) < try < final FileFilter filter = new FileFilter() < public boolean accept(File pathname) < return pathname.getName().endsWith(".jar") || pathname.isDirectory(); >>; for (File f : start.listFiles(filter)) < if (f.isDirectory()) < search(f); >else < searchJar(f); >> > catch (Exception e) < System.err.println("Error at: " + start.getPath() + " " + e.getMessage()); >> private static void searchJar(File f) < try < System.out.println("Searching: " + f.getPath()); JarFile jar = new JarFile(f); ZipEntry e = jar.getEntry(CLASS_FILE_TO_FIND); if (e == null) < e = jar.getJarEntry(CLASS_FILE_TO_FIND); if (e != null) < foundIn.add(f.getPath()); >> else < foundIn.add(f.getPath()); >> catch (IOException e) < e.printStackTrace(); >> >
There are also two different utilities called both «JarScan» that do exactly what you are asking for: JarScan (inetfeedback.com) and JarScan (java.net)
ClassFinder is a program that’s designed to solve this problem. It allows you to search recursively through directories and jar files to find all instances of a class matching a pattern. It is written in Java, not python. It has a nice GUI which makes it easy to use. And it runs fast. This release is precompiled in a runnable jar so you don’t have to build it from source.
user1207523’s script works fine for me. Here is a variant that searches for jar files recusively using find instead of simple expansion;
#!/bin/bash for i in `find . -name '*.jar'`; do jar -tf "$i" | grep $1 | xargs -I<> echo -e "$i : <>" ; done
I’ve always used this on Windows and its worked exceptionally well.
findstr /s /m /c:"package/classname" *.jar, where
findstr.exe comes standard with Windows and the params:
- /s = recursively
- /m = print only the filename if there is a match
- /c = literal string (in this case your package name + class names separated by ‘/’)
A bash script solution using unzip (zipinfo) . Tested on Ubuntu 12 .
#!/bin/bash # ./jarwalker.sh "/a/Starting/Path" "aClassName" IFS=$'\n' jars=( $( find -P "$1" -type f -name "*.jar" ) ) for jar in $ do classes=( $( zipinfo -1 $ | awk -F '/' '' | grep .class | awk -F '.' '' ) ) if [ $ -ge 0 ]; then for class in $ do if [ $ == "$2" ]; then echo "Found in $" fi done fi done
To find a class in a folder (and subfolders) bunch of JARs: https://jarscan.com/
Usage: java -jar jarscan.jar [-help | /?] [-dir directory name] [-zip] [-showProgress] [search string 2] [search string n] Help: -help or /? Displays this message. -dir The directory to start searching from default is "." -zip Also search Zip files -showProgress Show a running count of files read in -files or -class Search for a file or Java class contained in some library. i.e. HttpServlet -package Search for a Java package contained in some library. i.e. javax.servlet.http search string The file or package to search for. i.e. see examples above
java -jar jarscan.jar -dir C:\Folder\To\Search -showProgress -class GenericServlet
Just use FindClassInJars util, it’s a simple swing program, but useful. You can check source code or download jar file at http://code.google.com/p/find-class-in-jars/
A bit late to the party, but nevertheless.
I’ve been using JarBrowser to find in which jar a particular class is present. It’s got an easy to use GUI which allows you to browse through the contents of all the jars in the selected path.
To search all jar files in a given directory for a particular class, you can do this:
ls *.jar | xargs grep -F MyClass
Binary file foo.jar matches
It’s very fast because the -F option means search for Fixed string, so it doesn’t load the the regex engine for each grep invocation. If you need to, you can always omit the -F option and use regexes.
bash $ ls -1 | xargs -i -t jar -tvf '<>'| grep Abstract jar -tvf activation-1.1.jar jar -tvf antisamy-1.4.3.jar 2263 Thu Jan 13 21:38:10 IST 2011 org/owasp/validator/html/scan/AbstractAntiSamyScanner.class .
So this lists the jar and the class if found, if you want you can give ls -1 *.jar or input to xargs with find command HTH Someone.
To add yet another tool. this is a very simple and useful tool for windows. A simple exe file you click on, give it a directory to search in, a class name and it will find the jar file that contains that class. Yes, it’s recursive.
Check JBoss Tattletale; although I’ve never used it personally, this seems to be the tool you need.
Not sure why scripts here have never really worked for me. This works:
#!/bin/bash for i in *.jar; do jar -tf "$i" | grep $1 | xargs -I<> echo -e "$i : <>" ; done
Script to find jar file: find_jar.sh
IFS=$(echo -en "\n\b") # Set the field separator newline for f in `find $ -iname *.jar`; do jar -tf $| grep --color $2 if [ $? == 0 ]; then echo -n "Match found: " echo -e "$\n" fi done unset IFS
This is similar to most answers given here. But it only outputs the file name, if grep finds something. If you want to suppress grep output you may redirect that to /dev/null but I prefer seeing the output of grep as well so that I can use partial class names and figure out the correct one from a list of output shown.
The class name can be both simple class name Like «String» or fully qualified name like «java.lang.String»
import os, zipfile, glob, sys def main(): searchFile = sys.argv[1] #class file to search for, sent from batch file below (optional, see second block of code below) listOfFilesInJar = [] for file in glob.glob("*.jar"): archive = zipfile.ZipFile(file, 'r') for x in archive.namelist(): if str(searchFile) in str(x): listOfFilesInJar.append(file) for something in listOfFilesInJar: print("location of "+str(searchFile)+": ",something) if __name__ == "__main__": sys.exit(main())
You can easily run this by making a .bat file with the following text (replace «AddWorkflows.class» with the file you are searching for):
@echo off python -B -c "import searchForFiles;x=searchForFiles.main();" AddWorkflows.class pause
You can double-click CallSearchForFiles.bat to run it, or call it from the command line «CallSearchForFiles.bat SearchFile.class»
Search class names in jars
I’m using this command to search *.jar files for java classes, and I only get the name of the jars that contain those classes:
grep -ral --include=*.jar SignonEJB .
2 Answers 2
You passed the -l option, telling grep to only list the file names. That’s the names of the .jar files, there are no other files involved.
If you want grep to output the class names, you need to remove -l . But that will print a lot of other junk on the same “line”, because the jars are binary files, not organized by lines. (With GNU grep, you need to pass -a to get that output and not just “Binary file … matches”.)
With GNU grep, one possibility is to match the full class name and pass -o to output just that:
grep -rao --include='*.jar' '[0-9A-Z_a-z]*SignonEJB[0-9A-Z_a-z]*' .
or if you want the packages as well
grep -rao --include='*.jar' '[$./0-9A-Z_a-z]*SignonEJB[0-9A-Z_a-z]*' .
Another approach is to run strings on the files first to extract printable strings. (The two commands are equivalent; the sed version chokes on \& and newline, the awk version supports all characters.)
find . -name '*.jar' -exec sh -c 'strings "$0" | grep SignonEJB | sed "s&^&$0&"' <> \; find . -name '*.jar' -exec sh -c 'strings "$0" | jar=$0 awk "/SignonEJB/ "' <> \;
Alternatively (and strictly speaking, more reliably, even though using grep is unlikely to turn up false positives), use unzip to list the file names, and filter that.
find . -name '*.jar' -exec sh -c 'unzip -l -- "$0" | grep SignonEJB' <> \;
Search or list Java classes in classpath (ncluding JARS) via command line
I really like the javap command line program to decompile and inspect classes however most of the time I can’t recollect the fully qualified package name of a class:
If I don’t know the package name then I resort to using Google. Is there a built-in java program or slick Linux command that could search and list all the matching packages of a given class name?
Many IDE(s) (like NetBeans, IntelliJ and Eclipse) can do that; I’m not aware of an easy way to do it from the command line. But it is possible or the IDE(s) couldn’t do it.
«Questions asking us to recommend or find a tool, library or favorite off-site resource are off-topic for Stack Overflow as they tend to attract opinionated answers and spam. Instead, describe the problem and what has been done so far to solve it. «
1 Answer 1
find -name "*.jar" -exec jar -tf <> \; | grep "/\.class\$"
find ~/.ivy2/ -name "*.jar" -exec jar -tf <> \; | grep "/Filter\.class\$"
javax/servlet/Filter.class javax/servlet/Filter.class javax/servlet/Filter.class org/scalatest/Filter.class org/scalatest/Filter.class org/fusesource/scalate/filter/Filter.class org/fusesource/scalate/filter/Filter.class scala/tools/scalap/scalax/rules/Filter.class org/apache/ivy/util/filter/Filter.class com/foursquare/fongo/impl/Filter.class com/foursquare/fongo/impl/Filter.class com/foursquare/fongo/impl/Filter.class shapeless/Filter.class
I’m not personally in love with this solution.
To search all class files just use find :