【问题标题】:Comparing two .jar files比较两个 .jar 文件
【发布时间】:2011-04-21 14:15:03
【问题描述】:

如何比较两个 .jar 文件? 他们都编译了.class文件。

我想要方法变化等方面的差异。

【问题讨论】:

    标签: java jar comparison diff


    【解决方案1】:

    【讨论】:

    • Andrey,这些工具有什么区别?它们是否来自同一个核心?
    • @NikolayKuznetsov,不,这些工具有不同的核心。 pkgdiff - 类声明的可视化比较,japi-compliance-checker 和 clirr - 更改分析(第一个是用 perl 编写的,第二个是用 java 编写的)。
    • 您是否尝试过将某些东西与 TeamCity 集成? clirr 好像有一个 Maven 插件,还有一个叫做 JAPI-Checker 的工具。
    • 请注意 Japi-Compliance-Checker 和 Pkgdiff 都不会比较所有内容。例如,所有方法实现都被忽略。仅生成方法签名、方法删除和 API 兼容性作为报告。如果您想比较二进制文件,那么您可以选择使用 diff 或 cmp 或 IntelliJ 插件等工具,甚至 Beyond Compare!
    【解决方案2】:

    如果您在 IntellijIdea 中选择两个文件并按Ctrl + D,那么它将显示差异。我使用 Ultimate,不知道它是否适用于 Community 版本。

    【讨论】:

    • @ChristianNilsson,2018.2 年在 Mac 10.14 Mojave 上工作
    • 我错误地选择了 Maven 包装器。在 External Libraries 下,需要展开包装器,然后选择 jar 文件。谢谢@xuesheng​​span>
    • 超级简单的解决方案。
    • 这就是我一直在寻找的东西 :)
    【解决方案3】:
    1. 将 .jar 重命名为 .zip
    2. 提取
    3. jad反编译类文件
    4. 递归diff

    【讨论】:

    • 这是蛮力的,但这正是我要做的方式。 (除了我可能使用jar 来提取内容,而不是重命名文件并使用pkunzip。)
    • 可选地将步骤 3 替换为对 javap -c 的调用以将其保留为字节码(特别是如果通过“方法更改”,OP 意味着更改方法的签名)。
    • 如何处理在源文件中上下移动的方法体?我认为这会使javapjaddiffing 输出不正常。
    【解决方案4】:

    使用带有参数xvf 的jar 命令将每个jar 解压到它自己的目录中。即每个罐子的jar xvf myjar.jar

    然后,使用 UNIX 命令diff 比较两个目录。这将显示目录中的差异。您可以使用diff -r dir1 dir2 两次递归并显示每个目录(.xml、.properties 等)中文本文件的差异。

    这也将显示二进制类文件是否不同。要实际比较类文件,您必须按照其他人的说明对它们进行反编译。

    【讨论】:

      【解决方案5】:

      我使用ZipDiff lib(同时拥有Java和ant API)。

      【讨论】:

        【解决方案6】:

        创建一个文件夹并在其中创建另外 2 个文件夹,就像旧的和新的一样。将相关的 jar 文件添加到文件夹中。然后使用 IntelliJ 打开第一个文件夹。之后,单击您要比较的任何 2 个文件并右键单击并单击比较档案

        【讨论】:

          【解决方案7】:

          这是我执行 sje397 描述的过程的脚本:

              #!/bin/sh
          
              # Needed if running on Windows
              FIND="/usr/bin/find"
              DIFF="diff -r"
          
              # Extract the jar (war or ear)
              JAR_FILE1=$1
              JAR_FILE2=$2
          
              JAR_DIR=${PWD}          # to assign to a variable
              TEMP_DIR=$(mktemp -d)
          
              echo "Extracting jars in $TEMP_DIR"
          
              EXT_DIR1="${TEMP_DIR}/${JAR_FILE1%.*}"
              EXT_DIR2="${TEMP_DIR}/${JAR_FILE2%.*}"
          
              mkdir ${EXT_DIR1}
              cd ${EXT_DIR1}
              jar xf ${JAR_DIR}/${JAR_FILE1}
              jad -d . -o -t2 -safe -space -b -ff -s java -r **/*.class
              cd ..
          
              mkdir ${EXT_DIR2}
              cd ${EXT_DIR2}
              jar xf ${JAR_DIR}/${JAR_FILE2}
              jad -d . -o -t2 -safe -space -b -ff -s java -r **/*.class
              cd ..
          
              # remove class files so the diff is clean
              ${FIND} ${TEMP_DIR} -name '*.class' | xargs rm
          
              # diff recursively 
              ${DIFF} ${EXT_DIR1} ${EXT_DIR2}
          

          我可以使用 GIT for Windows 在 Windows 上运行它。只需打开命令提示符。运行 bash,然后从那里执行脚本。

          【讨论】:

          • 似乎您错过了最后一行:diff -r ${EXT_DIR1} ${EXT_DIR2}${DIFF} ${EXT_DIR1} ${EXT_DIR2}(如果重用您声明的变量)。对于那些使用 cygwin 的人来说,这个脚本几乎对我有用,除了我改变的两件事:1)我不得不使用内置的 javap 而不是 jad,因为我无法下载 jad(enterp.firewall ... ); 2)由于jar xf不理解/cygwin/c/rest/of/path之类的路径,在cygwin中由pwd返回,我不得不将其转换为c:/rest/of/pathJAR_DIR=${PWD}JAR_DIR=${JAR_DIR#*/cygdrive/c}JAR_DIR="c:$JAR_DIR"
          • 你是对的@dpg。最后一行是 ${DIFF} ${EXT_DIR1} ${EXT_DIR2}
          • 什么是jad? PATH 中没有可用的二进制文件
          • Jad 是一个 Java 反编译器。我认为它不再维护,但我发现它可以在 javadecompilers.com/jad
          • 如果您的参数(jar 文件)在子目录中(如foo/bar/toto.jar),您需要将-p 参数添加到 mkdir 命令
          【解决方案8】:

          使用Java Decompiler将jar文件转为源代码文件,然后使用WinMerge进行比较。

          您应该咨询源代码的版权所有者,看看是否可以这样做。

          【讨论】:

            【解决方案9】:

            在 Linux/CygWin 中,我有时会使用一个方便的脚本:

            #Extract the jar (war or ear)
            cd dir1
            jar xvf jar-file1
            for i in `ls *.class`
            do
             javap $i > ${i}.txt #list the functions/variables etc
            done
            
            cd dir2
            jar xvf jar-file2
            for i in `ls *.class`
            do
             javap $i > ${i}.txt #list the functions/variables etc
            done
            
            diff -r dir1 dir2 #diff recursively
            

            【讨论】:

              【解决方案10】:

              使用java decompiler反编译所有.class文件并将所有文件保存为项目结构。

              然后使用融合差异查看器并作为文件夹进行比较..

              【讨论】:

                【解决方案11】:

                这是一个明显免费的工具http://www.extradata.com/products/jarc/

                【讨论】:

                • 谢谢。我试过这个。它以 XML 格式生成输出,如果 .jar 中有许多类,则需要进一步处理以使其可读
                • 对我来说它抱怨缺少 tools.jar。我确实使用JDK,所以这不是问题。我认为它不支持java7。
                • @Tom 链接已损坏,此答案可能会被删除。
                【解决方案12】:

                请尝试http://www.osjava.org/jardiff/ - 工具旧且依赖列表很大。从文档来看,它看起来值得一试。

                【讨论】:

                  【解决方案13】:

                  此应用程序可能是您所需要的,运行良好,并显示一个简单的 GUI,显示差异。试试Jarcomp

                  【讨论】:

                    【解决方案14】:

                    如果您使用的是 IntelliJ IDEA 或 Android Studio,请将您的 jar 文件添加到 libs 文件夹下的项目中。 然后选择这两个jar文件,右键单击然后选择“Compare Archives

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 2022-01-04
                      • 2018-03-04
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多