I heard about FindBugs(tm) while listening to one of the Java Posse podcast. Since Hibernate Annotations and Hibernate EntityManager are very close to their respective final releases, I decided to give it a shot.
FindBugs(tm) is basically a static code analyser that tries to find bugs in your code through some pattern recognition. I have been working in the past with both static and dynamic code analysers and I have been pretty disappointed by their false positive ratios (basically a non-bug considered as a bug), and the complexity of their set up process. FindBugs was a refreshing experience.
The cool stuff about it is, well, there are several cool stuffs:
- it's a no brainer to set up and run
- the amount of false positive is surprisingly low
- it works at the bytecode level, so you don't have to have the source code (more later)
Set up and Run
I haven't read the documentation, just downloaded the package and run the .bat file. A couple of clicks and I was analysing Hibernate Annotations and Hibernate EntityManager . No fancy Ant integration required (you can, but you don't have to), no fancy IDE dependency (you can, but you don't have to), no fancy command line requiring you to RTFM (you can, ahem you should, but you don't have to). The provided GUI does the job pretty smoothly, even if a package filtering feature would have been really cool (more later).
A pretty low false positive ratio
THE thing that usually kills such a product is the amount of false positive bug claims. You end up scanning hundreds of warnings without paying attention to them and trash the whole product after 30 minutes. FindBugs has a pretty low false positive ratio, which is very good. And if the warning end up being a false positive, there are usually some good reasons that worth a second look at your code. I must admit I am pretty proud of me ;-) Of course in HAN and HEM, I found some bugs and suboptimal constructs (no worries, I fixed them), but much less than my expectations.
Work at the bytecode level
That is probably what makes it easy to use (and hard to develop), FindBugs(tm) works at the bytecode level, not the source level (it highlights the source line if the sources are available). So pointing a jar or a directory containing your compiled classes is enough. Actually what I did, was pointing to my project root directory, and the job was done.
So while analysing Hibernate Annotations and Hibernate EntityManager , I ended up analysing a bunch of jars (Oh Filter, where art thou?), and I can tell you some guys out there should take a look at FindBugs(tm) , this include a bunch of JDBC drivers and well known in-memory Database backed by some big company(ies) ;-)
Give it a try
It's free, it's easy to set up, it's going to take two hours of your time and save you much more.
Mr C.
Matt, running FindBugs on a recent Hibernate 3.2 build gives the following statistics:
Total Bugs: 1494
Bad Practice: 448
Correctness: 18
Internationalization: 55
Malicious code vulnerabilities: 251
Multithreaded correctness: 32
Performance: 41
Dodgy: 649
This is just on the hibernate3.jar, excluding all dependencies.
Dodgy.
Mr C.
'Dead store to local variable' also appears in places where it is not a bug.
I will [re]try pmd (http://pmd.sf.net) sometime.
- warnings related to inefficiency (no real world damage here)
- NPEs (mostly in error cases, so hard to track)
- exception catching misuse
- bugs due to subclassing
These were bugs in rare cases, but still bugs and some of them would have been hard to track.
Mr C.
Of course it cannot predict whether an object will be shared between threads or not, so it doesn't report the case where no synchronization is included at all when it should of been. What I mean is that if only one thread has access to a hashMap, synchronization is not needed. If the hashMap is accessible to multiple threads, then it should be synchronized. Of course you could also use concurrentHashMap (I really like the new memory model changes and concurrency utilities in Java 5).