Comment trouver le code inutilisé / mort dans les projets java [fermé]

306

Quels outils utilisez-vous pour trouver le code inutilisé / mort dans les grands projets Java? Notre produit est en développement depuis quelques années et il devient très difficile de détecter manuellement le code qui n'est plus utilisé. Nous essayons cependant de supprimer autant de code inutilisé que possible.

Des suggestions de stratégies / techniques générales (autres que des outils spécifiques) sont également appréciées.

Edit: Notez que nous utilisons déjà des outils de couverture de code (Clover, IntelliJ), mais ceux-ci sont peu utiles. Le code mort a toujours des tests unitaires et apparaît comme couvert. Je suppose qu'un outil idéal identifierait des grappes de code qui ont très peu de code en fonction, permettant une inspection manuelle des documents.

tricoté
la source
16
Conservez les tests unitaires dans une arborescence source distincte (vous devriez quand même le faire) et exécutez les outils de couverture uniquement sur l'arborescence en direct.
agnul
5
Je commencerais par l' inspection «Déclaration inutilisée» d'IDEA et décochez Inclure les sources de test . Pouvez-vous clarifier ce que vous voulez dire lorsque vous dites «peu d'aide» d'IDEA?
David Moles
1
Façons de trouver le code mort: 1) pas lié par quoi que ce soit à l'extérieur. 2) n'a pas été utilisé de l'extérieur même s'il est lié lors de l'exécution. 3) Linked & Called mais jamais utilisé comme variable morte. 4) état logiquement inaccessible. Donc, relier, accéder au fil du temps, basé sur la logique, utiliser après avoir accédé.
Muhammad Umer
Utilisez IntelliJ Idea et ma réponse d'ici: stackoverflow.com/questions/22522013/… :)
BlondCode
Ajout à la réponse de David Mole: voir cette réponse stackoverflow.com/a/6587932/1579667
Benj

Réponses:

40

J'instrumenterais le système en cours d'exécution pour conserver des journaux d'utilisation du code, puis commencerais à inspecter le code qui n'est pas utilisé pendant des mois ou des années.

Par exemple, si vous êtes intéressé par les classes inutilisées, toutes les classes peuvent être instrumentées pour se connecter lorsque des instances sont créées. Et puis un petit script pourrait comparer ces journaux avec la liste complète des classes pour trouver les classes inutilisées.

Bien sûr, si vous allez au niveau de la méthode, vous devez garder à l'esprit les performances. Par exemple, les méthodes n'ont pu enregistrer que leur première utilisation. Je ne sais pas comment cela se fait au mieux en Java. Nous l'avons fait dans Smalltalk, qui est un langage dynamique et permet donc de modifier le code lors de l'exécution. Nous instrumentons toutes les méthodes avec un appel de journalisation et désinstallons le code de journalisation une fois qu'une méthode a été journalisée pour la première fois, donc après un certain temps, il n'y a plus de pénalités de performances. Peut-être qu'une chose similaire peut être faite en Java avec des drapeaux booléens statiques ...

akuhn
la source
5
J'aime cette réponse, mais quelqu'un a-t-il une idée de comment faire cela en Java sans ajouter explicitement la journalisation dans chaque classe? Peut-être un peu de magie «proxy»?
Programmeur hors
14
@Outlaw AOP semble être un cas d'utilisation parfait pour cela.
Pascal Thivent
6
Si vous comprenez la structure de chargement de classe de l'application, vous pouvez utiliser AOP sur le chargeur de classe pour suivre les événements de chargement de classe. Ce serait moins invasif sur un système de production que des conseils à tous les constructeurs.
ShabbyDoo
5
Cette réponse est assez bonne pour un langage dynamique mais terrible pour un langage statique qui pourrait faire BEAUCOUP mieux. Avec un langage typé statiquement (en dehors de la réflexion), vous pouvez savoir avec certitude exactement quelles méthodes sont utilisées et lesquelles ne le sont pas, c'est l'un des plus grands avantages d'un langage typé statiquement et vous devriez l'utiliser plutôt que la méthode faillible comme décrit ici .
Bill K
4
@BillK plus de réflexion se produit que vous ne le pensez. Par exemple, le printemps fait un peu de magie sous les couvertures, y compris la réflexion. Votre outil d'analyse doit imiter cela.
Thorbjørn Ravn Andersen
220

Un plugin Eclipse qui fonctionne raisonnablement bien est Unused Code Detector .

Il traite un projet entier ou un fichier spécifique et montre diverses méthodes de code inutilisé / mort, ainsi que des suggestions de changements de visibilité (c'est-à-dire une méthode publique qui pourrait être protégée ou privée).

Mikezx6r
la source
Ça a l'air bien mais je n'ai pas réussi à le faire fonctionner - l'action "Détecter un ... code" est désactivée et je n'ai pas trouvé de moyen de l'activer.
Ondra Žižka
1
Trouvez en effet des méthodes inutilisées, MAIS constatez également que mes EJB ne sont pas utilisés (alors qu'ils le sont) parce que j'utilise un modèle de modèle de délégué commercial
Eildosa
Fonctionne-t-il toujours sur kepler? communiqués de presse sur eclipse 3.8: ucdetector.org/releases.html
Mr_and_Mrs_D
Semble être en parfait état de fonctionnement sur Kepler.
Erik Kaplun
4
Voulez-vous ajouter un lien vers la place de marché marketplace.eclipse.org/content/unnecessary-code-detector ? Cela facilite l'installation et répond à la question de savoir s'il est pris en charge sur les nouvelles versions d'Eclipse.
Thomas Weller
64

CodePro a récemment été publié par Google avec le projet Eclipse. Il est gratuit et très efficace. Le plugin a une fonctionnalité ' Find Dead Code ' avec un / plusieurs point (s) d'entrée. Fonctionne plutôt bien.

Berlin Brown
la source
1
Ne fonctionnera plus avec eclipse Kepler. Après l'avoir installé avec succès via le site de mise à jour, il fait planter eclipse à chaque fois.
txulu
Malheureusement, il semble que cet outil ne se rend pas compte de l'existence de Spring, par conséquent, il marquera tous mes @Components comme inutilisés, à tort
Clint Eastwood
Devenir très vieux Ne fonctionne plus Last updated this plugin March 27, 2012 developers.google.com/java-dev-tools/download-codepro
mumair
2
Tous les liens sont obsolètes.
zygimantus
3
Malheureusement, il semble que Google ait vidé le code sur le projet Eclipse et tout oublié.
Thorbjørn Ravn Andersen
30

Je suis surpris que ProGuard n'ait pas été mentionné ici. C'est l'un des produits les plus matures du marché.

ProGuard est un rétrécisseur, optimiseur, obfuscateur et prévérificateur de fichiers de classe Java gratuits. Il détecte et supprime les classes, champs, méthodes et attributs inutilisés. Il optimise le bytecode et supprime les instructions inutilisées. Il renomme les classes, champs et méthodes restants en utilisant des noms courts sans signification. Enfin, il prévérifie le code traité pour Java 6 ou Java Micro Edition.

Certaines utilisations de ProGuard sont:

  • Création de code plus compact, pour des archives de code plus petites, un transfert plus rapide sur les réseaux, un chargement plus rapide et des empreintes de mémoire plus petites.
  • Rendre les programmes et les bibliothèques plus difficiles à rétroconcevoir.
  • Liste du code mort, afin qu'il puisse être supprimé du code source.
  • Retargeting et pré-vérification des fichiers de classe existants pour Java 6 ou supérieur, pour profiter pleinement de leur chargement de classe plus rapide.

Voici un exemple de code mort de liste: https://www.guardsquare.com/en/products/proguard/manual/examples#deadcode

David d C e Freitas
la source
8
Fournir un exemple d'utilisation ferait une meilleure réponse.
rds
1
En lisant la documentation, je vois qu'il réduit le code inutilisé, mais je ne trouve nulle part où il le répertorie - convenu, un exemple ou un lien vers la section pertinente de la documentation, serait très utile!
orbfish
26

Une chose que l'on sait faire dans Eclipse, sur une seule classe, est de changer toutes ses méthodes en privé et de voir ensuite les plaintes que j'obtiens. Pour les méthodes utilisées, cela provoquera des erreurs et je les ramènerai au niveau d'accès le plus bas possible. Pour les méthodes inutilisées, cela provoquera des avertissements sur les méthodes inutilisées, et celles-ci peuvent ensuite être supprimées. Et en prime, vous trouverez souvent des méthodes publiques qui peuvent et doivent être rendues privées.

Mais c'est très manuel.

skiphoppy
la source
4
Ce n'est peut-être pas la réponse idéale, mais c'est vraiment intelligent.
Erik Reppen
8
C'est intelligent ... jusqu'à ce que vous ayez un appel depuis un code inutilisé d'une autre classe.
Danosaure
Itérer sur cette méthode pourrait supprimer d'énormes portions de code car une méthode utilisée en crée d'autres une fois supprimée.
4myle
15

Utilisez un outil de couverture de test pour instrumenter votre base de code, puis exécutez l'application elle-même, pas les tests.

Emma et Eclemma vous donneront de bons rapports sur le pourcentage de quelles classes sont exécutées pour une exécution donnée du code.

jamesh
la source
1
+1 car c'est un bon point de départ, mais gardez à l'esprit que, par exemple, les variables inutilisées (mais déclarées) deviendront également vertes.
DerMike
13

Nous avons commencé à utiliser Find Bugs pour aider à identifier une partie du funk dans l'environnement riche en cibles de notre base de code pour les refactorings. Je considérerais également la structure 101 pour identifier les endroits de l'architecture de votre base de code qui sont trop compliqués, afin que vous sachiez où se trouvent les vrais marais.

Alan
la source
4
FindBugs ne peut pas détecter le code mort et inutilisé, uniquement les champs inutilisés. Voir cette réponse .
Stefan Mücke
12

En théorie, vous ne pouvez pas trouver de manière déterministe du code inutilisé. Il y a une preuve mathématique de cela (eh bien, c'est un cas particulier d'un théorème plus général). Si vous êtes curieux, recherchez le problème de l'arrêt.

Cela peut se manifester dans le code Java de plusieurs manières:

  • Chargement des classes en fonction de l'entrée utilisateur, des fichiers de configuration, des entrées de base de données, etc.
  • Chargement de code externe;
  • Passer des arborescences d'objets à des bibliothèques tierces;
  • etc.

Cela étant dit, j'utilise IDEA IntelliJ comme mon IDE de choix et il dispose de nombreux outils d'analyse pour les dépendances de recherche entre les modules, les méthodes inutilisées, les membres inutilisés, les classes inutilisées, etc. balisé inutilisé mais une méthode publique nécessite une analyse plus approfondie.

cletus
la source
1
Merci pour votre participation. Nous utilisons IntelliJ et y obtenons de l'aide. Quant au problème de l'arrêt et de l'indécidabilité, je connais la théorie, mais nous n'avons pas nécessairement besoin d'une solution déterministe.
knatten
12
La phrase d'ouverture est trop forte. Comme pour le problème de l'arrêt (également souvent mal cité / abusé), il n'y a pas de solutions générales complètes, mais il existe de nombreux cas spéciaux qui SONT faisables à détecter.
joel.neely
9
Bien qu'il n'y ait pas de solution générale pour les langues avec eval et / ou réflexion, il y a beaucoup de cas où le code est prouvablement inaccessible.
pjc50
1
Sans réflexion et avec du code source complet, tout langage typé statiquement devrait faciliter la recherche déterministe de tout le code inutilisé.
Bill K
Vous ne pouvez pas trouver que cela est prouvable inaccessible par réflexion ou par des appelants externes, mais vous pouvez trouver du code qui est prouvable inaccessible statiquement à partir d'un point d'entrée donné ou d'un ensemble de points d'entrée
nafg
8

Dans Eclipse, accédez à Windows> Préférences> Java> Compilateur> Erreurs / Avertissements
et remplacez-les tous par des erreurs. Corrigez toutes les erreurs. C'est le moyen le plus simple. La beauté est que cela vous permettra de nettoyer le code pendant que vous écrivez.

Capture d'écran du code Eclipse:

entrez la description de l'image ici

smileprem
la source
5

IntelliJ dispose d'outils d'analyse de code pour détecter le code non utilisé. Vous devriez essayer de rendre autant de champs / méthodes / classes que non publics que possible et cela affichera plus de méthodes / champs / classes inutilisés

J'essaierais également de localiser le code en double pour réduire le volume du code.

Ma dernière suggestion est d'essayer de trouver du code open source qui, s'il était utilisé, rendrait votre code plus simple.

Peter Lawrey
la source
Des exemples de ce que sont ces outils?
orbfish
@orbfish Vous pouvez exécuter Analyse=> Run inspection by name=>unused
Peter Lawrey
5

La perspective de tranche Structure101 donnera une liste (et un graphique des dépendances) de tous les "orphelins" ou " groupes orphelins " de classes ou de packages qui n'ont aucune dépendance vers ou depuis le cluster "principal".

Chris Chedgey - Structure101
la source
Est-ce que cela fonctionne pour les variables / méthodes d'instance au sein d'une classe?
Joeblackdev
Comment savoir si cela est censé fonctionner, par exemple avec Eclipse 4.3?
Erik Kaplun
3

DCD n'est pas un plugin pour certains IDE mais peut être exécuté depuis ant ou autonome. Il ressemble à un outil statique et peut faire ce que PMD et FindBugs ne peuvent pas faire . Je vais essayer.

PS Comme mentionné dans un commentaire ci-dessous, le projet vit maintenant dans GitHub .

Heiner
la source
Cela devrait descendre comme un commentaire et ne pas répondre
Comptez le
Veuillez mettre à jour votre réponse pour supprimer votre déclaration selon laquelle DCD "semble mort maintenant". La version 2.1 est sortie il y a 12 jours . De plus, le lien dans votre réponse ne fonctionne pas.
skomisa
2

Il existe des outils qui profilent le code et fournissent des données de couverture de code. Cela vous permet de voir (au fur et à mesure que le code s'exécute) combien il est appelé. Vous pouvez obtenir n'importe lequel de ces outils pour découvrir la quantité de code orphelin dont vous disposez.

Vaibhav
la source
2
  • FindBugs est excellent pour ce genre de chose.
  • PMD (Project Mess Detector) est un autre outil qui peut être utilisé.

Cependant, aucun des deux ne peut trouver des méthodes statiques publiques inutilisées dans un espace de travail. Si quelqu'un connaît un tel outil, faites-le moi savoir.

graveca
la source
1

Outils de couverture utilisateur, tels que EMMA. Mais ce n'est pas un outil statique (c'est-à-dire qu'il nécessite d'exécuter réellement l'application à travers des tests de régression et à travers tous les cas d'erreur possibles, ce qui est, bien, impossible :))

Pourtant, EMMA est très utile.

Vladimir Dyuzhev
la source
1

Les outils de couverture de code, tels qu'Emma, ​​Cobertura et Clover, instrumenteront votre code et enregistreront les parties de celui-ci qui seront invoquées en exécutant une suite de tests. Ceci est très utile et devrait faire partie intégrante de votre processus de développement. Il vous aidera à déterminer dans quelle mesure votre suite de tests couvre votre code.

Cependant, ce n'est pas la même chose que d'identifier un code mort réel. Il identifie uniquement le code couvert (ou non couvert) par les tests. Cela peut vous donner de faux positifs (si vos tests ne couvrent pas tous les scénarios) ainsi que de faux négatifs (si vos tests accèdent à du code qui n'est en fait jamais utilisé dans un scénario réel).

J'imagine que la meilleure façon d'identifier vraiment le code mort serait d'instrumenter votre code avec un outil de couverture dans un environnement en direct et d'analyser la couverture du code sur une longue période de temps.

Si vous exécutez dans un environnement redondant à charge équilibrée (et sinon, pourquoi pas?), Je suppose qu'il serait logique de n'instrumenter qu'une seule instance de votre application et de configurer votre équilibreur de charge de sorte qu'une partie aléatoire, mais petite, de vos utilisateurs s'exécutent sur votre instance instrumentée. Si vous effectuez cette opération sur une longue période (pour vous assurer que vous avez couvert tous les scénarios d'utilisation du monde réel - telles les variations saisonnières), vous devriez être en mesure de voir exactement quelles zones de votre code sont accessibles dans le cadre d'une utilisation réelle et quelles parties ne sont vraiment jamais accessibles et donc du code mort.

Je n'ai jamais personnellement vu cela, et je ne sais pas comment les outils susmentionnés peuvent être utilisés pour instrumenter et analyser du code qui n'est pas invoqué via une suite de tests - mais je suis sûr qu'ils peuvent l'être.

Vihung
la source
1

Il existe un projet Java - Dead Code Detector (DCD). Pour le code source, cela ne semble pas bien fonctionner, mais pour le fichier .jar - c'est vraiment bien. De plus, vous pouvez filtrer par classe et par méthode.

Lukasz Czerwinski
la source
0

Eclipse peut afficher / mettre en évidence du code qui ne peut pas être atteint. JUnit peut vous montrer la couverture du code, mais vous aurez besoin de quelques tests et devez décider si le test correspondant est manquant ou si le code est vraiment inutilisé.

Matthias Winkelmann
la source
3
Eclipse vous indiquera uniquement si la portée de la méthode est locale (c'est-à-dire privée); et même alors, vous ne pouvez pas être sûr à 100% ... avec réflexion, la méthode privée peut être appelée de l'extérieur.
p3t0r
0

J'ai trouvé l'outil de couverture Clover qui code les instruments et met en évidence le code utilisé et non utilisé. Contrairement à Google CodePro Analytics, il fonctionne également pour les applications Web (selon mon expérience et je peux me tromper sur Google CodePro).

Le seul inconvénient que j'ai remarqué est qu'il ne prend pas en compte les interfaces Java.

Kashif Nazar
la source
Afaict, c'est un outil CI non libre côté serveur.
Erik Kaplun
0

J'utilise Doxygen pour développer une carte d'appels de méthode pour localiser les méthodes qui ne sont jamais appelées. Sur le graphique, vous trouverez des îlots de groupes de méthodes sans appelants. Cela ne fonctionne pas pour les bibliothèques car vous devez toujours commencer à partir d'un point d'entrée principal.

jbruni
la source