天天看點

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.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 -> not found
   edu.udo.sh -> com.beust.jcommander  not found
   edu.udo.sh -> edu.udo.sh.data       sh-2.6.3.jar
   edu.udo.sh -> edu.udo.sh.gui        sh-2.6.3.jar
   edu.udo.sh -> edu.udo.sh.gui.util   sh-2.6.3.jar
   edu.udo.sh -> edu.udo.sh.util       sh-2.6.3.jar
   edu.udo.sh -> java.io               java.base
   edu.udo.sh -> java.lang             java.base
   edu.udo.sh -> javax.swing           java.desktop
   edu.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_JDeps入門–分析項目的依賴關系

包括依賴項

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.jar
   edu.udo.sh -> edu.udo.sh.data       sh-2.6.3.jar
   edu.udo.sh -> edu.udo.sh.gui        sh-2.6.3.jar
   edu.udo.sh -> edu.udo.sh.gui.util   sh-2.6.3.jar
   edu.udo.sh -> edu.udo.sh.util       sh-2.6.3.jar
   edu.udo.sh -> java.io               java.base
   edu.udo.sh -> java.lang             java.base
   edu.udo.sh -> javax.swing           java.desktop
   edu.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
           
jdeps_JDeps入門–分析項目的依賴關系

深鑽

如果您想了解更多細節,-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子產品系統

jdeps_JDeps入門–分析項目的依賴關系
  • 子產品系統的深入介紹:
    • 基本概念和進階主題
  • 曼甯(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