How to find unused/dead code in java projects [closed]
Asked Answered
D

21

318

What tools do you use to find unused/dead code in large java projects? Our product has been in development for some years, and it is getting very hard to manually detect code that is no longer in use. We do however try to delete as much unused code as possible.

Suggestions for general strategies/techniques (other than specific tools) are also appreciated.

Edit: Note that we already use code coverage tools (Clover, IntelliJ), but these are of little help. Dead code still has unit tests, and shows up as covered. I guess an ideal tool would identify clusters of code which have very little other code depending on it, allowing for docues manual inspection.

Dysphemism answered 2/10, 2008 at 14:22 Comment(5)
Keep the unit tests in a separate source tree (you should anyway) and run the coverage tools only on the live tree.Grudge
I would start with IDEA's "Unused declaration" inspection and uncheck Include test sources. Can you clarify what you mean when you say IDEA's "of little help"?Jackshaft
Ways to find dead code: 1) not linked by anything outside. 2) hasn't been used from outside even though linked in runtime. 3) Linked & Called but never used like dead variable. 4) logically unreachable state. So linking, accessing over time, logic based, use after accessing.Elwoodelwyn
Use IntelliJ Idea and my answer from here: #22522513 :)Rattlebrain
Addition to David Mole's answer : see this answer https://mcmap.net/q/86249/-how-to-use-intellij-idea-to-find-all-unused-codeSherylsheryle
N
43

I would instrument the running system to keep logs of code usage, and then start inspecting code that is not used for months or years.

For example if you are interested in unused classes, all classes could be instrumented to log when instances are created. And then a small script could compare these logs against the complete list of classes to find unused classes.

Of course, if you go at the method level you should keep performance in mind. For example, the methods could only log their first use. I dont know how this is best done in Java. We have done this in Smalltalk, which is a dynamic language and thus allows for code modification at runtime. We instrument all methods with a logging call and uninstall the logging code after a method has been logged for the first time, thus after some time no more performance penalties occur. Maybe a similar thing can be done in Java with static boolean flags...

Napier answered 2/10, 2008 at 14:48 Comment(8)
I like this answer but does anyone have an idea how to do this in Java without explicitly adding the logging in every class? Maybe some 'Proxy' magic?Proliferation
@Outlaw AOP seems to be perfect use case for this.Minta
If you understand the application's classloading structure, you could use AOP on the classloader to track classload events. This would be less invasive on a production system than advice before all constructors.Sanjiv
I've successfully used the java.lang.instrument.Instrumentation.getAllLoadedClasses() and addTransformer() methods to log which classes are loaded. The ClassFileTransformer doesn't modify the bytecode; it simply logs the class name. You must run a java agent in order to access an Instrumentation instance.Ballroom
Are there any tools that could automate this using AOP and bytecode weaving or equivalent?Vu
This answer is pretty good for a dynamic language but terrible for a static language which could do MUCH better. With a staticly typed language (aside from reflection) you can know for sure exactly which methods are used and which are not, this is one of the biggest advantages of a statically typed language and you should use it rather than the fallable method as described here.Illuminometer
@BillK more reflection happens than you thinks. E.g. Spring does quite a bit of magic under the covers, including reflection. Your analysis tool must emulate that.Nightdress
Actually most professional reflection based tools are moving to annotations instead of just string based reflection for exactly this reason. Reflection takes away pretty much the entire advantage of a statically typed language.Illuminometer
P
228

An Eclipse plugin that works reasonably well is Unused Code Detector.

It processes an entire project, or a specific file and shows various unused/dead code methods, as well as suggesting visibility changes (i.e. a public method that could be protected or private).

Picket answered 2/10, 2008 at 15:14 Comment(10)
Looks nice but I wasn't able to get it working - the "Detect un... code" action is disabled and I didn't find way to enable it.Ogbomosho
Do indeed find unused methods, BUT also find that my EJBs are being unused (while they are) because I'm using a business delegate pattern designZoophilous
Does it still work on kepler ? releases say about eclipse 3.8 : ucdetector.org/releases.htmlLorenalorene
Seems to be in perfect working condition on Kepler.Vu
I'm using: eclipse Luna M7 Release (4.4.0M7), on kubuntu 64 bit, and UCDetector caused eclipse to crash and not load my preferences -- had to uninstall the plug in. ( June 2014)Giblets
UCDetector says it works on Eclipse 3.4 to 4.4, which includes Kepler.Mack
I wouldn't recommend this tool. It is not efficient when it comes methods and static variables. Use Google CodePro instead.Cramp
Do you want to add a link to the marketplace marketplace.eclipse.org/content/unnecessary-code-detector ? This makes it easier to install and answers the question whether it is supported on newer versions of Eclipse.Supraliminal
This tool looks good, mainly in detecting classes and public methods with zero references. Does this tool have a single view to show what all it has detected? I didn't find any. I have to browse each class to see what this tool has to say about that class, there is no single view.Sheepshanks
UCD does not work for the methods those are being called from spring-web-flow. Is there any way to get similar 0 reference markers as we get in normal projects (non spring-web-flow)?Maje
A
64

CodePro was recently released by Google with the Eclipse project. It is free and highly effective. The plugin has a 'Find Dead Code' feature with one/many entry point(s). Works pretty well.

Ashram answered 29/3, 2011 at 16:34 Comment(7)
Wont't work anymore with eclipse Kepler. After installing it successfully via update site, it makes eclipse crash every time.Phelloderm
Unfortunately, it looks like this tool doesn't realize of the existence of Spring, therefore, it will mark all my @Components as unused, wronglyGudrin
Become very old Doesn't work any more Last updated this plugin March 27, 2012 developers.google.com/java-dev-tools/download-codeproNata
@Eildosa check this developers.google.com/java-dev-tools/codepro/html/tasks/…Weisburgh
All links are outdated.Osric
Unfortunately it appears that Google dumped the code on the Eclipse project and forgot all about it.Nightdress
go to here to download to eclipse. #29390808Deemphasize
N
43

I would instrument the running system to keep logs of code usage, and then start inspecting code that is not used for months or years.

For example if you are interested in unused classes, all classes could be instrumented to log when instances are created. And then a small script could compare these logs against the complete list of classes to find unused classes.

Of course, if you go at the method level you should keep performance in mind. For example, the methods could only log their first use. I dont know how this is best done in Java. We have done this in Smalltalk, which is a dynamic language and thus allows for code modification at runtime. We instrument all methods with a logging call and uninstall the logging code after a method has been logged for the first time, thus after some time no more performance penalties occur. Maybe a similar thing can be done in Java with static boolean flags...

Napier answered 2/10, 2008 at 14:48 Comment(8)
I like this answer but does anyone have an idea how to do this in Java without explicitly adding the logging in every class? Maybe some 'Proxy' magic?Proliferation
@Outlaw AOP seems to be perfect use case for this.Minta
If you understand the application's classloading structure, you could use AOP on the classloader to track classload events. This would be less invasive on a production system than advice before all constructors.Sanjiv
I've successfully used the java.lang.instrument.Instrumentation.getAllLoadedClasses() and addTransformer() methods to log which classes are loaded. The ClassFileTransformer doesn't modify the bytecode; it simply logs the class name. You must run a java agent in order to access an Instrumentation instance.Ballroom
Are there any tools that could automate this using AOP and bytecode weaving or equivalent?Vu
This answer is pretty good for a dynamic language but terrible for a static language which could do MUCH better. With a staticly typed language (aside from reflection) you can know for sure exactly which methods are used and which are not, this is one of the biggest advantages of a statically typed language and you should use it rather than the fallable method as described here.Illuminometer
@BillK more reflection happens than you thinks. E.g. Spring does quite a bit of magic under the covers, including reflection. Your analysis tool must emulate that.Nightdress
Actually most professional reflection based tools are moving to annotations instead of just string based reflection for exactly this reason. Reflection takes away pretty much the entire advantage of a statically typed language.Illuminometer
H
33

I'm suprised ProGuard hasn't been mentioned here. It's one of the most mature products around.

ProGuard is a free Java class file shrinker, optimizer, obfuscator, and preverifier. It detects and removes unused classes, fields, methods, and attributes. It optimizes bytecode and removes unused instructions. It renames the remaining classes, fields, and methods using short meaningless names. Finally, it preverifies the processed code for Java 6 or for Java Micro Edition.

Some uses of ProGuard are:

  • Creating more compact code, for smaller code archives, faster transfer across networks, faster loading, and smaller memory footprints.
  • Making programs and libraries harder to reverse-engineer.
  • Listing dead code, so it can be removed from the source code.
  • Retargeting and preverifying existing class files for Java 6 or higher, to take full advantage of their faster class loading.

Here example for list dead code: https://www.guardsquare.com/en/products/proguard/manual/examples#deadcode

Hollinger answered 22/8, 2011 at 7:40 Comment(2)
Providing a sample usage would make a better answer.Bedcover
Reading the documentation, I see that it shrinks unused code, but I can't find anywhere where it lists it - agreed, an example, or link to the relevant section of the documentation, would be quite helpful!Mazer
O
25

One thing I've been known to do in Eclipse, on a single class, is change all of its methods to private and then see what complaints I get. For methods that are used, this will provoke errors, and I return them to the lowest access level I can. For methods that are unused, this will provoke warnings about unused methods, and those can then be deleted. And as a bonus, you often find some public methods that can and should be made private.

But it's very manual.

Oospore answered 28/1, 2009 at 19:45 Comment(3)
Maybe not the ideal answer but that's really clever.Overstock
This is clever... until you have a call to it from an unused code from another class.Boggers
Iterating over this method could remove huge swaths of code as one used method creates others once it's removed.Fehr
L
15

Use a test coverage tool to instrument your codebase, then run the application itself, not the tests.

Emma and Eclemma will give you nice reports of what percentage of what classes are run for any given run of the code.

Longways answered 2/10, 2008 at 16:21 Comment(1)
+1 for it is a good starting point but keep in mind that e. g. unused (yet declared) variables will come up green as well.Renin
L
14

We've started to use Find Bugs to help identify some of the funk in our codebase's target-rich environment for refactorings. I would also consider Structure 101 to identify spots in your codebase's architecture that are too complicated, so you know where the real swamps are.

Locomobile answered 2/10, 2008 at 14:47 Comment(1)
FindBugs cannot detect dead and unused code, only unused fields. See this answer.Jaipur
J
13

In theory, you can't deterministically find unused code. Theres a mathematical proof of this (well, this is a special case of a more general theorem). If you're curious, look up the Halting Problem.

This can manifest itself in Java code in many ways:

  • Loading classes based on user input, config files, database entries, etc;
  • Loading external code;
  • Passing object trees to third party libraries;
  • etc.

That being said, I use IDEA IntelliJ as my IDE of choice and it has extensive analysis tools for findign dependencies between modules, unused methods, unused members, unused classes, etc. Its quite intelligent too like a private method that isn't called is tagged unused but a public method requires more extensive analysis.

Jenellejenesia answered 2/10, 2008 at 14:28 Comment(5)
Thank you for your input. We are using IntelliJ, and are getting some help there. As for the Halting Problem and undecidability, I am familiar with the theory, but we do not necesarilly need a deterministic solution.Dysphemism
Opening sentence is too strong. As with the Halting Problem (also often misquoted/abused), there's no complete general solutions, but there are plenty of special cases that ARE feasible to detect.Edy
While there isn't a general solution for languages with eval and/or reflection, there's lots of cases where code is provably unreachable.Pension
Without reflection and with full source code any statically typed language should make it pretty easy to deterministically find all unused code.Illuminometer
You can't find that's provable unreachable by reflection or by external callers, but you can find code that's provable unreachable statically from a given entry point or set of entry pointsWhinstone
F
9

In Eclipse Goto Windows > Preferences > Java > Compiler > Errors/Warnings
and change all of them to errors. Fix all the errors. This is the simplest way. The beauty is that this will allow you to clean up the code as you write.

Screenshot Eclipse Code :

enter image description here

Fairish answered 21/1, 2016 at 10:51 Comment(0)
B
5

IntelliJ has code analysis tools for detecting code which is unused. You should try making as many fields/methods/classes as non-public as possible and that will show up more unused methods/fields/classes

I would also try to locate duplicate code as a way of reducing code volume.

My last suggestion is try to find open source code which if used would make your code simpler.

Breeches answered 23/2, 2009 at 20:31 Comment(2)
Any examples of what these tools are?Mazer
@Mazer You can run Analyse => Run inspection by name => unusedBreeches
E
5

The Structure101 slice perspective will give a list (and dependency graph) of any "orphans" or "orphan groups" of classes or packages that have no dependencies to or from the "main" cluster.

Expecting answered 17/11, 2009 at 13:40 Comment(2)
Does this work for instance variables / methods within a class?Prospective
How do I know if this is supposed to work with e.g. Eclipse 4.3?Vu
E
3

DCD is not a plugin for some IDE but can be run from ant or standalone. It looks like a static tool and it can do what PMD and FindBugs can't. I will try it.

P.S. As mentioned in a comment below, the Project lives now in GitHub.

Emigrate answered 28/6, 2012 at 8:29 Comment(2)
This should go down as a comment not answerBryce
Please update your answer to remove your statement that DCD "looks dead now". Version 2.1 was released 12 days ago. Also, the link in your answer doesn't work.Semiramis
J
2

There are tools which profile code and provide code coverage data. This lets you see (as code is run) how much of it is being called. You can get any of these tools to find out how much orphan code you have.

Jess answered 2/10, 2008 at 14:24 Comment(0)
C
2
  • FindBugs is excellent for this sort of thing.
  • PMD (Project Mess Detector) is another tool that can be used.

However, neither can find public static methods that are unused in a workspace. If anyone knows of such a tool then please let me know.

Cubeb answered 28/1, 2009 at 19:38 Comment(0)
S
1

User coverage tools, such as EMMA. But it's not static tool (i.e. it requires to actually run the application through regression testing, and through all possible error cases, which is, well, impossible :) )

Still, EMMA is very useful.

Symbolic answered 2/10, 2008 at 16:16 Comment(0)
I
1

Code coverage tools, such as Emma, Cobertura, and Clover, will instrument your code and record which parts of it gets invoked by running a suite of tests. This is very useful, and should be an integral part of your development process. It will help you identify how well your test suite covers your code.

However, this is not the same as identifying real dead code. It only identifies code that is covered (or not covered) by tests. This can give you false positives (if your tests do not cover all scenarios) as well as false negatives (if your tests access code that is actually never used in a real world scenario).

I imagine the best way to really identify dead code would be to instrument your code with a coverage tool in a live running environment and to analyse code coverage over an extended period of time.

If you are runnning in a load balanced redundant environment (and if not, why not?) then I suppose it would make sense to only instrument one instance of your application and to configure your load balancer such that a random, but small, portion of your users run on your instrumented instance. If you do this over an extended period of time (to make sure that you have covered all real world usage scenarios - such seasonal variations), you should be able to see exactly which areas of your code are accessed under real world usage and which parts are really never accessed and hence dead code.

I have never personally seen this done, and do not know how the aforementioned tools can be used to instrument and analyse code that is not being invoked through a test suite - but I am sure they can be.

Invincible answered 26/11, 2008 at 16:40 Comment(0)
M
1

There is a Java project - Dead Code Detector (DCD). For source code it doesn't seem to work well, but for .jar file - it's really good. Plus you can filter by class and by method.

Monsoon answered 6/9, 2013 at 12:55 Comment(0)
U
1

Netbeans here is a plugin for Netbeans dead code detector.

It would be better if it could link to and highlight the unused code. You can vote and comment here: Bug 181458 - Find unused public classes, methods, fields

Urmia answered 12/2, 2017 at 4:39 Comment(0)
C
0

Eclipse can show/highlight code that can't be reached. JUnit can show you code coverage, but you'd need some tests and have to decide if the relevant test is missing or the code is really unused.

Coke answered 2/10, 2008 at 14:24 Comment(1)
Eclipse will only tell you if the scope of the method is local (ie. private); and even then you can't be 100% sure... with reflection private method could be called from the outside.Chrismatory
A
0

I found Clover coverage tool which instruments code and highlights the code that is used and that is unused. Unlike Google CodePro Analytics, it also works for WebApplications (as per my experience and I may be incorrect about Google CodePro).

The only drawback that I noticed is that it does not takes Java interfaces into account.

Algology answered 13/12, 2011 at 10:14 Comment(1)
Afaict, it's a non-free server side CI tool.Vu
S
0

I use Doxygen to develop a method call map to locate methods that are never called. On the graph you will find islands of method clusters without callers. This doesn't work for libraries since you need always start from some main entry point.

Slapjack answered 1/3, 2017 at 21:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.