jdeps_JDeps入门–分析项目的依赖关系

jdeps

JDeps是Java依赖关系分析工具 ,这是一个命令行工具,它处理Java字节码(意味着.class文件或包含它们的JAR),并分析类之间静态声明的依赖关系。 可以用各种方式过滤结果,并可以将其汇总到包或JAR级别。 JDeps还可以告诉您您的项目正在使用哪些JDK内部API,并且完全了解模块系统 。 总而言之,它是检查各种形式的依赖图的非常有用的工具。

在这篇文章中,我将向您介绍JDeps的工作方式-后续文章将向您展示一些很好的用例。 对于此探索,我鼓励您继续进行,最好是执行您的一个项目。 如果您有一个项目的JAR,并且在它旁边是一个包含所有传递依赖项的文件夹,这将是最容易的。 如果您使用的是Maven,则可以通过maven-dependency-plugin的copy-dependencies目标实现后者。 使用Gradle,您可以使用复制任务,从设置为configuration.compile或configuration.runtime 。

作为示例项目,我选择了Scaffold Hunter :

Scaffold Hunter是基于Java的开源工具,用于对数据集进行可视化分析,重点是生命科学中的数据,旨在直观地访问大型和复杂的数据集。 该工具提供多种视图,例如图形,树状图和图解视图,以及分析方法,例如用于聚类和分类

我下载了2.6.3版本的ZIP,并将所有依赖项都复制到了libs中。

当显示输出时,我将scaffoldhunter(在软件包名称中)和scaffold-hunter(在文件名称中)缩写为sh以使其更短。

认识JDeps

从Java 8开始,您就可以在JDK的bin文件夹中找到JDeps可执行文件jdeps。如果在命令行上可以找到JDeps可执行文件jdeps,则最容易使用它,对此您可能必须执行一些特定于操作系统的设置步骤。 确保jdeps –version可以正常工作并显示Java 9版本正在运行。

下一步是获取JAR并将JDeps设置为宽松。 在不使用其他命令行选项的情况下使用,它将首先列出代码所依赖的JDK模块。 紧随其后的是软件包级别的依赖关系列表,其组织为<package>-> <package> <module / JAR>。

调用jdeps sh-2.6.3.jar会得到以下输出:

$ jdeps sh-2.6.3.jarsh-2.6.3.jar -> java.base
sh-2.6.3.jar -> java.datatransfer
sh-2.6.3.jar -> java.desktop
sh-2.6.3.jar -> java.logging
sh-2.6.3.jar -> java.prefs
sh-2.6.3.jar -> java.sql
sh-2.6.3.jar -> java.xml
sh-2.6.3.jar -> not foundedu.udo.sh -> com.beust.jcommander  not foundedu.udo.sh -> edu.udo.sh.data       sh-2.6.3.jaredu.udo.sh -> edu.udo.sh.gui        sh-2.6.3.jaredu.udo.sh -> edu.udo.sh.gui.util   sh-2.6.3.jaredu.udo.sh -> edu.udo.sh.util       sh-2.6.3.jaredu.udo.sh -> java.io               java.baseedu.udo.sh -> java.lang             java.baseedu.udo.sh -> javax.swing           java.desktopedu.udo.sh -> org.slf4j             not found
[... truncated many more package dependencies ...]

您可以看到Scaffold Hunter依赖于模块java.base (当然), java.desktop (这是一个Swing应用程序), java.sql (数据集存储在SQL数据库中)以及其他一些模块。 这之后是一长串的软件包依赖项,这有点麻烦。请注意,有些依赖项被标记为未找到,这很有意义,因为我没有告诉JDeps在哪里寻找它们。

现在是时候使用各种选项来配置JDeps了。 您可以使用jdeps -h列出它们。

包括依赖项

JDeps的一个重要方面是,它使您可以像分析代码一样将其依赖性进行分析。 达到该目标的第一步是使用–class-path将它们放到类路径中。

这使JDeps可以遵循进入依赖项JAR的路径,并使您摆脱未找到的指标。 要实际分析依赖关系,还需要使用-recursive或-R将JDeps递归到它们。

为了包括Scaffold Hunter的依赖关系,我使用–class-path'libs / *'和-recursive执行JDeps:

$ jdeps --class-path 'libs/*' -recursive sh-2.6.3.jar[... truncated split package warnings ...]
[... truncated some module/JAR dependencies...]
sh-2.6.3.jar -> libs/commons-codec-1.6.jar
sh-2.6.3.jar -> libs/commons-io-2.4.jar
sh-2.6.3.jar -> libs/dom4j-1.6.1.jar
sh-2.6.3.jar -> libs/exp4j-0.1.38.jar
sh-2.6.3.jar -> libs/guava-18.0.jar
sh-2.6.3.jar -> libs/heaps-2.0.jar
sh-2.6.3.jar -> libs/hibernate-core-4.3.6.Final.jar
sh-2.6.3.jar -> java.base
sh-2.6.3.jar -> java.datatransfer
sh-2.6.3.jar -> java.desktop
sh-2.6.3.jar -> java.logging
sh-2.6.3.jar -> java.prefs
sh-2.6.3.jar -> java.sql
sh-2.6.3.jar -> java.xml
sh-2.6.3.jar -> libs/javassist-3.18.1-GA.jar
sh-2.6.3.jar -> libs/jcommander-1.35.jar
[... truncated more module/JAR dependencies...]edu.udo.sh -> com.beust.jcommander  jcommander-1.35.jaredu.udo.sh -> edu.udo.sh.data       sh-2.6.3.jaredu.udo.sh -> edu.udo.sh.gui        sh-2.6.3.jaredu.udo.sh -> edu.udo.sh.gui.util   sh-2.6.3.jaredu.udo.sh -> edu.udo.sh.util       sh-2.6.3.jaredu.udo.sh -> java.io               java.baseedu.udo.sh -> java.lang             java.baseedu.udo.sh -> javax.swing           java.desktopedu.udo.sh -> org.slf4j             slf4j-api-1.7.5.jar
[... truncated many, many more package dependencies ...]

在这种特定情况下,输出以一些拆分程序包警告开头,我现在将忽略它们。 以下模块/ JAR和程序包的依赖关系与以前类似,但现在都可以找到,因此它们的数量更多。 但是,这会使输出变得更加压倒一切,因此现在该是时候探讨如何从如此大量的数据中弄清楚了。

配置JDeps的输出

有多种方法可以配置JDeps的输出。 也许在任何项目的第一次分析中使用的最佳选择是-summary或​​-s,它们仅显示JAR之间的依赖关系,而忽略包的依赖关系。 下表列出了各种其他方式来获取有关依赖关系的不同观点:

选项 描述
–package或-p 其次是只考虑该包,这是看哪里使用这些utils的所有地方一个伟大的方式依赖包名。
–regex或-e 后跟一个正则表达式,它仅考虑与正则表达式匹配的类的依赖。
(请注意,除非使用-verbose:class,否则输出仍会显示包。)
-filter或-f 后跟一个正则表达式,它排除对与正则表达式匹配的类的依赖。
(请注意,除非使用-verbose:class,否则输出仍会显示包。)
-filter:存档 在许多情况下,工件的依赖性不是那么有趣。
该选项将忽略它们,仅显示工件的依赖性。
–仅API 有时,尤其是在分析库时,您只关心JAR API。
使用此选项,仅检查公共签名和公共类的受保护成员的签名中提到的类型。

命令行上的输出是检查细节并深入研究有趣的位的好方法。 但是,它并不能提供最直观的概述-图表要好得多。 幸运的是,JDeps具有–dot-output选项,该选项可为每个单独的分析创建.dot文件 。 这些文件是纯文本,但是可以使用其他工具(例如Graphviz)从它们创建图像。

这两个命令产生下图:

$ jdeps --class-path 'libs/*' -recursive --dot-output dots sh-2.6.3.jar
$ dot -Tpng -O dots/summary.dot

深钻

如果您想了解更多细节,-verbose:class将列出类之间的依赖关系,而不是将它们聚合到包级别。

有时,仅列出对程序包或类的直接依赖关系是不够的,因为它们可能实际上不在您的代码中,而是在您的依赖关系中。 在这种情况下,-inverse或-I可能会有所帮助。 给定要查找的特定程序包或正则表达式,它会一直跟踪依赖关系,并在此过程中列出工件。 不幸的是,似乎没有直接方法可以在类级别而不是工件上查看结果。

在您的特定情况下,还有其他一些选项可能会对您有所帮助–如前所述,您可以使用jdeps -h列出它们。

JDeps和模块

就像借助模块系统一样,编译器和JVM可以在更高的抽象级别上运行 ,JDeps也可以。 可以使用–module-path指定模块路径(请注意-p已经保留,因此它不是此选项的简写形式),而初始模块可以使用–module或-m指定。 从那里,我们上面所做的分析可以完全相同。

因为Scaffold Hunter尚未模块化,所以我将切换到我的书中使用的关于Java 9模块系统的示例项目Monitor应用程序 。 在这里,我正在创建模块关系的摘要分析:

# on `master` branch
$ jdeps --module-path mods:libs -m monitor -summary -recursive[... truncated some module dependencies...]
monitor -> java.base
monitor -> monitor.observer
monitor -> monitor.observer.alpha
monitor -> monitor.observer.beta
monitor -> monitor.persistence
monitor -> monitor.rest
monitor -> monitor.statistics
monitor.observer -> java.base
monitor.observer.alpha -> java.base
monitor.observer.alpha -> monitor.observer
monitor.observer.beta -> java.base
monitor.observer.beta -> monitor.observer
monitor.persistence -> java.base
monitor.persistence -> monitor.statistics
monitor.rest -> java.base
monitor.rest -> monitor.statistics
monitor.rest -> spark.core
monitor.statistics -> java.base
monitor.statistics -> monitor.observer
slf4j.api -> java.base
slf4j.api -> not found
spark.core -> JDK removed internal API
spark.core -> java.base
spark.core -> javax.servlet.api
spark.core -> jetty.server
spark.core -> jetty.servlet
spark.core -> jetty.util
spark.core -> slf4j.api
spark.core -> websocket.api
spark.core -> websocket.server
spark.core -> websocket.servlet
[... truncated more module dependencies...]

除此之外,还有一些Java 9和特定于模块的选项。 使用–require <modules>,您可以列出所有需要命名模块的模块。 您可以使用–jdk-internals分析项目的问题依赖关系,以及–generate-module-info或–generate-open-module创建模块描述符的初稿。 正如前面提到的,JDeps还将始终报告其找到的所有拆分包。

在以后的文章中,我将向您展示如何使用这些标志来帮助您的项目进行模块化。

获取我的书,并了解有关如何在Java 9迁移中使用JDeps的更多信息!
Java 9模块系统

  • 模块系统的深入介绍:
    • 基本概念和高级主题
  • 曼宁(Manning)发布:
    • 自2017年赛事开始提供抢先体验
  • 订阅我的时事通讯以保持关注。
    (甚至可以偷看。)

使用代码fccparlog可获得 37%的折扣

反射

使用JDeps,您可以分析项目的静态声明的依赖关系。 它在类级别上运行,但是将结果汇总到包和工件级别。 使用各种过滤器,您可以专注于最重要的方面。 也许最基本的分析是跨代码和第三方库的工件依赖关系图:

$ jdeps --class-path 'libs/*' -summary -recursive sh-2.6.3.jar

它可用于执行一些非常有趣的分析,尤其是在较大的代码库上。 我将很快为您展示一些示例。

翻译自: https://www.javacodegeeks.com/2017/07/jdeps-primer-analyzing-projects-dependencies.html

jdeps

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/334818.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

extjs5的grid垂直滚动条bug_ExtJS 6.2.1 Classic Grid 滚动条bug解决方案

如果列表同时存在横向滚动条和竖向滚动条&#xff0c;当竖向滚动条滚动到底部时点击横向滚动条&#xff0c;滚动条会自动滚动到顶部此bug未在其他版本发现&#xff0c;参考高版本代码重写类解决此bug&#xff0c;直接上代码&#xff1a;/*** 如果列表同时存在横向滚动条和竖向滚…

禁止linux使用密码ssh,linux centos7服务器使用密钥登录ssh同时禁止root密码登录

这两天在大量的给服务器添加密钥&#xff0c;有的服务器简单绑定下就行了。但是京东云目前就毕竟弱了&#xff0c;得自己手动来。目前京东云的服务器需要自己手动修改配置&#xff0c;才能用密钥登录服务器&#xff0c;不然默认还是root用密码登录。把密钥保存到本地&#xff0…

cloudwatch_将CloudWatch Logs与Cloudhub Mule集成

cloudwatch在此博客中&#xff0c;我将解释如何为您的Mule CloudHub应用程序启用AWS Cloudwatch日志 。 AWS提供了Cloudwatch Logs Services&#xff0c;以便您可以更好地管理日志。 它比松散便宜。 由于cloudhub会自动翻转超过100 MB的日志&#xff0c;因此我们需要一种机制来…

linux 权限 mask,【自学Linux】Linux用户、组、权限(一)

用户、组、权限权限&#xff1a;r,w,x文件:r:可读&#xff0c;可以使用类似cat等命令查看文件内容w:可写&#xff0c;可以编辑或删除此文件x:可执行&#xff0c;eXacutable&#xff0c;可以命令提示符下当中命令提交给内核运行0 000 ---&#xff1a;无权限1 001 --x&#xff1a…

要多大内存才满足_什么是延迟满足能力?“延迟满足”能力对孩子有多重要家长要清楚...

文丨饭饭妈记得去年过春节的时候&#xff0c;家里来了两个亲戚&#xff0c;他们分别有一个小孩&#xff0c;当时大家都在准备年夜饭。其中一份糯米团子准备好放在桌子上之后&#xff0c;亲戚家的两个小孩都非常想要吃&#xff0c;亲戚对孩子说&#xff1a;“你们现在不能吃&…

Linux 命令之 cd 命令-切换目录

文章目录介绍语法格式常用选项参考示例介绍 cd 命令是 change directory 中单词的首字母缩写&#xff0c;其英文释义是改变目录&#xff0c;所以该命令的功能是从当前目录切换到指定目录。 其中目录的路径可分为绝对路径和相对路径。若目录名称省略&#xff0c;则切换至使用者…

Linux 命令之 pgrep -- 用于检索(搜索进程/查找进程)当前正在运行的进程

文章目录命令介绍常用选项参考示例示例 1&#xff0c;查看所有名称为 httpd 的进程示例 2&#xff0c;查看进程号最小的&#xff0c;名称为 httpd 的进程示例 3&#xff0c;查看进程号最大的&#xff0c;名称为 httpd 的进程命令介绍 pgrep 的意思是"进程号全局正则匹配输…

java端到端_Java应用程序性能监控:复杂分布式应用程序的端到端性能

java端到端通过从您的应用程序学习企业APM产品&#xff0c;发现更快&#xff0c;更有效的性能监控。 参加AppDynamics APM导览&#xff01; 在最复杂和分布式环境中端到端监视Java应用程序性能-专注于业务事务。 自动发现的业务交易&#xff0c;动态基准&#xff0c;代码级诊断…

Linux内核链表访问链表头指针,linux内核——链表结构分析

http://blog.csdn.net/tigerjibo/article/details/8299584简单整理(使用linux3.0内核)这里首先学习的是内核中一种抽象定义的双向链表&#xff0c;为了提高其扩展性。内核中链表的描述数据结构位置&#xff1a;Types.h (linux-3.0.12\include\linux) 5444 2011/11/2922…

遗传算法求二元函数极值怎么编码_用遗传算法求复杂函数的极值点

确定遗传在元素个体&#xff0c;遗传得到的个体和变异个体中选取最好的30个个体(对应的函数值最大的30个个体)作为下一次迭代的父样本。from random import randintfrom numpy import sindef decode(g):return [((g&0xfff) - 2048) * 0.001, ((g>>12) - 2048) * 0.00…

Linux 命令之 ulimit 命令-控制shell程序的资源

文章目录介绍常用选项参考示例介绍 用来限制系统用户对 shell 资源的访问。如果不懂什么意思&#xff0c;下面一段内容可以帮助你理解&#xff1a; 假设有这样一种情况&#xff0c;当一台 Linux 主机上同时登陆了 10 个人&#xff0c;在系统资源无限制的情况下&#xff0c;这…

java jvm虚拟机_Java虚拟机(JVM)简介

java jvm虚拟机什么是JVM Java虚拟机&#xff08;JVM&#xff09;是使计算机能够运行Java程序的抽象计算机。 JVM有三个概念&#xff1a; 1.规格 2.实施 3.实例。 该规范是正式描述JVM实现要求的文档。 具有单一规范可确保所有实现都可互操作。 JVM实现是满足JVM规范要求的…

linux qt应用程序全屏,QT在ubuntu下实现界面全屏,侧边栏隐藏,上边栏隐藏【实例】...

最近做一个Qt项目(ubuntu 14.04)&#xff0c;需要将界面全屏&#xff0c;全屏之后&#xff0c;ubuntu侧边栏隐藏&#xff0c;上边栏也隐藏&#xff0c;只显示Qt的界面。那么先介绍几个函数&#xff1a;Qt全屏显示函数&#xff1a;showFullScreen()Qt最大化显示函数&#xff1a;…

copyof java_JDK10——copyOf方法

package com.common.learn;import java.util.ArrayList;import java.util.HashMap;import java.util.HashSet;import java.util.List;import java.util.Map;import java.util.Set;/*** author 30378** JDK10中新增73个新功能API类库* 在java.util.List java.util.Set java.util…

Linux 命令之 w 命令-显示目前登入系统的用户信息

文章目录介绍常用选项参考示例显示目前登入系统的用户信息不打印头信息显示用户从哪登录使用短输出格式介绍 w 命令用于显示已经登陆系统的用户列表&#xff0c;并显示用户正在执行的指令。执行这个命令可得知目前登入系统的用户有那些人&#xff0c;以及他们正在执行的程序。…

linux系统引导分区,揭秘Linux(二)——操作系统引导与硬盘分区

通过前面的介绍想必大家对Linux有了个基础的了解&#xff0c;那么各位肯定该说是不是要装操作系统了&#xff0c;对不起让各位失望了&#xff0c;这次所讲解的是Linux运行原理与硬盘分区&#xff0c;这是重中之重啊&#xff01;请一定要细细品读。为了更好地了解Linux系统的运行…

jax-rs/jersey_JAX-RS 2.1的Jersey客户端依赖性

jax-rs/jersey泽西岛是JAX-RS 2.1的参考实现。 为了在企业容器外部运行具有JSON-P和JSON-B映射的JAX-RS 2.1客户端&#xff0c;需要以下Jersey依赖项。 Jersey客户端2.6版实现了JAX-RS 2.1 API。 以下依赖性将客户端运行时添加到项目中&#xff1a; <dependency><gr…

get占位符传多个参数_mybatis多个参数(不使用@param注解情况下),sql参数占位符正确写法...

useActualParamName配置useActualParamName允许使用方法签名中的名称作为语句参数名称。 为了使用该特性&#xff0c;你的工程必须采用Java 8编译&#xff0c;并且加上-parameters选项。(从3.4.1开始)true | falsetruemybatis的全局配置useActualParamName决定了mapper中参数的…

HTTP协议简介_请求消息/请求数据包/请求报文_响应消息/响应数据包/响应报文

文章目录HTTP 介绍请求数据包/请求消息/请求报文请求数据包解析响应数据包/响应消息/响应报文HTTP 介绍 概念&#xff1a;Hyper Text Transfer Protocol 超文本传输协议 传输协议&#xff1a;定义了客户端和服务器端通信时发送数据的格式 特点: 1.基于TCP/IP的高级协议 2.默认…

Linux的open函数的调用过程,Linux 中open系统调用实现原理

用户空间的函数在内核里面的入口函数是sys_open通过grep open /usr/include/asm/unistd_64.h查找到的#define __NR_open2__SYSCALL(__NR_open, sys_open)观察unistd_64.h&#xff0c;我们可以猜测用户空间open函数最终调用的系统调用号是2来发起的sys_open系统调用(毕竟glibc一…