Version Reviewed: 2.0
Current Version: 2.0
Rating: 3.5 cups
Cup rating system:
KL Group, Inc.
260 King Street East
Canada M5A 1K3
Tools for diagnosing and eliminating code errors and inefficiencies are much in demand.
Whatever the language or platform, developers need to know what's causing problems in their code
and where. For some time now, C++ developers have enjoyed a range of tools designed to help them
anticipate and correct performance problems during the development cycle. Until fairly recently,
Java jocks were not so lucky.
Last year, Canada's KL Group Inc., combined several of its Java debugging products into a utilities
suite to provide developers with an excellent toolset for boosting performance in applications.
Now in its second rev, the JProbe Suite is an integrated set of tools designed to help developers
debug a wide range of thread, memory, and performance problems in Java applications.
Expanded Product Coverage
Beginning with the July 1999 issue, John K. Waters assumes the rank of Java Report Product Editor.
With John's help, Java Report plans to expand its product section to include more customer stories
and interviews, along with other news and trends going on within the industry. Please direct all news
and product review queries to John's attention.
Todd C. Zino is a project analyst at the National Software Testing Lab in Conshohocken, PA. He can be
contacted at [email protected].
JAVA HAS FINALLY come of age (was there ever any doubt that it would?), carried along by a
veritable flood of new JavaBeans products that are taking this dynamic and flexible technology where no
language has gone before. Now we are seeing the emergence of sophisticated performance utilities
that have long been a staple of the mission-critical C++ developer's arsenal. The KL Group has
integrated the first wide sweep of these utilities into JProbe, a product suite that includes
profiling, memory debugging, code coverage, and thread analyzing tools.
JProbe 2.0 is packaged as a suite with three separate components: a Profiler, Coverage tools, and
a Threadalyzer tool. Each component of the suite bears a common two-pane browser interface with
the standard debugger stop/start/run toolbar. The I/O premise for each component is based on
"snapshots," which are binary files that store information relevant to the runtime applet/class
being examined. This snapshot model allows cumulative results to be saved in mid-test and
reopened at a later time. JProbe operates on the bytecode class files themselves, rather
than on the source code, making lack of the source code a non-issue if third-party classes
come into the picture. Each of the product's utilities begins testing by running the application
and letting JProbe automatically record its execution details in the browser—a huge step
beyond the painful days when developers entered the information in the code manually.
Code Coverage Versus Code Profiler
Average developers may not be familiar with pricey performance tools like JProbe, so some clarification of
terminology is in order. The terms code coverage and code profiler often are confused.
Both, in fact, began life as obscure command-line appendages that worked in tandem with inserted
referencing tags within code. When invoked, the debugger-like utilities would give detailed
feedback to help developers iron out quirks. Today, however, the tools serve very different
functions. "Code coverage" refers to the process of traversing and checking every branch created
by if statements and their ilk to ensure that every possible line of execution everywhere in
the program is, in fact, executed ("covered") and tested for bugs. The "code profiler" is more of a
performance and runtime monitor that gives detailed information about object references, memory
usage, and heap/register allocation at any given point during the program's execution.
The JProbe Profiler is easily the most sophisticated and versatile tool of the suite. It includes
functionality for memory debugging and for performance monitoring, which features operate independently
of one another. The purpose of Profiler is to calibrate and monitor the low-level memory heap and
call-execution time for each line of functionality in the code. Performance or heap snapshots can
be scheduled to occur at intervals or may be manually taken. These snapshots provide the developer
with hard statistics about where execution time and unneeded object references might be bogging
down program efficiency. The results yield a call graph (Figure 1) with color-gradient scores
that track class/method propagation. Clicking any node in this graph produces a detailed summary
in tabular form with cumulative time, method time, cumulative and method objects, and percentage
scores. The heap monitor is a line graph with color-coding for total size versus percentage
occupied. At each snapshot interval, the list of allocated and referenced objects and their sizes
can be accessed.
Figure 1. JProbe's profiler gives the developer graphical information on real-time memory and
Although this description may make all of this seem overwhelming, particularly for programmers who don't
usually get into heavy debugging, the presentation here is visually intuitive, and couldn't be
clearer—and has yet to be done better in any other application.
The JProbe Coverage component works by running through the program while tracking the execution path
through the code. When the program ends or is stopped prematurely, Coverage displays each class and
method in a hierarchical table (Figure 2) organized within collapsible trees. For each item, the table
displays total calls, methods hit/missed, lines hit/missed, and percentage calculations for all
relevant data. The browser allows for quick rerun and "merging" of multiple snapshots garnered
from repeated execution of all paths in a Java application. For any granular element in the browser,
double clicking jumps directly to the source code. Double click on the original source code and a
find file dialog box appears asking the user to locate the source code, overcoming discrepancies
of source/bytecode paths.
Figure 2. JProbe Coverage displays statistics about which lines of code were actually run.
Another noteworthy feature of JProbe Coverage is its handling of filters, which allow for inclusion
and exclusion of global package/class/native invocations. This feature allows the developer to
constrain the call propagation to the relevant bits only; most JDK and third-party working libraries
need not be reported for Coverage.
JProbe Threadalyzer is a thread debugger that targets common problems within multithreaded
applications, such as concurrency issues, deadlocks, and data race conditions. The Threadalyzer
tool is less sophisticated visually, but none the worse for it. The interface is a wonderfully
simple list of all thread events, with problems reported in bold. This list gives the developer
not only an above-average accounting of all running threads and their read/write actions on
critical data at any time, but also spots and explicitly reports the gamut of classic thread
bugs: Access Anomaly, Contention, Race Condition, Mutex Lock, Livelock, Dormancy, Deadlock,
Thread stall, and Data Races. When and if any such cases are found, a double click yields a
detailed report on the runtime objects affected and a location in the source code, if available.
Although Java's thread simplicity over that of C++ has resulted in a lot of modern IDEs including
thread browsers in the debugging feature, this is by far one of the more "intelligent" and
informative implementations currently available.
The JProbe Suite comes in a professional edition, which, along with the basic executable operation
of each of the suite's utilities, enables local or remote monitoring through TCP. A command-line
jplauncher executable makes this possible, and is bolstered by an attach remote menu feature
in the apps themselves. The main purpose of remote monitoring, particularly with profiling and
threads, is to provide a means of testing Middleware and server-side binaries that have no
frontends. Because this is where Java is really proving itself, thread and memory heap issues
are of utmost importance-and hardest to nail down in such an environment. The advantage really
begins to show with periodic snapshots automated to probe for memory bottlenecks, which only
develop over time.
Still, the product isn't perfect. The setup is something of a battle, and the documentation isn't
much help. (Just which machine should be "remote" and which should be "local" is not clear from
the manual.) Some parameterized scripting is necessary on the server side, and any server-side
Java tested must conform to Sun's servlet standard and be invoked with one of the many servlet
engines available (Java Web Server, Netscape Enterprise, JRun, and WebLogic are supported in this version).
Although JProbe has been deployed in executable wrappers, the user interface is written entirely
in Java, which is both good and bad. Java's multiple-platform support and ability to show dynamic
graphs is a real plus, but in some operations, performance slows noticeably. The somewhat
whimsical user-defined interface choices among "metal," "Windows," and "native" look-and-feel
do nothing to compensate for performance lags. The usually simple process of locating and saving
files is particularly unforgiving, given that the long delay was to invoke a "Javafied" take
on the standard "open file" dialog window. However, what the interface lacks in speed it makes
up for in extremely detailed consistency that makes use of all the bells and whistles that
demystify utilities like this (context menus, tool tips, double-click handling, etc.).
As for the versatility itself, the only thing inherently lacking is some way of controlling stepwise
program execution. Whether monitoring threads, gathering heap/execution efficiency, or examining coverage,
it seems as though stepwise line-by-line execution normally found in debuggers would be of help.
Although this may foul up cumulative time figures in the Profiler, it might also give the developer
a chance to figure out where the program is at any given breakpoint and what has been covered (and
to what level of efficiency). With such
a feature, JProbe could easily replace the need for any Java IDE debug, because it already gives
such detailed statistics and runtime access to source code. Currently, the closest thing to such
an implementation is in Profiler's ability to earmark checkpoints for memory heap that will be
displayed after the fact.
Overall, the JProbe Suite is a great product, but it and products like it may be disappearing in
the future. IDE makers everywhere are scrambling to pack as many features as possible into their
products—including debuggers and performance enhancers. Currently, Rational Software has made
one of the only other noteworthy strides into packaging a profiler and coverage tool together with
its Pure line.
There is little doubt that JProbe is a clear leader in providing these sophisticated utilities.
But the KL Group might want to consider finding a way to merge its suite into a leading IDE. They
might also consider building an editor and project manager into JProbe and offering it as a
comprehensive, if expensive, solution for serious developers.