Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

JVM Languages

Examining Enerjy's Java Toolkit

Source Code Accompanies This Article. Download It Now.


July, 2005: Examining Enerjy's Java Toolkit

Ryan is a lead systems engineer at E. & J. Gallo Winery. He can be contacted at [email protected]


Developing Java applications for business environments is a challenging task. Among the issues that come up in day-to-day activities are coding conventions, patterns usage, standard best practices application, and source-code style or layout. These issues are not only difficult to tackle with disparate teams of developers, but also with teams from one's local area.

Coding standards and best practices are only the tip of the iceberg for Java development issues. How do we, as Java developers, tackle the esoteric "performance" issues from which applications suffer? How do we ensure that applications are working correctly, performing to our predefined SLAs, and really doing what we expect? To address these issues, I've turned to a suite of tools from Enerjy Software (http://www.enerjy.com/) that includes a code analyzer, performance management/profiling tool, memory profiler, and thread analyzer. In this article, I examine each tool, providing an overview of their functionality and insight into how they work.

Before diving into the tools, however, it is worth noting that I use Eclipse as my IDE of choice, and develop a variety of applications, ranging from basic web applications using JSP and Servlet technologies to full-scale enterprise integration using JMS and similar technologies. Included in my daily routine is time devoted to testing applications, as well as mentoring colleagues on testing, tuning, and debugging applications and code.

As with any software, installation is the first encounter with Enerjy tools. Enerjy has done a great job setting up the installer to work with Eclipse. While I can't speak to its integration into JBuilder or other IDEs, integration and installation into Eclipse and WebSphere Studio Application Developer (WSAD) is first rate. The installation process is straightforward and self explanatory. The only hiccup I experienced with the installer was when the PATH variable wasn't modified correctly on a computer, causing the profiling tools to fail during startup. However, the error message produced by the profiler was descriptive enough to address the issue without needing to call technical support.

Code Analyzer

For me, the most valuable tool in the Enerjy toolkit is the Code Analyzer. It's ironic that the simplest piece of the suite is the one you can't live without. Code Analyzer is a basic code-analysis tool, complete with autocorrect, custom error levels, and other configurable rules that enable the use of open-source and "old" code without major headaches. The tool integrates nicely into Eclipse and installation is a snap. This is important because my development teams share a set of rules that we have customized using the external rules file feature of the analyzer.

Using Code Analyzer is simple (it just plugs into the IDE) and rule configuration is straightforward; see Figure 1. With the "analyze on save" enabled, you don't have to do much to have the tool check out your code. Even with all of these features, the real benefit to me is that the tool can be leveraged to provide a clean and efficient methodology to implement standard coding practices.

Integration into an IDE is great, but if a tool doesn't integrate into a build tool, it's useless for enforcement of standards or policies. Enerjy fits nicely into the Apache Ant platform, and works along with most build processes. It takes in a predefined rule configuration file (which can be shared between Ant and the IDE). The tool double checks all of the code that is about to be deployed before Ant finishes the build. With the configurable error levels, it is simple to force an entire build to fail if selected rules are violated. This is a great asset. With the simple reporting capabilities included with Code Analyzer, the development team can see immediately what warnings or errors—if any—were introduced into the last build. Couple this with the ability to predefine error levels for each rule and you have an easy-to-use, automated process to ensure that policies are followed and that applications are developed to standards.

For all of the nice things you can do with Code Analyzer, there is one thing of which you should be aware. The tool includes a feature that basically fixes some source code if it is in violation of a predefined set of correctable rules. Generally speaking, running this feature is safe. However, during early stages of development, it can cause headaches. Specifically, when methods are stubbed out and not yet using instance variables, the tool optimizes the source and makes those methods static.

Performance Profiler

Standards and best practices are great, but when they can be enforced quickly and easily, they're even better. However, there are other key issues that development teams need to address on a day-to-day basis—such as tracking and managing application performance.

As developers, we need to ensure that applications are doing what we want them to do, at the time that we want them to do it, as efficiently as possible. Application development can be a difficult task, especially as applications become more and more complex. Simple things, such as reading from a file, to difficult tasks, such as calculating the desired product for the next five years, can produce major performance bottlenecks. Enerjy provides a tool to address these issues—the Performance Profiler.

The main job of the Performance Profiler is to watch code-path execution and return statistics about the run. Given the nature of the applications many enterprises develop, performance is key. This tool steps up to the job. While the analysis is simple (essentially, a percentage of time spent across the code path), it gives you a good visual picture of how the application is really performing. For instance, Figure 2 shows the result of a performance analysis on Listing One, which is sample code provided with the Performance Profiler. Even without a lot of searching, you can see the readRecordsFromFile(String) method is using an exceptional amount of processing time—54.63 percent of the time to be exact. By clicking into that method name, the tool takes you to the exact line of code (again, the benefits of tight IDE integration), letting you inspect the code and find the issue. As you can see, the problem is that the program is reading a file one line at a time; after fixing the issue, simply rerun the analysis to verify the correction.

Overall, the Performance Profiler provides some good utilities for performance metrics. That said, it is not a full-blown performance suite. Recommendations on what is actually wrong with the code are not provided. It simply gives you visibility into what the code is doing. In other words, if you are looking for some sort of recognition engine for common performance-reducing patterns, you won't find it in the Enerjy Performance Profiler. On the other hand, if you are looking for a picture of the application's performance, with tight integration into the top IDEs, this tool fits the bill nicely.

Memory Profiler

The Memory Profiler tool is not for beginning Java developers who haven't grasped the details of hardcore Java issues like memory management. To me, this is one of the best memory profilers available. Its footprint is light, overhead is low with basic profiling, and when turned up to do hardcore profiling, it gives some amazing statistics.

For instance, the Memory Profiler (Figure 3) lets you visualize what your memory footprint looks like. You can see the heap grow as the application runs and watch garbage collection take place. In addition, the tool even looks for object leaks. In fact, the ability to identify object leaks is probably the Memory Profiler's most valuable feature. Object leaks can produce some strange results in applications. They are hard to reproduce and can bring production systems to their knees. Using this profiling tool judiciously can reduce these issues. In Listing Two (also provided with the tool), I enable full tracing—including leak detection—on-the-fly using the On-The-Fly profiling settings. Clicking the OK button starts the profile (Figure 4). Looking at the results of the profile in Figure 5, it is obvious that there is a memory leak, actually a few of them. The Memory Profiler lets you click into the code and take a peek.

Although the tool takes you to the exact line of code that is the leak culprit (in bold), this is not really where this leak resides. (Remember, memory leaks are tricky!) The leaked object, in this case, is the FolderEnumerator firstItem; however, the object is being leaked because the reference to the head of the queue is not being properly cleaned up when the queue is processed (via the WorkQueue.remove() method); see Listing Three.

After fixing the WorkQueue code by adding the line queue[head] = null; as indicated by the comment, you can avert the sometimes serious issues this leak would have created in the application, such as potentially bringing down production systems and stopping the business.

Thread Profiler

The Thread Profiler (Figure 6) provides snapshots of thread runs, giving you immediate insight into what the application is actually doing at runtime on a thread-by-thread basis. In other words, the tool shows you what the application is really doing, not just with log files and System.out.println(), but with pictures, graphs, and interactive tools. With this view of the application, you can see lots of different things, all related to threading—waits, deadlocks, contentions, and the like.

But seeing the picture is only half of the battle. Actually getting into the code is where the Thread Profiler provides value and, again with the tight integration into IDEs, you can click on the picture and the tool opens the source, highlighting the exact line of code that was executing. Listing Four is the code causing the issues in the Enerjy sample (simply right-click GoTo Source on the deadlock to reach the code).

Just as with memory leaks, deadlocks can be tricky to track down. The deadlock in Figure 6 occurred because the objects (from and to) are being synchronized, and they might be done in a different order. To fix the problem, add Listing Five before the synchronized(from) line. Then just rerun the analysis to verify that the change actually corrected the issues in the code. Figure 7 presents the new results showing a successful run of the sample threaded application.

Conclusion

Overall, the Enerjy tool suite provides valuable insight and enforcement capabilities. Having the ability to produce reports for build managers to view (in the case of coding rule violations), to debugging multithreaded applications visually, the tools provide immediate benefits on a day-to-day basis.

DDJ



Listing One

protected List readRecordsFromFile(String fileName) throws IOException {
   FileInputStream fis = new FileInputStream(fileName);
   List records = new ArrayList();      
   ...
   int ch = 0;
   int colNum = 0;
<b>   while (-1 != (ch = fis.read())) {</b>
      if (ch == '\t') {
      ...
      }
   }
   return records;
}
Back to article


Listing Two
    ...        
<b>FolderEnumerator firstItem = new FolderEnumerator(this, new File(directory));</b>
   workQueue.add(firstItem);
   // Keep processing work items until the queue is empty
   while (!workQueue.isEmpty()) {
      WorkQueue.IWorkItem item = workQueue.remove();
      item.doWork();
   }
 ...
Back to article


Listing Three
    
public IWorkItem remove() {
   if (head == tail) {
      return null;
   }
   IWorkItem item = queue[head];
<b>   //The queue head should be cleaned up at this point.</b>
   head++;
   if (head == queue.length) {
      head = 0;         
   }
   return item;
}
Back to article


Listing Four
synchronized (from) {
        if (from.amount < amount) {
            return;
        }
<b>        synchronized (to) {</b>
            to.amount += amount;
            from.amount -= amount;
            try {
                //TSA-JAVA0087: Sleep okay here
                Thread.sleep(XFER_OVERHEAD);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
Back to article


Listing Five
if (from.name.compareTo(to.name) > 0)  {
   // Swap to ensure same order for locks below
   BankAccount temp = from;
   from = to;
   to = temp;
   amount = -amount; 
}
Back to article


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.