277

如何在大量 jar 文件中找到特定的类名?

(寻找实际的类名,而不是引用它的类。)

4

35 回答 35

474

Unix

在 Linux、其他 Unix 变体、Windows 上的 Git Bash 或 Cygwin 上,使用jar(或unzip -v) grep、 和find命令。

下面列出了与给定名称匹配的所有类文件:

for i in *.jar; do jar -tvf "$i" | grep -Hsi ClassName && echo "$i"; done

如果您知道要搜索的 Java 档案的整个列表,您可以使用(符号)链接将它们全部放在同一个目录中。

或者使用find(区分大小写)查找包含给定类名的 JAR 文件:

find path/to/libs -name '*.jar' -exec grep -Hls ClassName {} \;

例如,要查找包含以下内容的存档名称IdentityHashingStrategy

$ find . -name '*.jar' -exec grep -Hsli IdentityHashingStrategy {} \;
./trove-3.0.3.jar

如果 JAR 可以在系统中的任何位置并且命令locate可用:

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 

视窗

打开命令提示符,切换到包含 JAR 文件的目录(或祖先目录),然后:

for /R %G in (*.jar) do @jar -tvf "%G" | find "ClassName" > NUL && echo %G

以下是它的工作原理:

  1. for /R %G in (*.jar) do- 遍历所有 JAR 文件,递归遍历目录;将文件名存储在%G.
  2. @jar -tvf "%G" |- 运行 Java Archive 命令列出给定存档中的所有文件名,并将结果写入标准输出;该@符号禁止打印命令的调用。
  3. find "ClassName" > NUL- 搜索标准输入,从 jar 命令的输出通过管道获取给定的类名;如果有匹配项,这将设置ERRORLEVEL为 1(否则为 0)。
  4. && echo %G- 如果ERRORLEVEL非零,则将 Java 归档文件名写入标准输出(控制台)。

网络

使用扫描JAR 文件的搜索引擎

于 2009-08-27T18:39:57.590 回答
68

Eclipse 可以做到这一点,只需创建一个(临时)项目并将您的库放在项目类路径中。然后你可以很容易地找到课程。

我想到的另一个工具是 Java Decompiler。它可以一次打开很多罐子,也有助于查找类。

于 2009-08-27T18:32:00.057 回答
62

前段时间,我为此编写了一个程序:https ://github.com/javalite/jar-explorer

于 2011-07-01T03:19:52.300 回答
33
grep -l "classname" *.jar

给你罐子的名字

find . -name "*.jar" -exec jar -t -f {} \; | grep  "classname"

给你类的包

于 2011-03-22T14:43:24.843 回答
13
#!/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
于 2011-01-07T06:58:46.970 回答
9

要找到与给定字符串匹配的 jar:

find . -name \*.jar -exec grep -l YOUR_CLASSNAME {} \;

于 2012-04-03T01:46:54.670 回答
8

当我遇到这个问题时,我不知道有一个实用程序可以做到这一点,所以我写了以下内容:

public class Main {

    /**
     * 
     */
    private static String CLASS_FILE_TO_FIND =
            "class.to.find.Here";
    private static List<String> foundIn = new LinkedList<String>();

    /**
     * @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();
        }
    }

}
于 2009-08-27T18:34:35.977 回答
7

还有两个称为“JarScan”的不同实用程序可以完全满足您的要求: JarScan (inetfeedback.com)JarScan (java.net)

于 2012-08-08T02:57:53.347 回答
5

ClassFinder 是一个旨在解决这个问题的程序。它允许您递归地搜索目录和 jar 文件以查找与模式匹配的类的所有实例。它是用 Java 编写的,而不是 python。它有一个很好的 GUI,使它易于使用。而且它跑得很快。此版本预编译在可运行的 jar 中,因此您不必从源代码构建它。

在此处下载:ClassFinder 1.0

于 2019-10-10T17:44:41.187 回答
4

user1207523 的脚本对我来说很好用。这是一个使用 find 而不是简单扩展搜索 jar 文件的变体;

#!/bin/bash
for i in `find . -name '*.jar'`; do jar -tf "$i" | grep $1 | xargs -I{} echo -e "$i : {}" ; done
于 2013-07-19T11:22:22.507 回答
4

我一直在 Windows 上使用它,并且效果非常好。

findstr /s /m /c:"package/classname" *.jar, where

findstr.exe 是 Windows 和参数的标准配置:

  • /s = 递归
  • /m = 如果匹配,则仅打印文件名
  • /c = 文字字符串(在这种情况下,您的包名 + 由“/”分隔的类名)

希望这可以帮助某人。

于 2016-10-21T14:42:28.850 回答
3

bash script使用unzip (zipinfo). _ 经测试Ubuntu 12

#!/bin/bash

# ./jarwalker.sh "/a/Starting/Path" "aClassName"

IFS=$'\n'
jars=( $( find -P "$1" -type f -name "*.jar" ) )

for jar in ${jars[*]}
    do
        classes=( $( zipinfo -1 ${jar} | awk -F '/' '{print $NF}' | grep .class | awk -F '.' '{print $1}' ) )
        if [ ${#classes[*]} -ge 0 ]; then
            for class in ${classes[*]}
                do
                    if [ ${class} == "$2" ]; then
                        echo "Found in ${jar}"
                    fi
                done
        fi
    done
于 2013-06-27T14:01:33.720 回答
2

只需使用 FindClassInJars 工具,它是一个简单的摇摆程序,但很有用。您可以在http://code.google.com/p/find-class-in-jars/查看源代码或下载 jar 文件

于 2011-03-31T13:36:10.813 回答
2

派对有点晚了,但尽管如此......

我一直在使用JarBrowser来查找特定类存在于哪个 jar 中。它有一个易于使用的 GUI,允许您浏览所选路径中所有 jar 的内容。

于 2013-02-15T00:41:20.600 回答
2

要在给定目录中搜​​索特定类的所有 jar 文件,可以执行以下操作:

ls *.jar | xargs grep -F MyClass

或者,甚至更简单,

grep -F MyClass *.jar

输出如下所示:

Binary file foo.jar matches

它非常快,因为 -F 选项意味着搜索固定字符串,因此它不会为每个 grep 调用加载正则表达式引擎。如果需要,您始终可以省略 -F 选项并使用正则表达式。

于 2013-06-07T16:22:51.600 回答
2

添加另一个工具...这是一个非常简单且有用的 Windows 工具。单击一个简单的 exe 文件,给它一个要搜索的目录,一个类名,它会找到包含该类的 jar 文件。是的,它是递归的。

http://sourceforge.net/projects/jarfinder/

于 2013-07-19T11:57:06.367 回答
2

我发现了这个新方法

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
...

所以这列出了 jar 和如果找到的类,如果你愿意,你可以给 ls -1 *.jar 或输入到 xargs 用 find 命令 HTH 某人。

于 2016-07-04T12:24:31.237 回答
2

要在一堆 JAR 的文件夹(和子文件夹)中查找一个类: https ://jarscan.com/

Usage: java -jar jarscan.jar [-help | /?]
                    [-dir directory name]
                    [-zip]
                    [-showProgress]
                    <-files | -class | -package>
                    <search string 1> [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
于 2019-04-30T11:08:04.130 回答
1

检查 JBoss Tattletale;尽管我从未亲自使用过它,但这似乎是您需要的工具。

于 2009-08-27T18:42:52.047 回答
1

不知道为什么这里的脚本从来没有真正为我工作过。这有效:

#!/bin/bash
for i in *.jar; do jar -tf "$i" | grep $1 | xargs -I{} echo -e "$i : {}" ; done
于 2013-03-04T12:38:30.927 回答
1

查找jar文件的脚本:find_jar.sh

IFS=$(echo -en "\n\b") # Set the field separator newline

for f in `find ${1} -iname *.jar`; do
  jar -tf ${f}| grep --color $2
  if [ $? == 0 ]; then
    echo -n "Match found: "
    echo -e "${f}\n"
  fi
done
unset IFS

用法:./find_jar.sh <包含jar文件的顶级目录> <要查找的类名>

这与此处给出的大多数答案相似。但它只输出文件名,如果 grep 找到了一些东西。如果您想禁止 grep 输出,您可以将其重定向到 /dev/null 但我更喜欢查看 grep 的输出,以便我可以使用部分类名并从显示的输出列表中找出正确的类名。

类名既可以是简单的类名,如“String”,也可以是完全限定名,如“java.lang.String”

于 2013-09-17T10:31:55.763 回答
1

文件名:searchForFiles.py

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

您可以通过使用以下文本创建一个 .bat 文件来轻松运行它(将“AddWorkflows.class”替换为您正在搜索的文件):

(文件:CallSearchForFiles.bat)

@echo off
python -B -c "import searchForFiles;x=searchForFiles.main();" AddWorkflows.class
pause

可以双击 CallSearchForFiles.bat 运行,或者从命令行“CallSearchForFiles.bat SearchFile.class”调用

单击以查看示例输出

于 2019-05-29T18:21:21.260 回答
0

您可以在一个充满 jar 的目录中找到一个类,并带有一些 shell:

寻找类“FooBar”:

LIB_DIR=/some/dir/full/of/jarfiles
for jarfile in $(find $LIBDIR -name "*.jar"); do
   echo "--------$jarfile---------------"
   jar -tvf $jarfile | grep FooBar
done
于 2009-08-27T18:41:21.660 回答
0

要添加到上述所有内容中的一件事:如果您没有可用的 jar 可执行文件(它随 JDK 提供,但不随 JRE 提供),您可以使用 unzip(或 WinZip,或其他)来完成同样的事情。

于 2009-09-14T16:53:10.220 回答
0

无耻的自我推销,但你可以试试我写的一个实用程序:http: //sourceforge.net/projects/zfind

它支持最常见的存档/压缩文件(jar、zip、tar、tar.gz 等),并且与许多其他 jar/zip 查找器不同,它支持嵌套的 zip 文件(zip 中的 zip、jar 中的 jar 等)直到无限深度。

于 2012-05-23T11:09:34.440 回答
0

以下脚本将帮助您

for file in *.jar
do
  # do something on "$file"
  echo "$file"
  /usr/local/jdk/bin/jar -tvf "$file" | grep '$CLASSNAME'
done
于 2013-05-08T09:51:14.060 回答
0

这个在MinGW(windows bash环境)中运行良好~ gitbash

将此函数放入 HOME 目录中的 .bashrc 文件中:

# this function helps you to find a jar file for the class
function find_jar_of_class() {
  OLD_IFS=$IFS
  IFS=$'\n'
  jars=( $( find -type f -name "*.jar" ) )
  for i in ${jars[*]} ; do 
    if [ ! -z "$(jar -tvf "$i" | grep -Hsi $1)" ] ; then
      echo "$i"
    fi
   done 
  IFS=$OLD_IFS
}
于 2013-08-08T09:48:39.110 回答
0

Grepj是一个命令行实用程序,用于在 jar 文件中搜索类。我是该实用程序的作者。

您可以像这样运行该实用程序grepj package.Class my1.jar my2.war my3.ear

可以提供多个jar、ear、war文件。对于高级用法,使用 find 提供要搜索的 jar 列表。

于 2013-08-19T04:06:30.583 回答
0

检查这个插件以获取可以完成您正在寻找的工作的 Eclipse。

https://marketplace.eclipse.org/content/jarchiveexplorer

于 2014-06-06T11:26:14.237 回答
0

在 Linux 环境下,您可以执行以下操作:

$ find <base_dir> -name *.jar -print0 | xargs -0 -l jar tf | grep <name>

其中name是您在 jar 中查看的类文件的名称,该文件分布在以base_dir为根的目录层次结构中。

于 2015-04-17T16:18:43.250 回答
0

您可以使用locategrep

locate jar | xargs grep 'my.class'

确保updatedb在使用之前运行locate

于 2016-04-11T12:53:26.697 回答
0

在 Eclipse 中,您可以使用旧的但仍然可用的插件jarsearch

于 2016-08-22T13:27:30.207 回答
0

如果你有一个类的实例,或者可以得到一个,你就有了一个纯 java 的解决方案:

try{
    Class clazz = Class.forName("        try{
        Class clazz = Class.forName("class-name");
        String name = "/"+clazz.getName().replace('.', '/')+".class";
        URL url = clazz.getResource(name);
        String jar = url.toString().substring(10).replaceAll("!.*", "");
        System.out.println( jar );
    }catch(Exception err){
        err.printStackTrace();
    }

当然,前两行必须根据类实例或类名的位置进行调整。

于 2016-11-30T20:17:00.450 回答
0

我知道这是一个老问题但是......
我有同样的问题,所以如果有人正在寻找一个非常简单的 Windows 解决方案 - 有一个名为 Locate32 的软件只需将 jar 作为文件扩展名
并包含类名
它会找到几秒钟内归档。

Locate32 在行动

于 2020-10-15T17:28:49.247 回答
-1

使用这个..你可以在类路径中找到任何文件..保证..

import java.net.URL;
import java.net.URLClassLoader;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class FileFinder {

    public static void main(String[] args) throws Exception {

        String file = <your file name>;

        ClassLoader cl = ClassLoader.getSystemClassLoader();

        URL[] urls = ((URLClassLoader)cl).getURLs();

        for(URL url: urls){
            listFiles(file, url);
        }
    }

    private static void listFiles(String file, URL url) throws Exception{
        ZipInputStream zip = new ZipInputStream(url.openStream());
          while(true) {
            ZipEntry e = zip.getNextEntry();
            if (e == null)
              break;
            String name = e.getName();
            if (name.endsWith(file)) {
                System.out.println(url.toString() + " -> " + name);
            }
          }
    }

}
于 2016-04-28T17:13:10.043 回答