【问题标题】:Find a class somewhere inside dozens of JAR files?在几十个 JAR 文件中的某个地方找到一个类?
【发布时间】:2010-11-23 11:52:47
【问题描述】:

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

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

【问题讨论】:

  • 我不知道这些答案中的任何一个,但是如果您看到在具有大量 JAR 文件的工作项目中使用的类对我有用,那么将光标放在类名上,右键单击在其上,然后单击打开声明(F3);那么它应该在新选项卡的顶部列出 JAR 文件。

标签: java class jar project-structure text-search


【解决方案1】:

Eclipse 可以做到,只需创建一个(临时)项目并将您的库放在项目类路径中。然后您可以轻松找到课程。

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

【讨论】:

  • 并在 Ctrl + Shift + T 的帮助下
【解决方案2】:

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

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

}

【讨论】:

    【解决方案3】:

    Unix

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

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

    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 
    

    窗口

    打开command prompt,切换到包含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" &gt; NUL - 搜索标准输入,从 jar 命令的输出通过管道传输给定的类名;这会将ERRORLEVEL 设置为 1 如果存在匹配项(否则为 0)。
    4. &amp;&amp; echo %G - 如果 ERRORLEVEL 不为零,则将 Java 归档文件名写入标准输出(控制台)。

    网络

    使用扫描JAR filessearch engine

    【讨论】:

    • 是的 -l 会给你,但当它从标准输入获取输入时不是很有用。
    • 迄今为止最好的方法:所有命令行。只需在 Windows Bash shell 上粘贴即可工作,找到了我想要的东西。
    • Brilliant - 刚刚使用 Windows GitBash 中的第一个类在 1580 个第三方 JAR 文件的集合中定位未知 jar 文件中的两个类(我需要在 SpringBoot jar 启动时获取堆栈跟踪)一个目录!
    【解决方案4】:

    你可以在一个装满 jars 的目录中找到一个类:

    寻找类“FooBar”:

    LIB_DIR=/some/dir/full/of/jarfiles
    for jarfile in $(find $LIBDIR -name "*.jar"); do
       echo "--------$jarfile---------------"
       jar -tvf $jarfile | grep FooBar
    done
    

    【讨论】:

      【解决方案5】:

      查看JBossTattletale;虽然我从未亲自使用过,但这似乎是您需要的工具。

      【讨论】:

        【解决方案6】:

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

        【讨论】:

          【解决方案7】:
          #!/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
          

          【讨论】:

          • 太棒了!我必须在没有 jar 的系统上使用它(即不在路径中),所以我将 jar -tvf 替换为 unzip -l
          【解决方案8】:
          grep -l "classname" *.jar
          

          给你罐子的名字

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

          给你类的包

          【讨论】:

          • 应该是 grep -lir "classname" *.jar
          【解决方案9】:

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

          【讨论】:

            【解决方案10】:

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

            【讨论】:

            • 查找任何类型的文件,而不仅仅是类。双击查看文件内容。是的,现在我可以找出我所有的弹簧模式了。
            • 太棒了。谢谢;)
            【解决方案11】:

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

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

            【讨论】:

            • 这也会找到对类的引用,而不仅仅是类本身。
            【解决方案12】:

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

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

            【讨论】:

              【解决方案13】:

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

              【讨论】:

                【解决方案14】:

                聚会有点晚了,不过……

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

                【讨论】:

                  【解决方案15】:

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

                  #!/bin/bash
                  for i in *.jar; do jar -tf "$i" | grep $1 | xargs -I{} echo -e "$i : {}" ; done
                  

                  【讨论】:

                    【解决方案16】:

                    下面的脚本会帮助你

                    for file in *.jar
                    do
                      # do something on "$file"
                      echo "$file"
                      /usr/local/jdk/bin/jar -tvf "$file" | grep '$CLASSNAME'
                    done
                    

                    【讨论】:

                      【解决方案17】:

                      要在给定目录中搜​​索特定类的所有 jar 文件,您可以这样做:

                      ls *.jar | xargs grep -F MyClass
                      

                      或者,甚至更简单,

                      grep -F MyClass *.jar
                      

                      输出如下所示:

                      Binary file foo.jar matches
                      

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

                      【讨论】:

                        【解决方案18】:

                        使用unzip (zipinfo)bash script 解决方案。在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
                        

                        【讨论】:

                        • 这个脚本不兼容 mingw
                        【解决方案19】:

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

                        #!/bin/bash
                        for i in `find . -name '*.jar'`; do jar -tf "$i" | grep $1 | xargs -I{} echo -e "$i : {}" ; done
                        

                        【讨论】:

                          【解决方案20】:

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

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

                          【讨论】:

                            【解决方案21】:

                            这个在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
                            }
                            

                            【讨论】:

                              【解决方案22】:

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

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

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

                              【讨论】:

                                【解决方案23】:

                                查找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

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

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

                                【讨论】:

                                  【解决方案24】:

                                  检查这个插件是否可以完成您正在寻找的工作。

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

                                  【讨论】:

                                    【解决方案25】:

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

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

                                    name 是您在分布于以 base_dir

                                    【讨论】:

                                      【解决方案26】:

                                      您可以使用locategrep

                                      locate jar | xargs grep 'my.class'
                                      

                                      确保在使用 locate 之前运行 updatedb

                                      【讨论】:

                                        【解决方案27】:

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

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

                                        【讨论】:

                                          【解决方案28】:

                                          我发现了这个新方法

                                          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 或使用 find 命令 HTH Some 输入 xargs。

                                          【讨论】:

                                          • 谢谢,我这样改进:ls -1 *.jar | xargs -i -t jar -tvf '{}'| grep 摘要
                                          【解决方案29】:

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

                                          【讨论】:

                                            【解决方案30】:

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

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

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

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

                                            希望这对某人有所帮助。

                                            【讨论】:

                                              猜你喜欢
                                              • 1970-01-01
                                              • 2010-12-02
                                              • 2012-06-10
                                              • 2013-07-29
                                              • 1970-01-01
                                              • 1970-01-01
                                              • 2011-04-30
                                              • 2011-10-30
                                              • 1970-01-01
                                              相关资源
                                              最近更新 更多