Effective Java Debugging with Eclipse
Learning to write code efficiently is only one step towards becoming a coding master. Another step is learning to debug. When it comes to legacy or 3rd party code you will need to debug in order to understand how the code behaves. In this post I will give you some basic tips on how to master your debugger and become more efficient.
This is a follow up to My Top 10 Tips on how to be more productive with the Eclipse IDE (which you should read before this one). I’ll assume you already know how to launch a Debug configuration for your project in your Workspace.
Note: Click on the images to reveal a larger screenshot.
1. Breakpoints
Basic Breakpoints This is essential and you probably already know how to use it - the Breakpoint.
In case you’re not familiar with them, you create a breakpoint by double-clicking on the left side of a line of code. The execution of your application will then halt at that point so you can analyze the state and hopefully find the cause of your misbehaving code.
Exception Breakpoints Sometimes an exception occurs, but you are not sure where (e.g. no stack trace available) or the exception is not logged and not visible. This is the right time to create a global breakpoint that pulls the hand brake if a certain exception occurs.
You’ll find this in the Breakpoints
view of the Debug
perspective.
Conditional Breakpoints To speed up debugging by not stopping at a breakpoint everytime, you can add a condition. The breakpoint will only stop your application if the condition is fulfilled - and will not unnecessarily disturb your hunt for the bug.
You can get there with a right-click
on your break point > Breakpoint Properties...
2. Detail Formatter
While debugging and inspecting variables/objects in your debug perspective, you might encounter textual representations of objects that are not really meaningful. Usually the .toString()
method on an object is used for the debug UI. It’s not the greatest idea to implement the .toString()
method just for debugging purposes. Instead you can set up a detail formatter that takes care of the textual representation of your object.
You can get there by right-click
ing on the variable in the Variables
view, then selecting New Detail Formatter...
.
3. Logic Structure
Here you can see what a difference a small click can make. Both Views show the same Map
object. By activating Logic Structure
in your Variables view, you get the “contents” and structure of objects presented as you would expect it for a human reader.
4. Drop To Frame
In case your application stopped at your break point and the interesting things had already happened, you can “Drop To Frame”. This means you can jump back in your stack and then start debugging from there…
5. Inspect and Watch
Inspect
provides you basically with the same functionality as the Variables
View - you can unfold and inspect the various values of the object. Watch
on the other hand enables you to observe a specific Object and see how it changes over time.
6. Change Variable Values
The Variables View can do more than just display values. You can also edit values. I don’t think there is much more to say about it ;)
7. Step Into, Over and Return - Shortcuts
Try to memorize the following function keys. They will greatly speed up your debugging by avoiding constantly having to use your mouse.
- F5 – Step Into
- F6 – Step Over
- F7 – Step Return
- F8 – Run until next breakpoint is reached
8. Step Filtering
With “Step Filters” you can filter out types that you do not wish to see or step through while debugging. This helps you to stay focused on the actual code and does not expose you to the inner workings where you might not even have the source. Have a look at Holger’s Effective Mockito post about Step Filtering in conjunction with Mockito.
You’ll find this in: Preferences > Java > Debug > Step Filtering
9. Remote Debugging
With Remote Debugging you can debug an application running on a different machine. The debugging itself is like any other app that you usually launch from within Eclipse. This is what you need to do:
Make sure the source code on your machine and the application on the other machine are in sync.
Start the application on the other machine with the following command line parameters:
java -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005
suspend=y/n declares whether the JVM of the application you want to debug will wait for Eclipse to connect or if it will start right away. address=5005 configures the TCP port to use for remote debugging.
Create a Remote Java Application Debug Launch Configuration.
Specify the Host and Port for your remote application.
Add all the source projects of the application you want to debug to the Source tab.
10. Heap dump + Memory Analyzer
Sometimes you need a bigger picture of the inner workings of your application than you can get with line-by-line debugging - especially for finding memory leaks. In this case you are better off with the Eclipse Memory Analyzer (MAT). My colleague Ian wrote a blog post about how to create a heap dump and analyze it.
Update 21.01.2013: Ian just published an other more detailed article about the Eclipse Memory Analyzer: “10 Tips for using the Eclipse Memory Analyzer”
These are just a few tips regarding debugging. If you have feedback or something to add, please feel free to leave a comment below.