Debugging Java applications using IntelliJ IDEA

IntelliJIDEADebuggingJavaThe creators of IntelliJ IDEA claim that it’s the most intelligent Java IDE out there. IntelliJ IDEA is said to be obsessed with helping developers achieve their best and enjoy their work – consistently, sustainably, over time. There are 1000s of IDEA users who would vouch for that claim and who use IDEA as their preferred IDE rather than NetBeans, Eclipse or any of the other more well known IDE.


Manning recently released the book “IntelliJ IDEA In Action” and the following is an excerpt from the book. It deals with the different kind of errors encountered during development and how best to use IntelliJ IDEA to debug your Java J2EE applications. Although some portions of the excerpt are IntelliJ specific, there’s a lot of info about debugging techniques and best practices, which could be useful irrespective of which IDE you use.



Adapted
from: IntelliJ IDEA in Action,

written by Fields, Saunders
and Belyaev

ISBN: 1932394443


Reprinted by permission of
Manning Publications Co.

Debugging

applications

In
this chapter…


* Running
programs under the IDEA debugger
*
Managing
breakpoints and monitoring runtime values
* Working
with threads and the call stack
*
Configuring
the debugger


We’d
all like to think that we never make mistakes. No matter how good a
developer you are, if you write programs then you also write
bugs—it’s an unavoidable fact of life. The question isn’t
whether you’ll need to debug your program, but how you plan on
going about doing it. Many beginning programmers rely on System.out.println() to show them what’s happening inside their program, but more
sophisticated developers understand the benefits of using a debugging
tool. The debugger included with IDEA is a powerful, easy-to-use tool for examining a running program to
determine what’s happening (or not happening) behind the
scenes. After reading this chapter, you’ll never need to rely
on print statements again.




  • Introducing
    the debugging process



In
this section, we’ll introduce the basic concepts of using a
symbolic debugger to analyze Java programs. If you’re familiar
with using such tools, and you just want to understand how the IDEA debugger works, feel free to skim ahead to the next section.




  • Finding
    and fixing bugs with a debugger



We
must start with some bad news: A debugger can neither find nor fix
bugs. If it could, we’d all have a lot more free time. No,
you’ll need to find the bugs on your own, either through
testing or pure luck (if you call getting big nasty stack traces
lucky). Although the debugger won’t fix bugs for you, it’s
immensely helpful in tracking them down and understanding what you
must do to fix them.




  • A debugger is essentially a tool that can tell you what’s
    going on inside the Java VM as your program is executing. It lets you start your program and
    then walk through it, method by method or line by line, using a
    process known as stepping through the code. Executing your
    code this way lets you slow things down and monitor your
    application’s progress. Each step of the way, you can examine
    the state and contents of your application’s variables and
    object references. The process can answer burning questions like,
    “What is the value of the variable x at the start of this method?”, “Where did that null
    pointer exception come from?”, and “How did I get here?”



  • Once
    you suspect a bug is lurking in your code, it’s time to bring
    out the debugger. Before you begin hunting down bugs, it’s
    important to know exactly what you’re looking for and to have
    an idea where you may find it. In the wild, you’ll encounter
    several different species of bugs, and the debugger can help you
    track down all of them.


Syntax
errors


Syntax
errors are the bugs you’re probably most familiar with. We bet
the first program you ever wrote consisted primarily of syntax
errors. (Heck, we still work with some guys like that.) Syntax
errors
are invalid statements or code structure that the Java
compiler can’t make sense of. In other words, they’re
just plain wrong.




  • Examples
    of syntax errors include referencing a variable that doesn’t
    exist or passing the wrong number of parameters to a method. Thanks
    to the real-time syntax analysis feature of IDEA’s
    editor, you’ll probably catch most of these errors before they
    get to the compiler, but occasionally one will slip through.



  • Bugs
    of this type surface during compilation and therefore can’t
    affect running code. The debugger is designed for analyzing programs
    that run, and it can’t help fix compilation problems like
    syntax errors—you’re on your own for that. It will,
    however, help determine the cause of any runtime errors you
    encounter.



Runtime
errors


Runtime
errors stick out like a sore thumb; you can’t miss them. They
can rear their ugly heads at any time, often with dramatic explosions
of stack traces and cryptic error messages. The JVM throws a runtime error when something unexpected happens, like trying
to read off the end of an array or encountering a null where an
object was expected. In Java, these issues are called exceptions,
and they come in many varieties. Some exceptions you’ll handle
yourself; others will bubble up and be handled by the VM or your application server. (Of course, its idea of handling an
exception may be to shut down the application.)




  • Once
    you’ve encountered a runtime error, you can use IDEA’s
    debugger to investigate its cause. If you have access to a stack
    trace or log message for the exception, it may help narrow down the
    source of the problem, possibly even giving the exact line number.
    But as we said, exceptions are inherently unexpected—so the
    question is, what happened that wasn’t expected? By executing
    the program in the debugger, you can follow its progress, test your
    assumptions, and observe the program data in a state of suspended
    animation. All of these features should help you determine what went
    wrong.



Logic
errors


Logic
bugs are trickier beasts because they may not be readily apparent.
With a logic error, your application seems to work fine, but the
outcome isn’t as expected. For example, if your new sorting
method generates lists of data that aren’t properly sorted, you
probably have a logic error.




  • Like
    runtime errors, the key to resolving logic errors is being able to
    peek under the covers of the running program. By examining the
    contents of your supposedly sorted list at each step of execution,
    you can try to determine the issue at hand.



Race
conditions


A race condition is a bug caused by an unexpected dependency on
the relative timing of events. For example, if an instance variable
is accessible by two threads simultaneously, one thread may interfere
with another’s use of the class. While this situation may not
cause a problem every time you run your application, the potential is
always there. Bugs tied to race conditions only cause a problem when
the timing is just right (or just wrong, depending how you look at
it). Race conditions are often the result of threading problems; to
help you find them, IDEA gives you the ability to examine all of your application’s
threads when searching for the problem.


The
dreaded Heisenbug


As
with particle physics, the attempt to examine a system tends to alter
its behavior in some way. Heisenbugs, a take-off on the
Heisenberg uncertainty principle, are bugs that seemingly disappear
or change their appearance when you try to track them down in the
debugger. Although using a debugger is for the most part a
noninvasive process, be aware that it can affect your running code in
terms of timing and concurrency. In particular, applications will run
slower under the debugger, which may cause bugs to run for cover when
you try to seek them out. Race conditions and threading-related bugs
are particularly susceptible to this effect.





  • Preparing
    your code for debugging



One
nice thing about working with a debugger to root out problems is that
you aren’t required to modify your source code, recompile, use
a special VM,
implement a magic interface, or write your code in any particular
style. The debugger takes advantage of monitoring technology built
into the Java platform. You do, however, have to follow a few rules
to make sure that the debugger can operate correctly with your
classes.


Generating
symbolic debugging information


When
you build your application, the compiler converts all your pretty
Java code into a tight bundle of Java byte code. A debugger works by
tracking the byte code’s execution and reporting on the
original source code references that generated it. This relationship
between byte code, your code symbols, and their original source files
and line numbers is called symbolic debugging information, and
it isn’t strictly required by the JVM to run your program. After all, the JVM doesn’t care that line number 3,310 from the file
LogonEventListener.java added 1 to the value of the variable logins;
it just executes the byte code to make it happen.




  • But
    you do care—unless you speak byte code. That is why when you
    compile your application, you must tell the compiler to preserve
    this information and save it as part of the generated class file.
    Fortunately, this is the default mode in most compilers, but you
    must be aware of this fact when specifying your compilation options.
    Why would you ask the compiler to omit this information? Because
    doing so reduces the size of your class files and may help protect
    the class files from reverse engineering. For this reason, some
    developers choose to compile their application twice, creating a
    debug version (which they keep) and a production version (which they
    deploy). For the production version, they omit the symbolic
    debugging information for the reasons stated earlier.



Compiling
the latest version of your code


Given
that the debugger works by mapping the running byte code to the
original source code, it stands to reason that the two must be in
sync. If your source code has been modified since you compiled and
executed your application, then the debugger is unable to accurately
report on its progress. When lines of executing source don’t
match up to your local source, things can get very confused, very
quickly. We’ve all been caught watching the debugger step
through yesterday’s class with today’s source. For that
reason, it’s best to always perform a clean build of your
application before firing up the debugger, to make sure everything is
properly updated.


Gathering
third-party source code


If
you’re using any third-party libraries and have their source
code, it’s a good idea to add it to your project. Sometimes
during your debugging you’ll want to follow the program flow
into these libraries to understand where a problem is occurring.
(Maybe it’s a bug in a vendor library and not your fault!) If
you have access to all the source code, you’ll more easily be
able to tell what’s going on.


Disabling
the JIT


The
just in time compiler (JIT)
is a component in the VM that helps improve the performance of running applications. It works
by caching generated machine code in memory and reusing it to speed
up execution of the program. When doing so, however, you lose your
ability to generate meaningful stack traces, even though the debugger
may still work. If a problem arises in executing the cached machine
code, the stack trace will only display the unhelpful reference in
compiled code
.




  • Therefore,
    you may want to turn off the JIT while debugging in order to more clearly follow what’s
    happening in the case of a problem. Options vary by VM,
    but generally you can disable the JIT by launching the VM with the parameter compiler=none. JDK 1.4 is smart about this type of thing, and it makes sure methods
    with breakpoints in them aren’t optimized by the JIT;
    this is supposed to eliminate this problem in the debugger.



Setting
breakpoints


When
you launch your program in the debugger, it runs uninterrupted until
it hits a breakpoint marker. A breakpoint is a logical code
reference that causes the debugger to suspend the program (or take
some other action) when it reaches that point. Once suspended, you
can use the debugger’s tools to examine the state of your
program. You can then advance the program to the next breakpoint or
the next line of code at your leisure.




  • Generally,
    you’ll set up breakpoints in your code to suspend the VM just as your program enters a section of code that you suspect is
    the source of a bug. Then you can follow the program step by step
    and make sure things are going as expected.



  • Breakpoints
    are markers known only to IDEA and the VM.
    They aren’t saved in your Java source or built into your
    generated class files. Therefore, breakpoints can be set or cleared
    as needed, at any time—even while the program is running. You
    may need to set them before launching your program, for example,
    should you wish to stop its execution early. Conversely, you may
    wish to toggle breakpoints on and off throughout the debugging
    session as you try to narrow down the problem.





  • Debugging
    your source code



Once
your code is compiled and ready to go, you launch the application in
the debugger to begin your bug hunting at the first breakpoint. From
there, you can peek at what’s happening inside your
application. We’ll discuss the details of using the debugger in
the next section of this chapter.


Launching
your application in the debugger


When
you use IDEA’s
debugger to launch your program, you’re actually running your
program with the VM’s
debug mode enabled. In debug mode, the VM continually reports information about the state of your program to
the debugger, which in turn displays the data to you in a meaningful
way.




  • WARNING
    IDEA uses the Java Platform Debugger Architecture (JPDA),
    a technology built into the Java2 platform, as a source of debugging
    information. If you’re developing an application using Java 1.1
    or earlier, you won’t be able to use the debugger.



Stepping
through your program


The
debugger allows you to step through each line of source code at
whatever pace you desire. This lets you follow each step logically,
evaluating the results and observing program flow. You can choose to
examine every line as it’s executed or skip ahead to meaningful
parts of the code you wish to observe more closely.


Examining
the values of variables and program state


As
you step through the program, you have the opportunity to examine the
internal values of your classes to see if they contain what you
expect them to. You can peek inside collections and arrays, evaluate
the output of methods, and examine instance variables. The debugger
also presents information about the current state of execution, the
call stack, and your program’s threads in order to help you
understand exactly what your program is doing.


Changing
data values on the fly to observe the results of potential changes


Beyond
strict observational capabilities, the debugger also lets you tweak
values on the fly in order to observe the results. For example, you
can force a method to return false instead of true, and observe the
outcome; or skip to the end of a loop by incrementing its counter.





  • Working
    with breakpoints



Breakpoints are source code markers used to trigger actions during a debugging
session. Typically, the purpose behind setting a breakpoint is to
suspend program execution to allow you to examine program data.
However, IDEA can use breakpoints as triggers for a variety of different actions,
as you’ll learn in this section. Breakpoints can be set at any
time during the debugging process, including prior to launching your
program in the debugger. Your breakpoints won’t affect your
Java source code files directly, but breakpoints and their settings
are saved with your IDEA project so you can reuse them across debugging sessions.




  • Managing
    breakpoints




You
can manage breakpoints through the Breakpoints panel, shown in
figure
6.1, which is accessible through the menu option Run | View
Breakpoints
(Ctrl+Shift+F8) as well as through the
corresponding icon on the Debug window toolbar.


Working
with different types of breakpoints


IDEA lets you create four types of breakpoints. Each is managed through
its own tab in the Breakpoints panel. The number beside each
type of breakpoint indicates the number of breakpoints defined for
that type. IDEA supports the following types of breakpoints:




  • Line
    breakpoints
    are assigned to a particular line of Java source.



  • Method
    breakpoints
    act in response to the program entering or exiting a
    particular method.



  • Exception
    breakpoints
    are triggered when a specified exception is thrown.



  • Field
    watchpoints
    allow you to react to any access or modification of
    specific instance variables.



Each
of these breakpoints addresses different debugging needs and has its
own individual settings. In this section, we’ll address some of
the concepts common to all types of breakpoints. We’ll discuss
each type of breakpoint in detail in the following sections.




  • TIP
    The
    easiest way to create line breakpoints in your application code is to
    click the gutter area next to the line of interest. If you Alt+Click the gutter area, the appropriate breakpoint type will appear. Its
    type depends on the context of the current line. You can remove a
    breakpoint by clicking its icon in the gutter area . The keyboard
    shortcut for toggling breakpoints is Ctrl+F8.




Here’s
another gem for 5.0 that makes it easy to set up logging
breakpoints. Select an expression or symbol you want to log during
debugging, and then Shift-Click in the gutter next to the line
where you wish to set the breakpoint. Doing so automatically creates
a breakpoint that doesn’t suspend the VM but only logs the value of the expression to the debugging console.


Navigating
back to the breakpoint’s source


For
method and line number breakpoints, you can use the View Source and Go to buttons to visit the source code the breakpoint
references. The View Source button loads the source into the
editor, and the Go to button also closes the Breakpoints panel and switches focus to the editor.


Breakpoint
icons


When
a breakpoint is set, the editor displays a breakpoint icon in the
gutter area to the left of the affected source code. Each type of
breakpoint is represented by its own icon in the editor, as shown in
table 6.1. The icons indicate both the type and status of the
breakpoint. You can place your mouse pointer over a breakpoint icon
in the gutter area of the editor to review the breakpoint’s
settings, including information about its type, location, and action.
In some cases, it’s possible for multiple breakpoints to apply
to the same line, in which case the icons line up next to one
another, expanding the gutter area as required.




  • The
    icons also serve as convenient shortcuts for managing your
    breakpoints. Clicking the icon removes the breakpoint. Successive
    use of Alt+Click the icon toggles its state between enabled
    and disabled. Right-clicking the breakpoint icon provides a context
    menu with three options:





  • Disable (like Alt+Click) temporarily disables the breakpoint.



  • Remove permanently removes the breakpoint.



  • Properties lets you configure the breakpoint in the Breakpoints panel.






























































    • The
      editor displays the status of your breakpoints in the left
      gutter. The icons allow you to immediately tell the type and
      status of the breakpoint without requiring a visit to the
      Breakpoints configuration window.


    Icon

    Description

    A
    breakpoint

    A
    disabled breakpoint

    A
    verified line breakpoint (visible only during an active debug
    session)

    An
    invalid line breakpoint (visible only during an active debug
    session)

    A
    field watchpoint

    A
    disabled field watchpoint

    A
    verified field watchpoint (visible only during an active debug
    session)

    An
    invalid field watchpoint (visible only during an active debug
    session)

    A
    method breakpoint

    A
    disabled method breakpoint

    A
    verified method breakpoint (visible only during an active debug
    session)

    An
    invalid method breakpoint (visible only during an active debug
    session)



Runtime
breakpoints


When
you run the debugger, it prepares and evaluates the configured
breakpoints. When this happens, the breakpoint becomes either verified or invalid, and the icon in the gutter area
updates to reflect this state. If the breakpoint is refused and
becomes invalid, in most cases it means there was an absence of
debugging information or the information doesn’t correspond to
the source code. In some cases, recompiling your sources may solve
the sync problem.


Removing
and disabling breakpoints


You
can permanently remove any breakpoint from your project by selecting
its entry in the Breakpoints panel and clicking its tab’s Remove button. To temporarily disable a breakpoint without
removing it, deselect the checkbox next to its definition. You can
also remove and disable individual breakpoints through their icon by
clicking and Alt+Clicking, as described earlier



You
can now use drag and drop to reposition breakpoints in your code.
Grab the breakpoint with your mouse, and drag it to its new home.




  • Working
    with line number breakpoints



If
you’ve worked with other debuggers, you’re already
familiar with line number breakpoints. These are the most
common type of breakpoints and are a staple of the debugging process.
Quite simply, they’re used to target a particular section of
code for debugging.


Breaking
at a line number


Line
number breakpoints are triggered when the program reaches the
specified line of source, before the line is executed. It’s
possible to define a line breakpoint that is never reached during
program execution, in which case it’s ignored.




  • Setting
    or unsetting a line number breakpoint is easy. Bring up the source
    file in question in the editor, position the cursor anywhere on the
    line you wish to target, and do one of the following to toggle the
    breakpoint on or off:





  • Choose Run | Toggle Line Breakpoint (Ctrl+F8).



  • Click
    in the gutter area next to the line.



Once
set, a line number breakpoint remains in the project until it’s
removed. Note, however, that the breakpoint is assigned to the line
number, not to the code. Moving or altering the line of code moves
its corresponding breakpoint, but the breakpoint obtains an invalid
status until you reload the class.




  • Line
    breakpoints can only be set on lines of code that can be executed by
    the VM.
    Comments, declarations of fields or methods, and empty lines aren’t
    valid locations for line breakpoints. If one of your breakpoints is
    invalid, it appears with the invalid breakpoint icon during your
    debugging session and is ignored.





  • TIP
    If
    the debugger shows some of your breakpoints as invalid even though
    they’re assigned to lines of code you know to be executable,
    your source code may be out of sync with the running application. Try
    recompiling your application and rerunning the debugger. You can even
    avoid recompiling and restarting your application by using IDEA’s
    HotSwap feature, which lets you reload classes within a running debug
    session (via the Run | Reload Changed Classes command).





  • Working
    with method breakpoints



Method
breakpoints
allow you to target your debugging sessions by the
method, rather than by line number, that you wish to investigate.
They let you follow program flow at the method level as well as check
entry and exit conditions. Unfortunately, relying on method
breakpoints can slow down the application you’re debugging, so
use them sparingly.


Setting
a method breakpoint


You
create a method breakpoint by placing your cursor inside the method
in question and selecting Run | Toggle Method Breakpoint from
the menu bar. The method breakpoint icon appears in the gutter area
next to the method declaration.




  • It
    doesn’t matter where inside the method your cursor is when you
    place the breakpoint. The breakpoint applies to the method as a
    whole, and the icon always appears next to the declaration
    statement. Left-clicking the icon removes it, whereas right-clicking
    brings up a context menu allowing you to modify the breakpoint’s
    properties.



  • You
    can also Alt+Click the gutter area next to the line where the
    method is declared, to set a method breakpoint basing on the context
    of the line.



Breaking
on method entry or exit


In
the Watch group of the Method Breakpoints options panel
are two checkbox options: Method entry and Method exit.
These selections control the points in the method access at which the
breakpoint’s action is triggered. You must enable at least one
of these method trigger conditions, both of which are on by default.
Select or deselect the boxes as required.




  • Working
    with exception breakpoints



Exception
breakpoints
allow you to tell the debugger to respond to thrown
exceptions. Unlike the line number and method breakpoints, which
require specific source references, exception breakpoints apply
globally to the exception condition, not to a particular code
reference. Exception breakpoints are a great shortcut to finding the
source of problems stemming from a Throwable condition deep in the bowels of your code, without the fuss of having
to track down the exact source of the problem yourself. (What can we
say? We’re as lazy as the next guys.)


Breaking
when a certain exception is thrown


Because
of their global nature, you must use the Breakpoints dialog to
create exception breakpoints. Select the Exception Breakpoints tab, and click the Add button to create a new breakpoint.
You’re presented with a dialog for selecting the exception you
wish to break on. You can select any Throwable class from your Classpath. Once a breakpoint is set for a particular
type of exception, its action is triggered when the exception is
thrown anywhere in the code. If this is too aggressive for you, you
can narrow the scope through the use of class filters.




  • TIP
    A
    very handy feature is the Any Exception option of the Breakpoints dialog. It’s a global option that can’t
    be removed, only disabled. Activating this option breaks the
    execution of the application at any point where it causes an
    exception, even if no breakpoint is explicitly set for that
    exception. Using Any Exception quickly illustrates any
    exception paths in the application’s execution.



Differentiating
between caught and uncaught exceptions


The Notifications option group for exception breakpoints provides
options for responding to caught and uncaught exceptions. By
selecting some combination of these two options, you can control the
type of exceptional condition that should trigger this breakpoint. If
a box is deselected, exceptions in that situation won’t trigger
the debugger action.



  • Working
    with field watchpoints



Field
watchpoints allow you to target your debugging search to specific
instance variables. For example, if at the end of a complicated
process you’re ending up with an obviously wrong value on one
of your fields, then setting up a field watchpoint may be the
quickest way to determine the origin of the fault.


Adding
a field watchpoint through the Breakpoints configuration window


Typically,
you set up a field watchpoint from the editor when the caret is on
the line of the field declaration. Select Run | Toggle Field
Watchpoint
from the main menu, or Alt+Click the gutter
area next to that line. You can also set a field watchpoint through
the Breakpoints dialog. Select the Run | View Breakpoints menu item to bring up the Breakpoints dialog (or press Ctrl+Shift+F8), and select the Field Watchpoints tab.
Like the
other types of breakpoints, any currently defined field watchpoints
are listed here. Click the Add button to bring up the Add
Field Watchpoint
dialog, and specify the class and field name you
want to break on. The class name you provide here must be fully
qualified. Using the selection buttons next to each field makes this
process easier, because you can navigate to the desired class and
field by name or through a tree view of your project.




  • Once
    added, your field watchpoint displays a corresponding icon in the
    editor’s gutter area. It behaves like other breakpoint icons:
    It can be disabled, enabled, or removed directly from the gutter
    area.





  • TIP
    You
    can set field watchpoints directly through the editor. To do so,
    right-click the line with declaration of the field you want to watch,
    and then select the Toggle Field Watchpoint option from the
    context menu. This sets the breakpoint and opens the Breakpoints dialog.



Adding
a field watchpoint while debugging


There
is another way to add a field watchpoint. Although it’s more
convenient, it can only be used once a debugging session is underway.
After you’ve suspended your application, you can add a field
watchpoint for an instance variable by right-clicking its icon in the
frame view and selecting the Add Field Watchpoint menu item.
This command creates the appropriate field watchpoint and opens the Breakpoints dialog. In addition, it prepopulates the instance
filter (described in the next section) with the instance ID of the field’s source object.


Breaking
on field access or modification


Regardless
of how you set up your field watchpoints, you must specify under
which circumstance you want the debugger to trigger the breakpoint.
These options are located in the Watch group of the Breakpoints dialog panel.




  • The
    first option, Field access, tells the debugger that you wish
    to trigger the breakpoint any time the field is accessed. This could
    involve initialization, read access, or write access. The second
    option, Field modification, says that you only care about
    changes to the field. Simple read attempts won’t cause the
    breakpoint to trigger. You must select at least one of these
    options.





  • Setting
    conditional breakpoints



Breakpoints
needn’t be absolute. You can also create breakpoints that take
effect only under certain conditions and situations. This gives you a
much finer degree of control, allowing you to spend more time
debugging and less time stepping through program code.


Breaking
only when a certain condition is true


This
option lets you specify a logical condition for activating the
breakpoint’s action. The condition is any valid Java expression
that evaluates to a boolean (true/false)
value at runtime. This expression is evaluated in the context of the
current line, so it can use any available fields, methods, or
variables available at that point. For example, any of the following
represent valid boolean expressions, assuming the referenced variables are accessible at the
breakpoint:


time
>= 100


user.getRoleId()
== STUDENTROLE


response
!= 0 && response > 12


Notice
that these are expressions, not lines of code or statements—don’t
end the expression with a semicolon. To set the break condition,
enter the expression in the Condition field of the Conditions option group, and enable it by selecting the appropriate checkbox.
Your expression isn’t validated until the debugger reaches it,
so type carefully! If you make a mistake and enter an invalid
expression, you’ll be notified when it’s reached and
given the option of breaking.




  • TIP
    You
    can use IDEA’s
    code-completion features to help construct your expression.



Breaking
only for certain instances


The Instance filters option lets you activate a breakpoint for
particular instances of the class within the VM.
Each object in the VM is assigned an instance ID at creation time. You can see this instance ID in the debugger’s view of the stack frame as the number
following the @ sign next to an object reference. Unfortunately, you can’t
predict the instance ID value—it’s not necessarily sequential. Instance IDs
change from run to run, so this conditional breakpoint setting must
be reset with each run.




  • When
    enabled, the breakpoint applies only to an object’s instance
    whose ID is included in the instance filter list. This option is useful for
    following the progress of a single object instance as it travels
    through code paths shared with many other instances, such as when
    you’re working with objects in collections.



Breaking
only for certain classes


You
can use class filters to narrow the scope of breakpoints so they
apply only to particular classes. Simple wildcard expansion can be
used to match the fully qualified class name. The filter format is
limited to either an exact match or a pattern match beginning or
ending with an asterisk. For example:




  • com.acme.conversion.currency.Currency matches a single class, Currency.



  • com.acme.conversion.currency.* matches all classes in the currency package and its subpackages.



  • java.* matches all classes in the core java packages.



  • *Listener matches any class whose name ends with Listener.



To
create a set of class filters for a breakpoint, enable the Class
filters
option and type in the pattern or list of patterns
delimited by spaces. By using a minus sign before a pattern, you can
exclude matching class(es) from the scope.




  • As
    an alternative to typing, you can click the ellipsis button next to
    the text box to show the Class Filters dialog; there you can
    specify the set of patterns using the IDEA’s find class by name feature.



Breaking
after a certain number of passes


This
option lets you create breakpoints that become active only after they
have been reached a certain number of times. To enable this
condition, enter a numeric value in the Pass count field of
the Conditions option group, and select the checkbox. The Pass
count
value is the threshold for enabling this breakpoint,
meaning that the breakpoint is active for all subsequent passes once
this threshold has been crossed. It doesn’t specify which
execution pass to debug, but rather the number of passes to skip
before debugging.




  • This
    option is useful for debugging loops or other lines of code that are
    called repeatedly. For example, if you want to examine the last
    iteration of a loop that runs 10,000 times, but you don’t feel
    like stepping through it for an hour, set the Pass count option to 9,999 to trigger your debugging action on the last
    iteration.





  • WARNING
    The Pass count condition is mutually exclusive with any other
    conditional operation.


————–

If you liked this excerpt from the book “IntelliJ IDEA In Action“, do check out the book.

Related:
>> IntelliJ IDEA 5.0 with JSP2 and J2ME features
>> IntelliJ IDEA beats both hands down on every factor except price
>> Top Java IDEs
>> Java IDE comparison: Borland JBuilder tops

Content Team

The IndicThreads Content Team posts news about the latest and greatest in software development as well as content from IndicThreads' conferences and events. Track us social media @IndicThreads. Stay tuned!

0 thoughts on “Debugging Java applications using IntelliJ IDEA

Leave a Reply