Javaプロジェクトで未使用/デッドコードを見つける方法


大規模なJavaプロジェクトで未使用/デッドコードを見つけるためにどのツールを使用しますか? 当社の製品は数年間開発されており、もはや使用されていないコードを手動で検出することは非常に困難になっています。 ただし、できるだけ多くの未使用コードを削除しようとします。

一般的な戦略/テクニック(特定のツール以外)の提案も評価されます。

編集:すでにコードカバレッジツール(Clover、IntelliJ)を使用していますが、これらはほとんど役に立ちません。 デッドコードにはまだユニットテストがあり、カバーされているように表示されます。 私は理想的なツールは、それに応じて他のほとんどコードを持っていないコードのクラスターを識別し、マニュアル検査を行うことができると思います。


Answers



私は、実行中のシステムにコード使用量のログを保存し、その後数ヶ月または数年間使用されていないコードの検査を開始します。

たとえば、未使用のクラスに興味がある場合は、インスタンスの作成時にすべてのクラスにログを記録することができます。 小さなスクリプトは、これらのログをクラスの完全なリストと比較して、未使用のクラスを見つけることができます。

もちろん、メソッドレベルに行く場合は、パフォーマンスを念頭に置いておく必要があります。 たとえば、メソッドは最初の使用のみをログに記録できます。 私はこれがJavaでどのように最善であるか知りません。 私たちはこれを動的言語であるSmalltalkで行い、実行時にコードを変更することができます。 ロギングコールを使用してすべてのメソッドをインストルメントし、メソッドが初めてログに記録された後にロギングコードをアンインストールするので、パフォーマンスペナルティが発生しなくなります。 たぶんJavaで静的なブール値のフラグを使って同様のことを行うことができます...




合理的にうまく動作するEclipseプラグインは、 Unused Code Detectorです。

これは、プロジェクト全体または特定のファイルを処理し、未使用/デッドコードのさまざまな方法を表示するだけでなく、可視性の変更(つまり、保護される可能性のあるパブリックメソッドまたはプライベート)を示します。




CodeProは最近、EclipseプロジェクトでGoogleからリリースされました。 それは無料で非常に効果的です。 プラグインには、1つまたは複数のエントリポイントを持つ「 Find Dead Code 」機能があります。 かなりうまくいく。




私がEclipseで行うことが知られていることは、1つのクラスで、すべてのメソッドを非公開に変更してから、どのような苦情が出るかを確認することです。 使用されているメソッドについては、これによりエラーが発生し、できるだけ低いレベルのアクセスレベルに戻します。 使用されていないメソッドについては、未使用のメソッドに関する警告が表示され、それらは削除されます。 そしてボーナスとして、プライベートにすることができ、プライベートにする必要のあるパブリックメソッドを見つけることがよくあります。

しかし、それは非常にマニュアルです。




私はProGuardがここで言及されていないことに驚いている。 これは、最も成熟した製品の一つです。

ProGuardは、無料のJavaクラスファイル圧縮ツール、オプティマイザ、難読化ツール、および事前検証ツールです。 未使用のクラス、フィールド、メソッド、および属性を検出して削除します。 バイトコードを最適化し、未使用の命令を削除します。 短い無意味な名前を使用して、残りのクラス、フィールド、およびメソッドの名前を変更します。 最後に、Java 6またはJava Micro Editionの処理済みコードを事前に検証します。

ProGuardの用途は次のとおりです。

  • よりコンパクトなコードの作成、より小さなコードアーカイブ、より速いネットワーク間の転送、より高速なローディング、小さなメモリフットプリント。
  • プログラムやライブラリをリバースエンジニアリングすることを難しくしています。
  • デッドコードをリストアップするので、ソースコードから削除することができます。
  • Java 6以上の既存のクラスファイルのターゲットを絞って事前検証し、より高速なクラスロードを最大限に活用します。



テストカバレッジツールを使用してコードベースを計測し、テストではなくアプリケーション自体を実行します。

EmmaEclemmaは、コードの任意の実行に対してどのクラスが実行されているかについての素晴らしいレポートをあなたに伝えます。




私たちは、コードベースのターゲットリッチなリファクタリング環境の中のいくつかのファンクを特定するのに役立つFind Bugsを使い始めました。 また、 構造101では、コードベースのアーキテクチャー内で複雑すぎる場所を特定し、本当の沼地がどこにあるのか知ることができます。




理論的には、未使用のコードを確定的に見つけることはできません。 これは数学的な証明です(これはもっと一般的な定理の特殊なケースです)。 好奇心が強い場合は、Halting Problemを参照してください。

これは、Javaコードでさまざまな形で現れます。

  • ユーザ入力、設定ファイル、データベースエントリなどに基づいてクラスをロードする。
  • 外部コードを読み込む。
  • オブジェクトツリーを第三者図書館に渡す。

つまり、私はIDEA IntelliJを自分のIDEとして使用し、モジュール、未使用メソッド、未使用メンバー、未使用クラスなどの間のfindign依存関係のための広範な分析ツールを使用しています。パブリックメソッドはより広範な分析を必要とする。




Structure101のスライスパースペクティブは、「メイン」クラスタとの依存関係のないクラスまたはパッケージの「孤立した」または「孤立したグループ 」のリスト(および依存関係グラフ)を提供します。




IntelliJには未使用のコードを検出するコード解析ツールがあります。 できるだけ多くのフィールド/メソッド/クラスを非公開にしてください。これは未使用のメソッド/フィールド/クラスをさらに表示します

私はまた、コード量を減らす方法として重複コードを見つけることを試みるでしょう。

私の最後の提案は、もしあなたがコードを簡単にするオープンソースコードを見つけることです。




Eclipseで[Windows]> [設定]> [Java]> [コンパイラ]> [エラー/警告]
それらのすべてをエラーに変更します。 すべてのエラーを修正してください。 これは最も簡単な方法です。 美しさは、これはあなたが書くようにコードをきれいにすることができるということです。

スクリーンショットEclipseコード:




コードをプロファイルし、コードカバレッジデータを提供するツールがあります。 これにより、呼び出されているコードの量(コードが実行されたとき)が表示されます。 これらのツールのどれかを使って、あなたの孤児コードの量を知ることができます。







EMMAなどのユーザーカバレッジツール。 しかし、それは静的ツールではありません(つまり、実際には回帰テストを通じてアプリケーションを実行する必要があります)

それでもEMMAは非常に便利です。




Emma、Cobertura、Cloverなどのコードカバレッジツールは、コードを計測し、一連のテストを実行してコードのどの部分を呼び出すかを記録します。 これは非常に便利で、開発プロセスの不可欠な部分でなければなりません。 テストスイートがコードをどの程度うまくカバーしているかを確認するのに役立ちます。

しかし、これは実際のデッドコードを特定するのと同じではありません。 テストでカバーされる(またはカバーされない)コードだけを識別します。 これにより、偽陽性(テストがすべてのシナリオをカバーしていない場合)および偽陰性(実際のシナリオでは実際に使用されていないコードにアクセスするテスト)が得られます。

デッドコードを実際に識別する最良の方法は、実行中の環境でカバレッジツールを使用してコードをインストルメントし、長時間にわたってコードカバレッジを分析することです。

ロードバランスされた冗長環境で実行している場合(そうでない場合は、なぜですか?)、アプリケーションのインスタンスを1つだけインストルメントし、ロードバランサを構成して、ユーザーは計測されたインスタンス上で実行されます。 これを長時間にわたって行う場合(現実世界の使用シナリオ(季節変動など)をすべて網羅していることを確認するために)、現実世界でどの部分がアクセスされているのか、実際には決してアクセスされず、したがってデッドコードです。

私はこれを個人的に見たことはありませんし、上記のツールをテストスイートを通して呼び出されていないコードを計測し分析するためにどのように使用できるのか分かりませんが、確信しています。




  • FindBugsはこのようなことに優れています。
  • PMD(Project Mess Detector)は、使用可能な別のツールです。

しかし、どちらもワークスペースで使用されていないパブリック静的メソッドを見つけることはできません。 そのようなツールを知っている人は、私に知らせてください。







Eclipseは、到達できないコードを表示/強調表示できます。 JUnitはコードカバレッジを表示できますが、いくつかのテストが必要であり、関連するテストが欠落しているかコードが実際に使用されていないかを判断する必要があります。




私はCloverカバレッジツールを見つけました。このツールは、使用されているコードと使用されていないコードを強調表示します。 Google CodePro Analyticsとは異なり、Webアプリケーションでも動作します(私の経験によれば、私はGoogle CodeProについて間違いかもしれません)。

私が気づいた唯一の欠点は、Javaインターフェイスを考慮しないことです。




Javaプロジェクト、 Dead Code Detector (DCD)があります。 ソースコードについてはうまく動作していないようですが、.jarファイルでは本当にうまいです。 さらに、クラスごと、および方法ごとにフィルタリングすることができます。




私はDoxygenを使用して、決して呼び出されないメソッドを見つけるメソッド呼び出しマップを開発します。 グラフには、呼び出し元のないメソッドクラスの島があります。 これはライブラリのためには動作しません。なぜなら、いつもメインエントリポイントから始める必要があるからです。