【问题标题】:How to list dependencies of a JAR如何列出 JAR 的依赖项
【发布时间】:2011-05-24 00:01:30
【问题描述】:

是否有工具可以列出包含 JAR 中引用的(第三方)类的第三方“包”?假设它会从 JAR 文件定义中识别什么是“home”包,它会打印出在 JAR 中引用的第三方类的完全限定名称列表,最高可达 3 级。

org.apache.commons  
org.apache.maven
javax.servlet.jsp
org.eclipse.persistence
org.apache.jackrabbit

目的是我需要找到该 JAR 文件的 maven 依赖项并将其部署为 maven 工件。

【问题讨论】:

  • 难道 Maven 不就是为了这个目的吗?
  • 假设您有一个基于 Ant 的项目,并且您希望将其部署到 maven 存储库以供其他人使用它作为依赖项。您必须在 pom 定义中指定其传递依赖项。我需要一种可以轻松找到它们的方法
  • 编辑:我知道如何手动完成,花费了很多精力。理论上应该可以自动解决依赖关系,所有信息都在 .jar 和 Maven 存储库中。
  • 这一定是有原因的,sonatype 或社区的人居然没有为这么重要的事情做任何事情,这真的很奇怪
  • 查看 maven-dependency-plugin 中的 copy-dependencies 目标。

标签: java jar dependencies maven


【解决方案1】:

自 JDK 8 以来有一个新工具:jdeps

https://wiki.openjdk.java.net/display/JDK8/Java+Dependency+Analysis+Tool

jdeps 是自 JDK 8 以来添加的新命令行工具,供开发人员用于了解其应用程序和库的静态依赖关系。 jdeps 是给定类文件的静态分析工具

【讨论】:

  • 一点提示:生成的图可以包含很多包,并且可以变得很宽。要垂直组织它,请在 grap 定义中添加(在 digraph 内):graph [ rankdir = "LR" ];
  • jdeps 对我不起作用。我刚刚收到错误“线程“main”java.lang.InternalError 中的异常:缺少消息:warn.skipped.entry'
【解决方案2】:

JarAnalyzer:

jar 文件的依赖管理实用程序。它的主要目的是遍历一个目录,解析该目录中的每个 jar 文件,并识别 jar 文件之间的依赖关系。输出是一个 xml 文件,表示 jar 文件之间的 PhysicalDependencies

有关PhysicalDependencies的更多信息,包括各种设计模式,请查看Extensible Java...

【讨论】:

  • Chrome 警告我该网站包含恶意软件。
  • 嗯,是的,它似乎已经消失了。抱歉打扰了。
  • @MJB 网站似乎已关闭
  • mvnrepository.com/artifact/com.kirkk/jaranalyzer/1.2 是 jar 的 maven repo,尽管我承认,此时可能有更新、更好的选择
  • 另外,我现在很想使用更像 gradle 依赖项的任务。
【解决方案3】:

您可以执行以下操作(如果它是 maven 项目):

mvn dependency:tree

它还显示了传递依赖,这使得调试依赖冲突非常有用。

【讨论】:

    【解决方案4】:

    Tattleltale 是 JBoss 的一个工具

    tattletale.jboss.org/

    【讨论】:

    • 我无法让它为我的 jar 工作。我只是收到大量消息,例如 'java.io.IOException: invalid constant type: 15'
    【解决方案5】:

    如果你使用 maven(据我了解),你可以简单地使用 Maven 依赖插件。

    首先你需要用你所有的 jar 编写一个基本的 pom.xml,你可以复制这个例子(我使用 hibernate 作为例子),并替换你的 jar:

        <?xml version="1.0" encoding="UTF-8"?>
        <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
           <modelVersion>4.0.0</modelVersion>
           <groupId>com.mycompany.app</groupId>
           <artifactId>my-app</artifactId>
           <version>1.0-SNAPSHOT</version>
           <packaging>jar</packaging>
           <name>Maven Quick Start Archetype</name>
           <url>http://maven.apache.org</url>
           <dependencies>
              <dependency>
                 <groupId>org.hibernate</groupId>
                 <artifactId>hibernate-core</artifactId>
                 <version>3.5.0-Final</version>
              </dependency>
    <!-- add here other dependencies -->
           </dependencies>
        </project>
    

    然后打开终端,进入上面 pom.xml 的包含文件夹并运行以下命令:

    mvn 依赖:树

    这将打印一个依赖列表...

    或者如果你想下载并复制到一个文件夹中,所有依赖项运行以下命令:

    mvn 依赖:复制依赖

    您将在文件夹 ./target/dependencies 中找到所有依赖项

    【讨论】:

      【解决方案6】:

      这可能是此工具的替代品。但它没有列出引用的类。最后一个数字决定“包级别”。

      jar tvf yourjar.jar | perl -nle'BEGIN{$depth=(shift)-1}print join(".", (split(/\//, (split)[-1]))[0..$depth])' 3
      

      问题是,这种方式不可能从类定义中获取引用的类。因此,唯一可能的方法似乎是在 JAVA 中进行。

      那么问题来了:有没有 Java 工具可以做到这一点?

      编辑:

      我找到了我需要的东西:M2eclipse 有一个名为类搜索

      的功能

      在 maven 存储库视图中,右键单击存储库并启用完整索引

      然后导航 > 从 maven 打开类型 - 在那里您可以查看所有基于 java 包约定的可用工件

      【讨论】:

      • 到达那里。现在您需要将包列表转换为包含它们的 jar 列表。该列表会很大(库的多个版本),因此您想检查接口兼容性并找到最匹配的一个 - 编写工作量很大,但听起来可行。我会称之为autolinker
      • 我会通过什么搜索来找到 JAR?本地 Maven 存储库?在这种情况下,不可能通过远程 maven repo 进行搜索
      • 这不提供依赖版本。
      【解决方案7】:

      我的第一个想法是,您可以通过使用类加载器来迭代 jar 中的所有类文件并使用反射来分析每个类文件的依赖关系来做到这一点。但是 Class 类没有告诉您此信息的方法。所以下一个想法是使用某种字节码分析器(例如asm)从编译类中提取所有引用的类。

      假设您可以获得此信息,下一个问题是将类回溯到 jar。从某种意义上说,这将是简单的部分,因为您需要做的就是为您的 maven 存储库、目录或 jar 所在的任何位置中的每个 jar 创建一个类加载器,然后依次询问每个 jar 是否包含特定的类。

      这种想法的缺陷是 java 类(原始源代码或编译的)没有详细说明从何处获取导入的类。因此,如果您有两个具有相同包和名称的类(发生的频率比您想象的要多),那么您将无法确定使用哪个类。

      甚至 java 也只是假设它在类路径中找到的第一个是正确的,如果结果不正确则抛出异常 (MethodNotFoundException)。因此,除非您要进一步分析字节码以找出每个类上调用了哪些方法,然后将它们与类路径中的类进行比较,否则您仍然无法正确。

      简而言之,您可能想做什么就做什么,但可能非常困难且耗时。

      我通常处理这个问题的方式是简单地在测试代码中启动类并继续添加依赖项,直到我可以让它执行我感兴趣的每个方法。

      【讨论】:

      • 嗨,德里克,谢谢你的想法。这将是相当耗时的。我会接受 MJB 的回答,因为 JarAnalyzer 正是我正在寻找的。如果它支持递归目录搜索,它实际上会列出您需要的 Maven 依赖项。当然没有版本号和可用的输出,但是你可以很容易地设置 pom 定义。
      【解决方案8】:

      如果你的项目是基于 maven 的项目

      mvn dependency:build-classpath -Dmdep.pathSeparator=":" -Dmdep.prefix='' -Dmdep.fileSeparator=":" -Dmdep.outputFile=classpath
      

      看下面的链接 http://maven.apache.org/plugins/maven-dependency-plugin/build-classpath-mojo.html

      可能是你的情况

      mvn dependency:build-classpath -Dmdep.pathSeparator=":" -Dmdep.prefix='' -Dmdep.fileSeparator=":" -Dmdep.outputFile=classpath -f pathtopom.xml of third party 
      

      【讨论】:

      • 这个问题的重点是以人类可读的形式列出 JAR 中引用的所有类:最高 3-5 级:“org.apache.commons.blabla” ....设置JAR 的依赖列表,用于将其部署为 Maven 工件
      • 您可以读取上述命令产生的输出并将其用于部署!
      • 看,你只有一些 JAR,你想为它创建一个 pom 定义并将它部署为一个工件......我没有任何 maven 项目......我只是想定义它的传递依赖...我不确定你是否理解这个问题的意义
      • 好的。所以你没有为你正在输入的 jar 启用 maven pom 。事实上,大多数项目(开源项目)现在都启用了 maven ,无论如何这又是另一回事了。即使您成功了,您也必须注意 jar 的版本,即使您使用完全限定名称获取工件 id,也无法预测版本,下载的唯一版本将是来自 maven repo 的最新版本。跨度>
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-18
      • 1970-01-01
      • 2015-11-24
      相关资源
      最近更新 更多