So finden Sie unbenutzten / toten Code in Java-Projekten [geschlossen]


306

Mit welchen Tools finden Sie unbenutzten / toten Code in großen Java-Projekten? Unser Produkt befindet sich seit einigen Jahren in der Entwicklung und es wird sehr schwierig, nicht mehr verwendeten Code manuell zu erkennen. Wir versuchen jedoch, so viel unbenutzten Code wie möglich zu löschen.

Vorschläge für allgemeine Strategien / Techniken (außer spezifischen Werkzeugen) werden ebenfalls geschätzt.

Bearbeiten: Beachten Sie, dass wir bereits Tools zur Codeabdeckung (Clover, IntelliJ) verwenden, diese jedoch wenig hilfreich sind. Toter Code hat noch Unit-Tests und wird als abgedeckt angezeigt. Ich denke, ein ideales Tool würde Codecluster identifizieren, von denen nur sehr wenig anderer Code abhängt, was eine manuelle Überprüfung der Dokumente ermöglicht.


16
Bewahren Sie die Komponententests in einem separaten Quellbaum auf (sollten Sie es trotzdem tun) und führen Sie die Coverage-Tools nur im Live-Baum aus.
2.

5
Ich würde mit IDEA Anfang „nicht verwendet Erklärung“ Inspektion und deaktivieren Testquellen umfassen . Können Sie klarstellen, was Sie meinen, wenn Sie IDEAs "wenig Hilfe" sagen?
David Moles

1
Möglichkeiten, toten Code zu finden: 1) durch nichts außerhalb verbunden. 2) wurde nicht von außen verwendet, obwohl es zur Laufzeit verknüpft ist. 3) Verknüpft und aufgerufen, aber nie wie eine tote Variable verwendet. 4) logisch nicht erreichbarer Zustand. Also verknüpfen, im Laufe der Zeit zugreifen, logikbasiert, nach dem Zugriff verwenden.
Muhammad Umer

Verwenden Sie IntelliJ Idea und meine Antwort von hier: stackoverflow.com/questions/22522013/… :)
BlondCode

Ergänzung zu David Moles
Benj

Antworten:


40

Ich würde das laufende System instrumentieren, um Protokolle der Codeverwendung zu führen, und dann damit beginnen, Code zu überprüfen, der seit Monaten oder Jahren nicht mehr verwendet wird.

Wenn Sie beispielsweise an nicht verwendeten Klassen interessiert sind, können alle Klassen instrumentiert werden, um beim Erstellen von Instanzen zu protokollieren. Und dann könnte ein kleines Skript diese Protokolle mit der vollständigen Liste der Klassen vergleichen, um nicht verwendete Klassen zu finden.

Wenn Sie sich für die Methodenebene entscheiden, sollten Sie natürlich die Leistung im Auge behalten. Beispielsweise konnten die Methoden nur ihre erste Verwendung protokollieren. Ich weiß nicht, wie das am besten in Java gemacht wird. Wir haben dies in Smalltalk getan, einer dynamischen Sprache, die zur Laufzeit Codeänderungen ermöglicht. Wir instrumentieren alle Methoden mit einem Protokollierungsaufruf und deinstallieren den Protokollierungscode, nachdem eine Methode zum ersten Mal protokolliert wurde, sodass nach einiger Zeit keine Leistungseinbußen mehr auftreten. Vielleicht kann etwas Ähnliches in Java mit statischen booleschen Flags gemacht werden ...


5
Ich mag diese Antwort, aber hat jemand eine Idee, wie man dies in Java macht, ohne die Protokollierung in jeder Klasse explizit hinzuzufügen? Vielleicht etwas 'Proxy'-Magie?
Outlaw Programmer

14
@Outlaw AOP scheint hierfür ein perfekter Anwendungsfall zu sein.
Pascal Thivent

6
Wenn Sie die Klassenladestruktur der Anwendung verstehen, können Sie AOP auf dem Klassenladeprogramm verwenden, um Klassenladeereignisse zu verfolgen. Dies wäre für ein Produktionssystem weniger invasiv als die Beratung aller Konstrukteure.
ShabbyDoo

5
Diese Antwort ist ziemlich gut für eine dynamische Sprache, aber schrecklich für eine statische Sprache, die VIEL besser sein könnte. Mit einer statisch typisierten Sprache (abgesehen von der Reflexion) können Sie genau wissen, welche Methoden verwendet werden und welche nicht. Dies ist einer der größten Vorteile einer statisch typisierten Sprache, und Sie sollten sie anstelle der hier beschriebenen fehlbaren Methode verwenden .
Bill K

4
@ BillK mehr Reflexion passiert als Sie denken. ZB macht der Frühling unter der Decke einiges an Magie, einschließlich Reflexion. Ihr Analysetool muss dies emulieren.
Thorbjørn Ravn Andersen

220

Ein Eclipse-Plugin, das recht gut funktioniert, ist Unused Code Detector .

Es verarbeitet ein gesamtes Projekt oder eine bestimmte Datei und zeigt verschiedene nicht verwendete / tote Codemethoden sowie Vorschläge für Änderungen der Sichtbarkeit (dh eine öffentliche Methode, die geschützt oder privat sein könnte).


Sieht gut aus, aber ich konnte es nicht zum Laufen bringen - die Aktion "Un ... Code erkennen" ist deaktiviert und ich habe keine Möglichkeit gefunden, sie zu aktivieren.
Ondra Žižka

1
Finden Sie in der Tat nicht verwendete Methoden, ABER auch, dass meine EJBs nicht verwendet werden (während sie es sind), weil ich ein
Musterdesign für

Funktioniert es immer noch mit Kepler? Veröffentlichungen sagen über Eclipse 3.8: ucdetector.org/releases.html
Mr_and_Mrs_D

Scheint bei Kepler in einwandfreiem Zustand zu sein.
Erik Kaplun

4
Möchten Sie einen Link zum Marktplatz marketplatz.eclipse.org/content/unnecessary-code-detector hinzufügen ? Dies erleichtert die Installation und beantwortet die Frage, ob es in neueren Versionen von Eclipse unterstützt wird.
Thomas Weller

64

CodePro wurde kürzlich von Google mit dem Eclipse-Projekt veröffentlicht. Es ist kostenlos und sehr effektiv. Das Plugin verfügt über eine Funktion " Find Dead Code " mit einem / mehreren Einstiegspunkten. Funktioniert ziemlich gut.


1
Funktioniert nicht mehr mit Eclipse Kepler. Nach der erfolgreichen Installation über die Update-Site stürzt Eclipse jedes Mal ab.
Txulu

Leider sieht es so aus, als ob dieses Tool die Existenz von Spring nicht erkennt. Daher markiert es alle meine @Components als unbenutzt, falsch
Clint Eastwood

Sehr alt werden Funktioniert nicht mehr Last updated this plugin March 27, 2012 Entwickler.google.com/java-dev-tools/download-codepro
mumair

2
Alle Links sind veraltet.
Zygimantus

3
Leider scheint Google den Code im Eclipse-Projekt abgelegt und alles vergessen zu haben.
Thorbjørn Ravn Andersen

30

Ich bin überrascht, dass ProGuard hier nicht erwähnt wurde. Es ist eines der ausgereiftesten Produkte überhaupt.

ProGuard ist ein kostenloser Dateischrinker, Optimierer, Verschleierer und Vorverstärker der Java-Klasse. Nicht erkannte Klassen, Felder, Methoden und Attribute werden erkannt und entfernt. Es optimiert den Bytecode und entfernt nicht verwendete Anweisungen. Die verbleibenden Klassen, Felder und Methoden werden mit kurzen, bedeutungslosen Namen umbenannt. Schließlich wird der verarbeitete Code für Java 6 oder für Java Micro Edition vorab überprüft.

Einige Anwendungen von ProGuard sind:

  • Erstellen von kompakterem Code für kleinere Codearchive, schnellere Übertragung über Netzwerke, schnelleres Laden und geringeren Speicherbedarf.
  • Das Reverse Engineering von Programmen und Bibliotheken wird erschwert.
  • Auflisten von totem Code, damit dieser aus dem Quellcode entfernt werden kann.
  • Retargeting und Preverifizierung vorhandener Klassendateien für Java 6 oder höher, um das schnellere Laden von Klassen voll auszunutzen.

Hier ein Beispiel für die Liste des toten Codes: https://www.guardsquare.com/de/products/proguard/manual/examples#deadcode


8
Die Bereitstellung einer Beispielnutzung wäre eine bessere Antwort.
rds

1
Wenn ich die Dokumentation lese, sehe ich, dass nicht verwendeter Code verkleinert wird, aber ich kann nirgendwo finden, wo er aufgelistet ist - vereinbart, ein Beispiel oder ein Link zum entsprechenden Abschnitt der Dokumentation wäre sehr hilfreich!
Orbfish

26

Eine Sache, die ich in Eclipse für eine einzelne Klasse gemacht habe, ist, alle Methoden auf privat zu ändern und dann zu sehen, welche Beschwerden ich bekomme. Bei den verwendeten Methoden führt dies zu Fehlern, und ich stelle sie auf die niedrigste Zugriffsebene zurück, die ich kann. Bei nicht verwendeten Methoden werden Warnungen vor nicht verwendeten Methoden ausgelöst, die dann gelöscht werden können. Und als Bonus finden Sie oft einige öffentliche Methoden, die privat gemacht werden können und sollten.

Aber es ist sehr manuell.


4
Vielleicht nicht die ideale Antwort, aber das ist wirklich klug.
Erik Reppen

8
Das ist klug ... bis Sie einen Aufruf von einem nicht verwendeten Code einer anderen Klasse erhalten.
Danosaure

Durch Iterieren über diese Methode können große Codeschwaden entfernt werden, wenn eine verwendete Methode andere erstellt, sobald sie entfernt wird.
4myle

15

Verwenden Sie ein Testabdeckungstool, um Ihre Codebasis zu instrumentieren, und führen Sie dann die Anwendung selbst aus, nicht die Tests.

Emma und Eclemma geben Ihnen nette Berichte darüber, wie viel Prozent der Klassen für eine bestimmte Ausführung des Codes ausgeführt werden.


1
+1 ist ein guter Ausgangspunkt, aber denken Sie daran, dass z. B. nicht verwendete (noch deklarierte) Variablen ebenfalls grün angezeigt werden.
DerMike

13

Wir haben begonnen, Find Bugs zu verwenden, um einen Teil des Funk in der zielreichen Umgebung unserer Codebasis für Refactorings zu identifizieren. Ich würde auch Struktur 101 in Betracht ziehen , um zu komplizierte Stellen in der Architektur Ihrer Codebasis zu identifizieren, damit Sie wissen, wo sich die echten Sümpfe befinden.


4
FindBugs kann keinen toten und nicht verwendeten Code erkennen, sondern nur nicht verwendete Felder. Siehe diese Antwort .
Stefan Mücke

12

Theoretisch können Sie nicht verwendeten Code nicht deterministisch finden. Es gibt einen mathematischen Beweis dafür (nun, dies ist ein Sonderfall eines allgemeineren Satzes). Wenn Sie neugierig sind, schlagen Sie das Halteproblem nach.

Dies kann sich in Java-Code auf viele Arten manifestieren:

  • Laden von Klassen basierend auf Benutzereingaben, Konfigurationsdateien, Datenbankeinträgen usw.;
  • Laden von externem Code;
  • Übergeben von Objektbäumen an Bibliotheken von Drittanbietern;
  • usw.

Davon abgesehen verwende ich IDEA IntelliJ als IDE meiner Wahl und es verfügt über umfangreiche Analysewerkzeuge, um Abhängigkeiten zwischen Modulen, nicht verwendeten Methoden, nicht verwendeten Mitgliedern, nicht verwendeten Klassen usw. zu finden. Es ist auch ziemlich intelligent wie eine private Methode, die nicht aufgerufen wird Nicht verwendet, aber eine öffentliche Methode erfordert eine umfassendere Analyse.


1
Danke für deinen Beitrag. Wir verwenden IntelliJ und bekommen dort Hilfe. Was das Halteproblem und die Unentscheidbarkeit betrifft, bin ich mit der Theorie vertraut, aber wir brauchen nicht unbedingt eine deterministische Lösung.
Knatten

12
Der Eröffnungssatz ist zu stark. Wie beim Halteproblem (auch oft falsch zitiert / missbraucht) gibt es keine vollständigen allgemeinen Lösungen, aber es gibt viele Sonderfälle, die erkannt werden können.
joel.neely

9
Während es keine allgemeine Lösung für Sprachen mit Auswertung und / oder Reflexion gibt, gibt es viele Fälle, in denen Code nachweislich nicht erreichbar ist.
pjc50

1
Ohne Reflexion und mit vollständigem Quellcode sollte jede statisch typisierte Sprache es ziemlich einfach machen, den gesamten nicht verwendeten Code deterministisch zu finden.
Bill K

Sie können nicht feststellen, dass dies durch Reflexion oder durch externe Anrufer nicht erreichbar ist, aber Sie können Code finden, der von einem bestimmten Einstiegspunkt oder einer Reihe von Einstiegspunkten aus statisch nicht erreichbar ist
nafg

8

Gehen Sie in Eclipse zu Windows> Einstellungen> Java> Compiler> Fehler / Warnungen
und ändern Sie alle in Fehler. Beheben Sie alle Fehler. Dies ist der einfachste Weg. Das Schöne ist, dass Sie so den Code beim Schreiben bereinigen können.

Screenshot Eclipse Code:

Geben Sie hier die Bildbeschreibung ein


5

IntelliJ verfügt über Code-Analyse-Tools zum Erkennen von nicht verwendetem Code. Sie sollten versuchen, so viele Felder / Methoden / Klassen wie möglich nicht öffentlich zu machen. Dadurch werden mehr nicht verwendete Methoden / Felder / Klassen angezeigt

Ich würde auch versuchen, doppelten Code zu finden, um das Codevolumen zu reduzieren.

Mein letzter Vorschlag ist, Open Source Code zu finden, der bei Verwendung Ihren Code einfacher macht.


Gibt es Beispiele für diese Tools?
Orbfish

@orbfish Sie können laufen Analyse=> Run inspection by name=>unused
Peter Lawrey

5

Die Structure101 slice Perspektive gibt eine Liste (und Abhängigkeitsgraph) eine „Waisen“ oder „orphan Gruppen “ von Klassen oder Paketen , die keine Abhängigkeiten zu oder von der „Haupt“ Cluster haben.


Funktioniert dies beispielsweise für Variablen / Methoden innerhalb einer Klasse?
Joeblackdev

Woher weiß ich, ob dies mit z. B. Eclipse 4.3 funktionieren soll?
Erik Kaplun

3

DCD ist kein Plugin für eine IDE, kann aber von ant oder Standalone ausgeführt werden. Es sieht aus wie ein statisches Tool und kann das tun, was PMD und FindBugs nicht können . Ich werde es versuchen.

PS Wie in einem Kommentar unten erwähnt, lebt das Projekt jetzt in GitHub .


Dies sollte als Kommentar nicht beantwortet werden
Count

Bitte aktualisieren Sie Ihre Antwort, um Ihre Aussage zu entfernen, dass DCD "jetzt tot aussieht". Version 2.1 wurde vor 12 Tagen veröffentlicht . Außerdem funktioniert der Link in Ihrer Antwort nicht.
Skomisa

2

Es gibt Tools, die Code codieren und Daten zur Codeabdeckung bereitstellen. Auf diese Weise können Sie sehen (während der Code ausgeführt wird), wie viel davon aufgerufen wird. Mit jedem dieser Tools können Sie herausfinden, wie viel verwaisten Code Sie haben.


2
  • FindBugs eignet sich hervorragend für solche Dinge.
  • PMD (Project Mess Detector) ist ein weiteres Tool, das verwendet werden kann.

Es können jedoch keine öffentlichen statischen Methoden gefunden werden , die in einem Arbeitsbereich nicht verwendet werden. Wenn jemand von einem solchen Tool weiß, lassen Sie es mich bitte wissen.


1

Tools zur Benutzerabdeckung wie EMMA. Aber es ist kein statisches Tool (dh es muss die Anwendung tatsächlich durch Regressionstests und durch alle möglichen Fehlerfälle ausgeführt werden, was durchaus unmöglich ist :))

Dennoch ist EMMA sehr nützlich.


1

Tools zur Codeabdeckung wie Emma, ​​Cobertura und Clover instrumentieren Ihren Code und zeichnen auf, welche Teile davon durch Ausführen einer Reihe von Tests aufgerufen werden. Dies ist sehr nützlich und sollte ein wesentlicher Bestandteil Ihres Entwicklungsprozesses sein. Mithilfe dieser Funktion können Sie feststellen, wie gut Ihre Testsuite Ihren Code abdeckt.

Dies ist jedoch nicht dasselbe wie das Identifizieren von echtem toten Code. Es wird nur Code identifiziert, der von Tests abgedeckt (oder nicht abgedeckt) wird. Dies kann zu falsch positiven Ergebnissen führen (wenn Ihre Tests nicht alle Szenarien abdecken) sowie zu falsch negativen Ergebnissen (wenn Ihre Tests auf Code zugreifen, der in einem realen Szenario tatsächlich nie verwendet wird).

Ich kann mir vorstellen, dass der beste Weg, um toten Code wirklich zu identifizieren, darin besteht, Ihren Code mit einem Coverage-Tool in einer Live-Laufumgebung zu instrumentieren und die Codeabdeckung über einen längeren Zeitraum zu analysieren.

Wenn Sie in einer redundanten Umgebung mit Lastenausgleich arbeiten (und wenn nicht, warum nicht?), Ist es wahrscheinlich sinnvoll, nur eine Instanz Ihrer Anwendung zu instrumentieren und Ihren Lastenausgleich so zu konfigurieren, dass ein zufälliger, aber kleiner Teil von Ihre Benutzer werden auf Ihrer instrumentierten Instanz ausgeführt. Wenn Sie dies über einen längeren Zeitraum tun (um sicherzustellen, dass Sie alle realen Nutzungsszenarien - solche saisonalen Schwankungen - abgedeckt haben), sollten Sie genau sehen können, auf welche Bereiche Ihres Codes unter realer Nutzung und auf welche Teile zugegriffen wird werden wirklich nie zugegriffen und daher toter Code.

Ich habe dies noch nie persönlich gesehen und weiß nicht, wie die oben genannten Tools verwendet werden können, um Code zu instrumentieren und zu analysieren, der nicht über eine Testsuite aufgerufen wird - aber ich bin mir sicher, dass dies möglich ist.


1

Es gibt ein Java-Projekt - Dead Code Detector (DCD). Für den Quellcode scheint es nicht gut zu funktionieren, aber für die JAR-Datei ist es wirklich gut. Außerdem können Sie nach Klasse und Methode filtern.



0

Eclipse kann nicht erreichbaren Code anzeigen / hervorheben. JUnit kann Ihnen die Codeabdeckung anzeigen, aber Sie benötigen einige Tests und müssen entscheiden, ob der entsprechende Test fehlt oder der Code wirklich nicht verwendet wird.


3
Eclipse teilt Ihnen nur mit, ob der Umfang der Methode lokal (dh privat) ist. und selbst dann kann man nicht 100% sicher sein ... mit reflexion könnte eine private methode von außen aufgerufen werden.
p3t0r

0

Ich habe ein Clover-Coverage-Tool gefunden, das den Code instrumentiert und den verwendeten und nicht verwendeten Code hervorhebt. Im Gegensatz zu Google CodePro Analytics funktioniert es auch für WebApplications (meiner Erfahrung nach kann es sein, dass ich bei Google CodePro falsch liege).

Der einzige Nachteil, den ich bemerkt habe, ist, dass Java-Schnittstellen nicht berücksichtigt werden.


Afaict, es ist ein nicht freies serverseitiges CI-Tool.
Erik Kaplun

0

Ich verwende Doxygen, um eine Methodenaufrufzuordnung zu entwickeln, um Methoden zu finden, die niemals aufgerufen werden. In der Grafik finden Sie Inseln von Methodenclustern ohne Aufrufer. Dies funktioniert bei Bibliotheken nicht, da Sie immer an einem Haupteinstiegspunkt beginnen müssen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.