Javaの依存関係管理:アプリケーションには何行のコードが含まれているのか?
2020年8月12日
0 分で読めます数週間前、オランダのJavaカンファレンス JSpringで講演する機会がありました。テーマはJavaの依存関係管理でした。
講演では、シンプルなSpring Bootアプリケーションを作成し、自分で書いたコードの行数と、Javaの依存関係によって追加されるコードの行数を比較しました。依存関係がアプリケーションの大部分を占めており、それらにも注意を払う必要があることを示すためです。講演後、この内容について投稿した次のツイートが大きな反響を呼び、この記事を書くきっかけになりました。
Javaの依存関係が追加するコード行数を調べる
ステップ1:Spring Bootアプリケーションを生成する
まず、Spring Boot Initialzrを使い、依存関係としてwebだけを指定してSpring Bootアプリケーションを作成しました。

つまり、プロジェクトの直接の依存関係はspring-boot-starter-webだけです。
ステップ2:RESTコントローラーを作成する
次に、考えられる限りシンプルな4行のRESTエンドポイントを書きました。
ステップ3:デプロイ可能なJARをビルドする
このJavaプロジェクトから作成されるJARファイルは、プロジェクトが依存するすべてのJARを含む実行可能な「fat jar」です。Spring Bootはアプリケーションサーバーをアプリケーション本体と一緒に含めるためです。
ステップ4:JARを解析する
次に、作成したSpring BootのJARを読み込むシンプルなアプリケーションを構築しました。JARファイルを展開し、その中に含まれるすべての依存関係も取り出します。JAR内のクラスファイルをすべて逆コンパイルし、コード行数を数えます。
ステップ5:結果を集計する
自分で書いたコードの行数:4
JAR:33個
クラスファイル:9,917個
コード行数:518,772行
数値についての補足
上記の数値は正確とは言えません。空行や、括弧だけの行は除外されているため、最終的な集計には含まれていません。
数値の精度を高めるために、こうした行をさらに分析して除外する必要があるかどうかは議論の余地があります。また、逆コンパイラーによって結果は異なります。
これはどちらかというと疑似科学だと考えています。数値は正確ではありませんが、依存関係がアプリケーションで大きな役割を果たしていることは示せます。それが私の意図でした。
Javaの依存関係を適切に管理する
確かに数値は大きいですが、この例から何がわかるのでしょうか。まず、Hello WorldアプリケーションにSpring Bootを使うのは過剰です。次に、Spring Bootはアプリケーションサーバーなので、この大きな数値も当然ですよね。
どの指摘もそのとおりです。これほど使い道のないRESTエンドポイントはないでしょう。しかし、この例は、本番環境に投入するバイナリの大部分を依存関係が占めているという事実を浮き彫りにしています。Spring Bootは多くのJava開発者が使うフレームワークなので、意図的にこの例に選びました。
考えてみてください。この例で自分が書いたコードは、本番環境に投入するコード全体の1%にも満たないでしょう。それでも、チームとしてそのすべてに責任を負います。アプリケーションに問題が起きれば、開発チームが解決しなければなりません。コードレビュー、ペアプログラミング、自動静的解析などを導入すれば、より良いコードベースの構築に役立ちます。しかし、私たちが利用し、大きく依存している残り99%のコードはどうでしょうか。
依存関係を適切に管理し、適切なタイミングでアップグレードすることは欠かせません。1つのパッケージをインポートすると、多数の依存関係が加わり、攻撃対象となる可能性も増えます。依存関係の選定、更新、削除の方法を定めたJavaの依存関係管理戦略は、すべての開発チームが検討すべきものです。セキュリティの観点からは、依存関係や推移的依存関係に脆弱性が見つかった場合、少なくとも警告を受け取れるようにする必要があります。
Snykでアプリケーションをスキャンし、オープンソースの依存関係にある脆弱性を検出することで、この課題に対処できます。Snykはソフトウェア開発ライフサイクル(SDLC)のあらゆる段階で利用でき、高い適応性を備えているため、自動化にも最適です。Snykは脆弱性を検出するだけでなく、できるだけ早い段階で検出できるよう支援します。
まとめ
コードを適切に管理するだけでは不十分です。依存関係はアプリケーションで大きな役割を果たすため、依存関係にも目を配る必要があります。
Snykのようなツールで依存関係をスキャンすれば、依存関係に潜む脆弱性を見逃さずに済みます。さらに、堅牢なJavaの依存関係管理戦略を導入することは、アプリケーションの保守性、拡張性、予測可能性、そして何よりも安全性を保つうえで欠かせません。
Capture the Flagを始めよう
オンデマンドのバーチャル入門ワークショップを見て、Capture the Flagの課題の解き方を学びましょう。
