【问题标题】:How to analyse which jar file is used in a Java program?如何分析Java程序中使用了哪个jar文件?
【发布时间】:2016-01-12 15:18:27
【问题描述】:

假设有一个名为 callme.jar 的 jar 文件

它位于多个目录中,

如何在运行时分析其中哪一个被使用?

【问题讨论】:

  • 您想从应用内部分析,还是从应用外部分析?
  • externally.otherwise I can just check classpath.

标签: java classpath


【解决方案1】:

使用-verbose:class 参数调用java 可执行文件。这将产生如下输出:

[从文件加载 org.apache.log4j.helpers.ThreadLocalMap:/C:/.../1.2.14/log4j-1.2.14.jar]
[从文件加载org.apache.commons.cli.Option:/C:/.../commons-cli-1.2.jar]

【讨论】:

  • 如果它为它加载的每个类输出,您可能希望将其通过管道传递给 grep:java -verbose:class ... | grep 'callme.jar';应该减少噪音
  • 我认为这个答案应该是公认的
【解决方案2】:

可能不是最简单的方法,但您可以查看进程打开了哪些文件并从中确定。

如果您在 Windows 上,您可以使用 Process Explorer 查看进程在任何给定时间打开了哪些文件,或使用 Process Monitor 在文件系统运行时查看文件系统访问。会有很多噪音,但你可以从那里弄清楚。

如果您使用的是 Mac,我认为内置的活动监视器可以为您提供打开文件的列表。遗憾的是我不知道你在 Linux 中使用的命令。

【讨论】:

  • lsof -p PID - 将列出在 linux 中为特定进程打开的文件
【解决方案3】:
System.getProperty("java.class.path");

【讨论】:

  • 这个答案看似正确 - 因为 JVM(或者至少是 Sun 的?)将从包含它的类路径上的第一个位置加载该类;按照类路径的顺序
  • 这只有在您可以控制代码时才有效。这里可能就是这种情况,但我不确定。
【解决方案4】:

试试这段代码:

    //Get the System Classloader
    ClassLoader sysClassLoader = ClassLoader.getSystemClassLoader();

    //Get the URLs
    URL[] urls = ((URLClassLoader)sysClassLoader).getURLs();
    System.out.println("CURRENT CLASSPATH :");
    for(int i=0; i< urls.length; i++){
        System.out.println(urls[i].getFile());
    }       
    System.out.println("END OF CLASSPATH");

【讨论】:

    【解决方案5】:

    只有在调用该 jar 的代码正在执行(即被覆盖)时,才能知道是否正在使用 JAR 中的一段代码。直到您的代码未被覆盖为止,很难知道您的应用程序类路径上的 jar 是否正在被使用。

    为此,您可能需要正确的 junit 测试用例,它可以覆盖您的整个代码,然后您可以使用类依赖分析器工具。

    这是一种尝试和观察的事情。您可以尝试逐个删除 JAR 并检查应用程序是否正常工作,但 junit 案例是进行此检查的最佳选择。

    【讨论】:

    • 有了这个答案所暗示的详尽的(单元)测试套件,再加上 JVM 选项-verbose:class(不使用依赖分析器,也没有手动删除 jar-s),即使在复杂的设置中,你也有一个很好的改变例如具有深层类加载器层次结构的 Web 应用程序,可能具有自定义加载策略。
    猜你喜欢
    • 1970-01-01
    • 2011-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-15
    • 1970-01-01
    • 2017-04-09
    相关资源
    最近更新 更多