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


306

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

一般的な戦略/手法(特定のツール以外)の提案も歓迎されます。

編集:すでにコードカバレッジツール(Clover、IntelliJ)を使用していますが、これらはほとんど役に立ちません。デッドコードにはまだユニットテストがあり、カバーされているように見えます。理想的なツールは、コードに依存する他のコードがほとんどないコードのクラスターを識別し、ドキュメントを手動で検査できると思います。


16
単体テストを別のソースツリーに保存し(とにかく必要があります)、カバレッジツールはライブツリーでのみ実行します。
2008年

5
IDEAの「未使用の宣言」の検査から始め、テストソースを含める」のチェックを外します。IDEAが「ほとんど役に立たない」と言ったときの意味を明確にできますか?
David Moles

1
死んだコードを見つける方法:1)外部からリンクされていない。2)ランタイムでリンクされているにもかかわらず、外部から使用されていない。3)リンク&呼び出されますが、デッド変数のようには使用されません。4)論理的に到達できない状態。したがって、リンク、時間の経過に伴うアクセス、ロジックベース、アクセス後の使用。
Muhammad Umer

ここからIntelliJのアイデアと私の答えを使用してください:stackoverflow.com/questions/22522013/… :)
BlondCode

David Moleの回答への追加:この回答を参照してくださいstackoverflow.com/a/6587932/1579667
Benj

回答:


40

コードの使用状況のログを保持するように実行中のシステムを計測し、数か月または数年使用されていないコードの検査を開始します。

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

もちろん、メソッドレベルで実行する場合は、パフォーマンスに留意する必要があります。たとえば、メソッドは最初の使用のみをログに記録できます。これがJavaでどのように最適に行われるかはわかりません。これは、Smalltalkで行いました。これは動的言語であり、実行時にコードを変更できるようにします。すべてのメソッドをログ呼び出しで計測し、メソッドが初めてログに記録された後でログコードをアンインストールするため、しばらくするとパフォーマンスが低下することはありません。静的なブールフラグを使用してJavaで同様のことができるかもしれません...


5
私はこの答えが好きですが、すべてのクラスにログを明示的に追加せずにJavaでこれを行う方法を誰かが知っていますか?たぶんいくつかの「プロキシ」魔法?
アウトロープログラマ、

14
@Outlaw AOPはこのための完璧なユースケースのようです。
Pascal Thivent 2009年

6
アプリケーションのクラスローディング構造を理解していれば、クラスローダーでAOPを使用してクラスロードイベントを追跡できます。これは、すべてのコンストラクタの前のアドバイスよりも、運用システムへの影響が少ないでしょう。
ShabbyDoo 2010

5
この答えは、動的言語にはかなり良いですが、はるかにうまくできる静的言語にはひどいものです。静的型付け言語(リフレクションを除く)を使用すると、どのメソッドが使用され、どのメソッドが使用されないかを確実に知ることができます。これは、静的型付け言語の最大の利点の1つであり、ここで説明するような誤ったメソッドではなく、それを使用する必要があります。 。
ビルK

4
@BillKあなたが思っているよりも多くの反射が起こります。たとえば、Springは、反射を含め、内部でかなりの魔法をかけます。分析ツールはそれをエミュレートする必要があります。
–ThorbjørnRavn Andersen 2016

220

適度に機能するEclipseプラグインは、未使用コード検出機能です。

プロジェクト全体または特定のファイルを処理し、さまざまな未使用/デッドコードメソッドを示し、可視性の変更を提案します(つまり、保護またはプライベートにすることができるパブリックメソッド)。


見栄えはいいのですが、動作させることができませんでした。「コードを検出...」アクションが無効になっていて、有効にする方法が見つかりませんでした。
OndraŽižka11年

1
実際に使用されていない方法を見つけること、しかし、また、私はビジネスデリゲートパターンのデザインを使用していますので、(彼らはしている間)私のEJBが未使用されていることを見つけてください
Eildosa

それはまだケプラーで動作しますか?リリースはeclipse 3.8について言う:ucdetector.org/releases.html
Mr_and_Mrs_D

ケプラーで完璧な作業状態にあるようです。
エリックカプルン2014年

4
marketplace marketplace.eclipse.org/content/unnecessary-code-detectorへのリンクを追加しますか?これにより、インストールが簡単になり、新しいバージョンのEclipseでサポートされているかどうかの質問に答えます。
Thomas Weller

64

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


1
日食ケプラーではもう動作しません。更新サイトから正常にインストールした後、毎回Eclipseがクラッシュします。
txulu 2014年

残念ながら、このツールはSpringの存在を認識していないようです。そのため、すべての@Componentsが誤って未使用としてマークされます
Clint Eastwood

非常に古くなるもはや機能しないLast updated this plugin March 27, 2012 developer.google.com/java-dev-tools/download-codepro
mumair

2
すべてのリンクが古くなっています。
zygimantus

3
残念ながら、GoogleはEclipseプロジェクトにコードをダンプし、そのすべてを忘れているようです。
するThorbjörnRavnアンデルセン

30

私は驚いていProGuardのが、ここで言及されていません。これは、最も成熟した製品の1つです。

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

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

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

デッドコードのリストの例:https : //www.guardsquare.com/en/products/proguard/manual/examples#deadcode


8
サンプルの使用法を提供すると、より適切な回答が得られます。
RDS

1
ドキュメントを読むと、未使用のコードが縮小されていることがわかりますが、それがリストされている場所はどこにもありません。同意、例、またはドキュメントの関連セクションへのリンクが非常に役立ちます。
orbfish 2017年

26

私がEclipseの単一のクラスで行うことで知られていることの1つは、すべてのメソッドをプライベートに変更してから、どのようなクレームが発生するかを確認することです。使用されているメソッドの場合、これはエラーを引き起こし、できる限り低いアクセスレベルに戻します。未使用のメソッドの場合、これは未使用のメソッドに関する警告を引き起こし、それらは削除できます。そしておまけとして、非公開にすることができ、非公開にする必要があるいくつかの公開メソッドを見つけることがよくあります。

しかし、それは非常に手動です。


4
多分理想的な答えではないかもしれませんが、それは本当に賢いです。
Erik Reppen 2013

8
これは賢い...別のクラスからの未使用のコードからの呼び出しがあるまで。
Danosaure 2013

このメソッドを反復すると、使用されている1つのメソッドが削除されると他のメソッドが作成されるため、コードの膨大な部分を削除できます。
4myle 2017年

15

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

EmmaEclemmaは、コードの特定の実行に対してどのクラスの何パーセントが実行されているかについての素晴らしいレポートを提供します。


1
+1は良い出発点ですが、たとえば未使用の(まだ宣言されていない)変数も緑色で表示されることに注意してください。
DerMike

13

Find Bugsを使用して、コードベースのターゲットが豊富なリファクタリング環境のファンクを特定できるようになりました。また、Structure 101を検討して、コードベースのアーキテクチャで複雑すぎるスポットを特定し、実際の沼地がどこにあるかを確認します。


4
FindBugsは、使用されていないコードのみを検出できません。使用されていないフィールドのみです。この回答を参照してください。
StefanMücke2012

12

理論的には、未使用のコードを確定的に見つけることはできません。これの数学的証明があります(まあ、これはより一般的な定理の特殊なケースです)。興味があれば、停止問題を調べてください。

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

  • ユーザー入力、構成ファイル、データベースエントリなどに基づいてクラスをロードする。
  • 外部コードの読み込み;
  • オブジェクトツリーをサードパーティのライブラリに渡す。

そうは言っても、私はIDEAとしてIDEA IntelliJを使用しており、モジュール、未使用のメソッド、未使用のメンバー、未使用のクラスなどの依存関係を見つけるための広範な分析ツールを備えています。呼び出されないプライベートメソッドのように非常にインテリジェントです。タグ付けされた未使用ですが、パブリックメソッドはより広範な分析を必要とします。


1
ご意見ありがとうございます。IntelliJを使用しており、そこでいくつかの助けを得ています。停止問題と決定不可能性については、私は理論に精通していますが、必ずしも決定論的な解決策は必要ありません。
knatten 2008年

12
冒頭の文が強すぎます。停止問題(しばしば誤って引用/乱用される)の場合と同様に、完全な一般的な解決策はありませんが、検出が可能な多くの特別なケースがあります。
joel.neely 2009

9
evalやリフレクションを使用する言語の一般的な解決策はありませんが、コードにアクセスできない可能性がある場合が多くあります。
pjc50 2009

1
リフレクションを使用せず、完全なソースコードを使用すると、静的に型付けされた言語を使用すると、未使用のすべてのコードを確定的に見つけることが非常に簡単になります。
ビルK

リフレクションや外部の呼び出し元では到達できないと証明できないが、特定のエントリポイントまたは一連のエントリポイントから静的に到達できないと証明できるコードを見つけることができる
nafg

8

Eclipse Goto Windows> Preferences> Java> Compiler> Errors / Warningsで
、すべてをエラーに変更します。すべてのエラーを修正します。これが最も簡単な方法です。美しさは、これにより、作成時にコードをクリーンアップできることです。

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

ここに画像の説明を入力してください


5

IntelliJには、未使用のコードを検出するためのコード分析ツールがあります。あなたはできるだけ多くのフィールド/メソッド/クラスを非公開にすることを試みるべきです、そしてそれはより多くの未使用のメソッド/フィールド/クラスを表示します

また、コードの量を減らす方法として、重複するコードを見つけようとしました。

私の最後の提案は、オープンソースコードを見つけることです。これを使用すると、コードが単純になります。


これらのツールの例はありますか?
orbfish 2017年

@orbfish実行できますAnalyse=> Run inspection by name=>unused
Peter Lawrey

5

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


これはクラス内のインスタンス変数/メソッドで機能しますか?
Joeblackdev

これがEclipse 4.3などで動作するはずであるかどうかはどうすればわかりますか?
エリックカプルン2014年

3

DCDは一部のIDEのプラグインではありませんが、antまたはスタンドアロンから実行できます。静的なツールのように見え、PMDやFindBugsではできないことを実行できます。。やってみます。

PS以下のコメントで述べたように、プロジェクトは現在GitHubにあります


これは、コメントではなく回答として下がるはずです。
カウント

回答を更新して、DCDが「今は死んでいるように見える」というステートメントを削除してください。バージョン2.1は12日前にリリースされました。また、回答のリンクが機能しません。
skomisa 2018年

2

コードをプロファイルし、コードカバレッジデータを提供するツールがあります。これにより、(コードの実行時に)どれだけのコードが呼び出されているかを確認できます。これらのツールのいずれかを入手して、孤立したコードの量を調べることができます。


2
  • FindBugsは、この種のものに最適です。
  • PMD(Project Mess Detector)は、使用できる別のツールです。

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


1

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

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


1

Emma、Cobertura、Cloverなどのコードカバレッジツールは、コードをインストルメント化し、一連のテストを実行することによって呼び出されるコードの部分を記録します。これは非常に便利で、開発プロセスに不可欠な部分です。これは、テストスイートがコードをどの程度カバーしているかを特定するのに役立ちます。

ただし、これは実際のデッドコードを識別することとは異なります。テストでカバーされる(またはカバーされない)コードのみを識別します。これにより、偽陽性(テストがすべてのシナリオをカバーしない場合)と偽陰性(実際のシナリオで実際に使用されないコードにテストがアクセスする場合)が発生する可能性があります。

死んだコードを本当に特定する最善の方法は、ライブ実行環境でカバレッジツールを使用してコードを計測し、長期間にわたってコードカバレッジを分析することだと思います。

負荷分散された冗長環境で実行している場合(そうでない場合は、なぜそうでないのでしょうか?)、アプリケーションのインスタンスを1つだけインスツルメントし、ロードバランサーをランダムで小さいユーザーはインストルメント化されたインスタンスで実行されます。これを長期間にわたって行うと(実際の使用シナリオ(季節変動など)をすべてカバーしていることを確認するため)、実際の使用状況でアクセスされているコードの領域と部分を正確に確認できるはずです。実際にはアクセスされないため、デッドコードになります。

私はこれが個人的に行われたのを見たことがないので、前述のツールを使用して、テストスイートから呼び出されていないコードを計測および分析する方法を知りませんが、そうであると確信しています。


1

Javaプロジェクト-Dead Code Detector(DCD)があります。ソースコードの場合はうまく機能しないようですが、.jarファイルの場合は非常に優れています。さらに、クラスおよびメソッドでフィルタリングできます。



0

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


3
Eclipseは、メソッドのスコープがローカル(つまり、プライベート)である場合にのみ通知します。それでも100%確実ではありません...リフレクションを使用すると、外部からプライベートメソッドを呼び出すことができます。
p3t0r 2008年

0

コードを計測し、使用されているコードと未使用のコードを強調表示するCloverカバレッジツールを見つけました。Google CodePro Analyticsとは異なり、これはWebApplicationsでも機能します(私の経験によると、Google CodeProについては正しくない可能性があります)。

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


Afaict、それはフリーではないサーバー側のCIツールです。
エリックカプルン2014年

0

私はDoxygenを使用して、呼び出されないメソッドを見つけるメソッド呼び出しマップを開発しました。グラフには、呼び出し元のないメソッドクラスタのアイランドが表示されます。常にいくつかのメインエントリポイントから開始する必要があるため、これはライブラリでは機能しません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.