Jdj Foss Java Tools


Published on

Published in: Technology, News & Politics
  • Be the first to comment

  • Be the first to like this

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Jdj Foss Java Tools

  1. 1. FEATURE Uncommon Java Bugs Detecting them with FOSS tools by S.G. Ganesh A ny large Java source base can have insidious and work schedules results in code that is often substandard subtle bugs. Every experienced Java programmer and filled with bugs. So, because of practical problems, knows that finding and fixing these bugs can be most code developed in the real world has bugs and it’s difficult and costly. Fortunately, there are a large worthwhile using static analysis tools to find them and fix number of free open source Java tools available that can them. be used to find and fix defects early in the development In this article we’ll see an uncommon defect and intro- lifecycle. In this article, we’ll look at a few examples of duce a tool that detects it. We do this for two reasons: to specific uncommon or unusual defects that can happen in illustrate the kind of unusual problems that can happen code and see how different Java static analysis tools detect in the code and to introduce a FOSS tool that’s suitable for them. detecting this kind of problem. Testing Jlint As software gets more complex and ubiquitous, it What does this program print? becomes more difficult to ensure high-quality code. One common method of finding bugs is testing. But testing class LongVal { can’t cover all paths and possibilities or enforce good public static void main(String[] s) { programming practices. Expert knowledge in the form of long l = 0x1l; manual code review by peers is one of the best ways to System.out.format(“%x”, l); ensure good code quality. Code review is often used as a } mandatory process step for improving the code and for } finding the problems early in the software lifecycle. Since testing and manual code review processes are When you run it, it prints 1, not 11 – why? Let’s use a resource-intensive, it would be helpful to use automated tools to review code. Static analysis tools help consid- Benefits of Using FOSS Java Static Analysis Tools NEED erably in detecting the problems early in the software HEAD lifecycle and help enhance the quality of the code Using Java static analysis tools can significantly improve the quality significantly. of code. Although static analysis tools can’t cover all the paths or pos- SHOT There are many high-quality Java tools available in the sibilities, it provides significant help in providing coverage in detecting open source domain. While it’s true that Java programs problems early in code; such tools can also point out programming prob- S. G. Ganesh is a research don’t suffer from traditional C/C++ problems like memory lems and warn of violations of important and well-accepted program- engineer at Siemens (Corpo- issues and major portability issues, Java software does suf- ming rules and recommendations. rate Technology), Bangalore. fer quality problems like reliability, efficiency, maintain- Using static analysis tools has many attractive benefits. A few of the Prior to Siemens, he worked ability, and security. A brief discussion on benefits of using salient benefits of most of these tools are listed here. Most of the Java at Hewlett-Packard for FOSS Java tools is given in the sidebar. FOSS tools: around five years. His areas Before getting into the meat of the matter, let’s discuss • Can cover code that’s not covered by testing or dynamic analysis of interest are programming why bugs happen. First, it’s important to recognize that • Find many unusual or uncommon bugs that are usually missed languages and compilers. His everyone makes mistakes, even experts. Second, compil- during testing or manual code review latest book is 60 Tips on Ob- ers only check for syntax and semantic violations. Errors • Work even on partial code – fully compilable source isn’t always ject Oriented Programming in language or API use, which manifest themselves as needed (ISBN-13 978-0-07-065670-3) bugs, aren’t detected by compilers: This is left to static • Easily integrate with popular IDEs, so it’s comfortable to use them in published by Tata McGraw- analysis tools and it’s important to use them to detect cod- your favorite environment Hill, New Delhi. ing problems. Third, programmers and engineers are un- • Are usually easy-to-run –with just a button click from your IDE der constant pressure to “get-the-work-done” under tight • Are absolutely free and high-quality sgganesh@gmail.com schedules; working under “almost-impossible-to-meet” 10 May 2008 JDJ.SYS-CON.com
  2. 2. tool to detect the problem. The antic tool (that’s part of JLint) finds it: $antic –java LongVal.java LongVal.java:3:26: May be ‘l’ is used instead of ‘1’ at the end of integer constant The programmer, possibly by mistake, typed ‘l’ (English letter l) instead of ‘1’ (number one)! long l = 0x1l; To avoid this problem, it’s best to use ‘L’ (upper case letter L) as the suffix for long constants instead of ‘l’ (lower case letter l). Antic is part of the Jlint tool that’s meant to find prob- Figure 1 FindBugs detects the check-for-equality-to-NaN problem lems related to C syntax. There are quite a few coding problems that are common to languages that use C-like syntax. The problem we saw now is just one such problem. Jlint ferrets out Java inconsistencies and bugs. It’s not a very sophisticated tool and if you don’t have experience using static analysis tools, JLint is a good tool to start with. Antic works on Java source files and Jlint works on Java class file builds. It’s a command line tool and easy-to-use. It’s available at http://jlint.sourceforge.net. Figure 2 Test.java program results in NullPointerException FindBugs What does this program print? class NaNTest { public static void main(String[] s) { double d = getVal(); if(d == Double.NaN) System.out.println(“d is NaN”); } Figure 3 The DeadLock.java program results in a “deadlock condition” private static double getVal() { return Double.NaN; } PMD } What’s wrong with the program in Listing 1? If you try to run it (as shown in Figure 2) you’ll get a NullPointer- You might be surprised to find that it doesn’t print any- Exception! thing! What went wrong? The FindBugs tool detects the What could have gone wrong? PMD detects it and warns problem and warns us about it (see Figure 1). of the problem: The bug is that the condition (NaN == NaN) evaluates to false! In the condition (d == Double.NaN), this code $ pmd Test.java text design checks to see if a floating-point value is equal to the spe- Test.java:3 Overridable method ‘foo’ called during object con- cial “Not A Number” value. The IEEE 754 floating-point struction standard provides the special semantics of NaN: no value is equal to NaN, including NaN itself. So, the check (d == The bug in this program is that the constructor of Double.NaN) always evaluates to false. The correct check the Base class calls an overridden method. Construc- to use is the condition check Double.isNaN(x). tors don’t support runtime polymorphism since derived The FindBugs tool detects this problem and aptly objects aren’t constructed when the base class constructor names it “Doomed test for equality to NaN”. executes. The virtual method foo is called from the base The FindBugs tool is excellent. It detects correctness class constructor. Since foo is overridden, the overridden problems, multithreading issues, performance problems, foo calls the toString method from I, which isn’t initial- and bad practices. It has less false positives and warns ized yet (note that i gets initialized only after the Derived of only critical or important problems that are likely constructor has completed executing). Because of this, the to be actual defects in code. So, if you’re pressed for time program terminates with a NullPointerException. For this and want to look at only important problems, this tool reason, it’s not a recommended programming practice to will suit you. It runs on Java class/jar files, so no Java call overridable methods from constructors. source files are needed to use it. And it runs in a nice The PMD tool checks for problems like possible bugs, standalone GUI. You can download it at http://findbugs. design rule violations, duplicates, sub-optimal or dead sourceforge.net/. code, suggestions for migration to newer JDK versions, JDJ.SYS-CON.com May 2008 11
  3. 3. FEATURE J2EE, JavaBeans, JSP, and JUnit rules. It works on Java Acquiring multiple locks is not a recommended program- source files and can be used from command lines. Plug- ming practice. However, it’s often required in practice, so ins for popular IDEs like Eclipse, JBuilder, and JCreator when we need to acquire multiple locks, we should ensure are also available. You can download it from http://pmd. that we acquire them in the same order in the code. sourceforge.net/. Alternatively, we can consider using non-blocking locks when we attempt to acquire multiple locks. The tryLock meth- QJ-Pro od in the java.util.concurrent.locks.Lock interface provides What’s wrong with the program in Listing 2? this ability. It’s also recommended to release locks quickly and It’s likely that the program will hang after running success- not hold the locks for a long time; so, it’s not recommended to fully for few times as shown in Figure 3; in other words, this use sleep/wait methods after acquiring a lock; consider using program can lead to a “deadlocked condition” (the program the wait/notify mechanism instead to avoid deadlocks be- actually hint at this: the name of the class is Deadlock!). cause of holding a lock for a long time waiting for a condition The QJ-Pro tool detects it as shown in Figure 4. to occur. The bug in this code is that the code acquires two locks in The QJ-Pro tool checks for problems like conformance to opposite order; and after that a sleep/wait method is called coding standards, coding best practices, misuse of features, – this condition will usually result in a deadlock. and APIs. It gives lots of violations by default, so you’d have to Locks are the basic Java synchronization mechanism. Using spend some time selecting the list of rules you want to run for locks ensures exclusive ownership for a thread while executing your project. It works on Java source files and is easy-to-use in a critical section. Incorrect use of synchronization can lead to its standalone GUI version (shown in Figure 5). You can use its deadlocks. plug-ins with popular IDEs like Eclipse, JBuilder, JDeveloper A big problem with deadlocks (as with most multithreading plug-ins or Ant. You can get QJ-Pro from http://qjpro.source- problems) is that deadlocks are “non-deterministic” – they forge.net/. need not reproduce consistently, and so it’s difficult to detect, reproduce, and fix problems related to deadlocks. Other Tools Acquiring multiple locks is prone to deadlock, particularly Other than the four tools covered here – Jlint, FindBugs, if not done in the same order or if the sleep()/wait() in the PMD, and QJ-Pro – there are many other FOSS tools avail- Thread is called after acquiring locks. In this program, foo and able. For example, CheckStyle checks for adherence to coding bar acquire locks in opposite order and call sleep(). Hence standards such as Sun’s. You can get it from http://checkstyle. deadlock occurs. sourceforge.net/. JCSC (Java Coding Style Checker) checks for coding style adherence and for common bugs. You can get it at http://jcsc.sourceforge.net/. There are many more useful tools like Classycle, Condenser, DoctorJ, and JarAnalyzer. More in- formation and links on Java tools is provided in the Resource section. Conclusion We saw four specific static analysis tools that can be used to detect not-so-common defects in code. They are free, easy-to- integrate with IDEs, and easy-to-use. It’s highly recommended to use such tools to improve the quality of the software by detecting and fixing bugs early in the software lifecycle. Figure 4 QJ-Pro detects deadlock because of acquiring multiple locks Resources • If you’re interested in a list of the Java FOSS static analysis tools available, check http://java-source.net/open-source/ code-analyzers. • “A Comparison of Bug Finding Tools for Java” by Nick Rutar, Christian B. Almazan, and Jeffrey S. Foster from the University of Maryland provides a detailed technical comparison of Bandera, ESC/Java, FindBugs, JLint and PMD tools. See http://www.cs.umd.edu/~jfoster/papers/ issre04.pdf. • If you’re using Eclipse, it’s very convenient to use Java tools as plug-ins. The list of available plug-ins for Java is at http://www.eclipseplugincentral.com/Web_Links-index- req-viewcatlink-cid-14-orderby-rating.html. • The book Java Puzzlers: Traps, Pitfalls, and Corner Cases by Joshua Bloch and Neal Gafter covers many interesting bugs that can happen in code. Check the link http://www. Figure 5 QJ-Pro detects deadlock because of acquiring multiple locks javapuzzlers.com/. 12 May 2008 JDJ.SYS-CON.com
  4. 4. Listing 1 synchronized(That.class) { class Base { Thread.currentThread().sleep(10); public Base() { } foo(); } } } public void foo() { public static void bar() throws InterruptedException { System.out.println(“In Base’s foo “); synchronized(That.class) { } synchronized(This.class) { } Thread.currentThread().sleep(10); } class Derived extends Base { } public Derived() { } i = new Integer(10); } public void run() { public void foo() { try { System.out.println(“In Derived’s foo “ foo(); + i.toString()); bar(); } } catch (InterruptedException e) { private Integer i; System.out.println(“Caught interrupted } exception”); } class Test { } public static void main(String [] s) { } new Derived().foo(); } class DeadLock { } public static void main(String []s) { DoSynchronize pc = new DoSynchronize(); Thread t1 = new Thread(pc); Listing 2 class This {} Thread t2 = new Thread(pc); class That {} t1.start(); t2.start(); class DoSynchronize implements Runnable { } public static void foo() throws InterruptedException { synchronized(This.class) { } JDJ.SYS-CON.com May 2008 13