torutkのブログ

ソフトウェア・エンジニアのブログ

JDK 8のjdepsでJARファイル間の依存関係を可視化

Java SE 8 Development Kit(JDK 8)で新たに搭載されたコマンドjdepsは、JavaのクラスファイルやJARファイルから、JARファイルやパッケージやクラスの間の依存関係を解析します。ツールの結果はテキスト(標準出力)とdot形式ファイル(Graphvizでグラフィカルに表示)として生成できます。

http://docs.oracle.com/javase/8/docs/technotes/tools/unix/jdeps.html

今回は、JARファイル間の依存関係をjdepsコマンドで調べてみました。

GeoToolsのJARファイルの依存関係を調べる

Javaオープンソース地図ライブラリGeoToolsは、多数のJARファイルから構成されています。
http://www.geotools.org/

次にGeoTools 11.1に含まれるJAR一覧を示します。実に190個もあります。

batik-transcoder-1.7.jar                gt-jdbc-h2-11.1.jar                      imageio-ext-gdalecw-1.1.9.jar
bridj-0.6-c-only.jar                    gt-jdbc-mysql-11.1.jar                   imageio-ext-gdalecwjp2-1.1.9.jar
bufr-4.3.16.jar                         gt-jdbc-oracle-11.1.jar                  imageio-ext-gdalehdr-1.1.9.jar
common-2.6.0.jar                        gt-jdbc-postgis-11.1.jar                 imageio-ext-gdalenvihdr-1.1.9.jar
commons-beanutils-1.7.0.jar             gt-jdbc-spatialite-11.1.jar              imageio-ext-gdalerdasimg-1.1.9.jar
commons-cli-2.0-gt2-pre1.jar            gt-jdbc-sqlserver-11.1.jar               imageio-ext-gdalidrisi-1.1.9.jar
commons-codec-1.2.jar                   gt-jdbc-teradata-11.1.jar                imageio-ext-gdalkakadujp2-1.1.9.jar
commons-collections-3.1.jar             gt-jp2k-11.1.jar                         imageio-ext-gdalmrsid-1.1.9.jar
commons-dbcp-1.4.jar                    gt-jts-wrapper-11.1.jar                  imageio-ext-gdalmrsidjp2-1.1.9.jar
commons-digester-1.7.jar                gt-main-11.1.jar                         imageio-ext-gdalnitf-1.1.9.jar
commons-httpclient-3.1.jar              gt-mark-wkt-11.1.jar                     imageio-ext-gdalrpftoc-1.1.9.jar
commons-io-2.1.jar                      gt-matfile5-11.1.jar                     imageio-ext-geocore-1.1.9.jar
commons-jxpath-1.3.jar                  gt-mbtiles-11.1.jar                      imageio-ext-imagereadmt-1.1.9.jar
commons-lang-2.3.jar                    gt-metadata-11.1.jar                     imageio-ext-imagereadmt-1.1M012010.jar
commons-logging-1.1.1.jar               gt-mongodb-11.1.jar                      imageio-ext-kakadu-1.1.9.jar
commons-pool-1.5.4.jar                  gt-netcdf-11.1.jar                       imageio-ext-mat-sas-1.1M012010.jar
core.commands-3.6.0.I20100512-1500.jar  gt-ogr-bridj-11.1.jar                    imageio-ext-streams-1.1.9.jar
core.runtime-3.6.0.v20100505.jar        gt-ogr-core-11.1.jar                     imageio-ext-tiff-1.1.9.jar
eastwood-1.1.1-20090908.jar             gt-ogr-jni-11.1.jar                      imageio-ext-utilities-1.1.9.jar
ecore-2.6.1.jar                         gt-opengis-11.1.jar                      jai_codec-1.1.3.jar
ehcache-1.6.2.jar                       gt-process-11.1.jar                      jai_core-1.1.3.jar
equinox.common-3.6.0.v20100503.jar      gt-process-feature-11.1.jar              jai_imageio-1.1.jar
gdal-1.8.1.jar                          gt-process-geometry-11.1.jar             javacsv-2.0.jar
geodb-0.7-RC2.jar                       gt-process-raster-11.1.jar               jdom-1.1.3.jar
grib-4.3.16.jar                         gt-property-11.1.jar                     jface-3.6.1.M20100825-0800.jar
gt-api-11.1.jar                         gt-property-ng-11.1.jar                  jgridshift-1.0.jar
gt-app-schema-11.1.jar                  gt-referencing-11.1.jar                  json-simple-1.1.jar
gt-app-schema-resolver-11.1.jar         gt-referencing3D-11.1.jar                jsqlparser-0.3.14.jar
gt-arcgrid-11.1.jar                     gt-render-11.1.jar                       jsr-275-1.0-beta-2.jar
gt-arcsde-11.1.jar                      gt-sample-data-11.1.jar                  jt-contour-1.3.1.jar
gt-arcsde-common-11.1.jar               gt-sample-data-access-11.1.jar           jt-rangelookup-1.3.1.jar
gt-brewer-11.1.jar                      gt-sfs-11.1.jar                          jts-1.13.jar
gt-charts-11.1.jar                      gt-shapefile-11.1.jar                    jt-utils-1.3.1.jar
gt-complex-11.1.jar                     gt-shapefile-old-11.1.jar                jt-vectorbinarize-1.3.1.jar
gt-complex-11.1-tests.jar               gt-svg-11.1.jar                          jt-vectorize-1.3.1.jar
gt-coverage-11.1.jar                    gt-swing-11.1.jar                        jt-zonalstats-1.3.1.jar
gt-coverage-api-11.1.jar                gt-swt-11.1.jar                          log4j-over-slf4j-1.6.4.jar
gt-coveragetools-11.1.jar               gt-transform-11.1.jar                    miglayout-3.7-swing.jar
gt-cql-11.1.jar                         gt-unidata-11.1.jar                      mongo-java-driver-2.5.jar
gt-csv-11.1.jar                         gt-validation-11.1.jar                   mysql-connector-java-5.1.17.jar
gt-data-11.1.jar                        gt-vpf-11.1.jar                          net.opengis.csw-11.1.jar
gt-epsg-extension-11.1.jar              gt-wfs-11.1.jar                          net.opengis.fes-11.1.jar
gt-epsg-hsql-11.1.jar                   gt-wms-11.1.jar                          net.opengis.ows-11.1.jar
gt-epsg-oracle-11.1.jar                 gt-wps-11.1.jar                          net.opengis.wcs-11.1.jar
gt-epsg-postgresql-11.1.jar             gt-xml-11.1.jar                          net.opengis.wfs-11.1.jar
gt-epsg-wkt-11.1.jar                    gt-xsd-core-11.1.jar                     net.opengis.wps-11.1.jar
gt-feature-aggregate-11.1.jar           gt-xsd-csw-11.1.jar                      netcdf-4.3.16.jar
gt-feature-pregeneralized-11.1.jar      gt-xsd-fes-11.1.jar                      opendap-2.1.jar
gt-geojson-11.1.jar                     gt-xsd-filter-11.1.jar                   org.w3.xlink-11.1.jar
gt-geometry-11.1.jar                    gt-xsd-gml2-11.1.jar                     picocontainer-1.2.jar
gt-geopkg-11.1.jar                      gt-xsd-gml3-11.1.jar                     postgresql-8.4-701.jdbc3.jar
gt-geotiff-11.1.jar                     gt-xsd-kml-11.1.jar                      slf4j-log4j12-1.5.6.jar
gt-graph-11.1.jar                       gt-xsd-ows-11.1.jar                      slf4j-log4j12-1.6.4.jar
gt-grassraster-11.1.jar                 gt-xsd-sld-11.1.jar                      spatialite-jdbc-3.7.2-2.4.jar
gt-grib-11.1.jar                        gt-xsd-wcs-11.1.jar                      sqlite-jdbc-3.7.2.jar
gt-grid-11.1.jar                        gt-xsd-wfs-11.1.jar                      swt.gtk.linux.x86-3.6.1.v3655c.jar
gt-gtopo30-11.1.jar                     gt-xsd-wms-11.1.jar                      swt.win32.win32.x86_64-3.6.1.v3655c.jar
gt-image-11.1.jar                       gt-xsd-wps-11.1.jar                      ui.workbench-3.6.1.M20100826-1330.jar
gt-imageio-ext-gdal-11.1.jar            h2-1.1.119.jar                           vecmath-1.3.2.jar
gt-imagemosaic-11.1.jar                 hsqldb-2.2.8.jar                         xml-commons-resolver-1.2.jar
gt-imagemosaic-jdbc-11.1.jar            icu4j-3.4.4.jar                          xpp3_min-1.1.4c.jar
gt-imagepyramid-11.1.jar                imageio-ext-arcgrid-1.1.9.jar            xsd-2.6.0.jar
gt-jdbc-11.1.jar                        imageio-ext-gdalarcbinarygrid-1.1.9.jar
gt-jdbc-db2-11.1.jar                    imageio-ext-gdaldted-1.1.9.jar

ここで、gt-api-11.1.jar (GeoToolsの主要APIを提供するJAR)に着目し、このJARが依存しているJARをjdepsコマンドで調べてみます。

まずは、jdepsのオプション説明を見ながら、次のコマンドを実行します。

C:\java\geotools-11.1> jdeps -s -cp * gt-api-11.1.jar
gt-api-11.1.jar -> jsr-275-1.0-beta-2.jar
gt-api-11.1.jar -> gt-metadata-11.1.jar
gt-api-11.1.jar -> jts-1.13.jar
gt-api-11.1.jar -> gt-referencing-11.1.jar
gt-api-11.1.jar -> C:\Program Files\Java\jdk1.8.0_05\jre\lib\rt.jar
gt-api-11.1.jar -> gt-opengis-11.1.jar
C:\java\geotools-11.1>

gt-api-11.1.jarが直接依存するJARファイルが解析できました。

  • -sオプションはサマリのみ表示で、JARファイルの依存関係のみ表示されます。
  • -cpオプションはクラスパス指定でJDKの他のツールと同じ指定が使えます。クラスパス指定ではアスタリスク'*'はJARにマッチします。

実行結果は、graphviz(dot形式)へも出力できます。
http://www.graphviz.org/

C:\java\geotools-11.1>jdeps -s -dotoutput r:\temp\dot -cp * gt-api-11.1.jar

C:\java\geotools-11.1>dir /b r:\temp\dot
summary.dot
C:\java\geotools-11.1>

summary.dotをGraphvizで開くと、次のようなグラフが見えます。

さて、ここまでの結果は、指定したgt-api-11.1.jarが直接依存しているJARファイルです。gt-api-11.1.jarを使用するプログラムを実行するのに必要なJARのすべてではありません。gt-api-11.1.jarが依存するJARがさらに別なJARに依存している場合、プログラムの実行にはそのJARも必要となります。

jdepsでは、-Rオプション(-recursiveオプション)を指定することで、gt-api-11.1.jarから依存するJARファイルを再帰的に解析します。

C:\java\geotools-11.1>jdeps -R -s -cp * gt-api-11.1.jar
gt-api-11.1.jar -> C:\Program Files\Java\jdk1.8.0_05\jre\lib\rt.jar
gt-api-11.1.jar -> gt-referencing-11.1.jar
gt-api-11.1.jar -> jsr-275-1.0-beta-2.jar
gt-api-11.1.jar -> jts-1.13.jar
gt-api-11.1.jar -> gt-metadata-11.1.jar
gt-api-11.1.jar -> gt-opengis-11.1.jar
gt-metadata-11.1.jar -> C:\Program Files\Java\jdk1.8.0_05\jre\lib\rt.jar
gt-metadata-11.1.jar -> gt-opengis-11.1.jar
gt-opengis-11.1.jar -> C:\Program Files\Java\jdk1.8.0_05\jre\lib\rt.jar
gt-opengis-11.1.jar -> jsr-275-1.0-beta-2.jar
gt-referencing-11.1.jar -> C:\Program Files\Java\jdk1.8.0_05\jre\lib\rt.jar
gt-referencing-11.1.jar -> jsr-275-1.0-beta-2.jar
gt-referencing-11.1.jar -> gt-metadata-11.1.jar
gt-referencing-11.1.jar -> gt-opengis-11.1.jar
gt-referencing-11.1.jar -> vecmath-1.3.2.jar
jsr-275-1.0-beta-2.jar -> C:\Program Files\Java\jdk1.8.0_05\jre\lib\rt.jar
jts-1.13.jar -> C:\Program Files\Java\jdk1.8.0_05\jre\lib\rt.jar
vecmath-1.3.2.jar -> C:\Program Files\Java\jdk1.8.0_05\jre\lib\rt.jar
C:\Program Files\Java\jdk1.8.0_05\jre\lib\jce.jar -> C:\Program Files\Java\jdk1.8.0_05\jre\lib\rt.jar
C:\Program Files\Java\jdk1.8.0_05\jre\lib\rt.jar -> C:\Program Files\Java\jdk1.8.0_05\jre\lib\jce.jar

C:\java\geotools-11.1>

テキスト結果ではだんだん把握が困難になってきました。dot形式で出力しGraphvizで結果を見てみます。

C:\java\geotools-11.1>jdeps -R -s -dotoutput r:\temp\dot -cp * gt-api-11.1.jar

C:\java\geotools-11.1>

summary.dotをGraphvizで開くと、次のようなグラフが見えます。

すべてのJARファイルの依存関係を解析するには、

C:\java\geotools-11.1>jdeps -s -dotoutput r:\temp\dot -cp * *.jar

C:\java\geotools-11.1>

とすればいいと思われます。クラスパス指定にカレントディレクトリのすべてのJARファイルを、解析対象にカレントディレクトリのすべてのJARを指定したつもりです。

GeoToolsについてこれを実行した結果はすごいことになったので省略します(GraphvizPNG画像出力が12MBと巨大なものに・・・)

大きなアプリケーションプログラムを開発するときは、複数のビルド単位(IDEのプロジェクト)に分割して開発するアプローチをとることが多いかと思います。各ビルド単位でJARファイルを生成するので、JARファイルの依存関係を調べることでプロジェクト間の実際の依存関係が把握できます。

その他

この手の構造解析用ツールは、古くからjdependなどのオープンソースツールをはじめ商用製品もいろいろ存在します。設計の観点で本格的な解析をするならば、そうした専用のツールを用いるのがよいでしょう。

jdependでは、主系列解析もできるのでおすすめです。
http://d.hatena.ne.jp/torutk/20050419/p2