Byron Kiourtzoglou

About Byron Kiourtzoglou

Byron is a master software engineer working in the IT and Telecom domains. He is always fascinated by SOA, middleware services and mobile development. Byron is co-founder and Executive Editor at Java Code Geeks.

Using FindBugs to produce substantially less buggy code

Some time ago a user of Java-monitor, the forum of our JCG partner, Kees Jan, spotted that his system was forcing a large number of full Garbage Collections despite the fact that the overall memory utilization was low. A rough estimation for the cause of the problem suggested a potential call to System.gc() performed by one of the libraries in use. Lets see what our partner has to say about clarifying similar issues in order to produce substantially less buggy code.

… It did occur to me that there is a tool that could have helped with the System.gc() issue. It is aptly named FindBugs. Actually, there are several (PMD and CheckStyle being other, similar tools), but FindBugs is nice because you don’t actually need the application’s source code to check it for bugs. All you need are the JAR files and/or class files. Another great feature is that each report is documented very well. You don’t just get vague warnings that you sort-of give up on after a few minutes, but you can find an explanation for each warning on-line.

Here is a sample output of FindBugs, when you would run it against Java-monitor’s probe.

$ findbugs -textui -effort:max java-monitor-probes/build/WEB-INF/classes
The following classes needed for analysis were missing:
  javax.servlet.http.HttpServlet
  javax.servlet.Filter
  javax.servlet.http.HttpServletResponse
  javax.servlet.ServletException
  javax.servlet.ServletConfig
  javax.servlet.FilterConfig
  javax.servlet.ServletRequest
  javax.servlet.ServletResponse
  javax.servlet.FilterChain
Missing classes: 7

From this report you can see that FindBugs cannot find any issues with the code itself. There are some classes that the code depends on. These were not included in the analysis. Since these are all Sun-provided classes I presume them to be bugfree. *cough*

Anyway. Let’s make the analysis a bit more juicy. Here is the output when running FindBugs against the well-known MySQL JDBC driver. I’m sure that many of you use it in production today. This code produces significantly more results and FindBugs takes a while to analyse the whole package. I have shown only a few lines of the 154 warnings.

$ findbugs -textui -effort:max mysql-connector-java-5.1.5-bin.jar 
  ......
H C NP: Method call in com.mysql.jdbc.profiler.ProfilerEvent.pack() passes null for unconditionally dereferenced parameter of writeBytes(byte[], byte[], int)  Method invoked at ProfilerEvent.java:[line 375]
  ......
M D NP: Possible null pointer dereference of s1 on path that might be infeasible in com.mysql.jdbc.ConnectionImpl.nullSafeCompare(String, String)  Dereferenced at ConnectionImpl.java:[line 341]
  ......
M C NP: Method call in com.mysql.jdbc.DatabaseMetaData.getInstance(ConnectionImpl, String) passes null for unconditionally dereferenced parameter of new DatabaseMetaData(ConnectionImpl, String)  Method invoked at DatabaseMetaData.java:[line 632]
  ......
H S SQL: Method com.mysql.jdbc.DatabaseMetaData.getColumnPrivileges(String, String, String, String) passes a nonconstant String to an execute method on an SQL statement  At DatabaseMetaData.java:[line 2156]
H S SQL: Method com.mysql.jdbc.DatabaseMetaData.getTablePrivileges(String, String, String) passes a nonconstant String to an execute method on an SQL statement  At DatabaseMetaData.java:[line 4638]
M S SQL: Method com.mysql.jdbc.ConnectionImpl.setSessionVariables() passes a nonconstant String to an execute method on an SQL statement  At ConnectionImpl.java:[line 5074]
  ......
M M IS: Inconsistent synchronization of com.mysql.jdbc.CallableStatement.outputParameterResults; locked 50% of time  Unsynchronized access at CallableStatement.java:[line 1948]
M M IS: Inconsistent synchronization of com.mysql.jdbc.StatementImpl.wasCancelledByTimeout; locked 83% of time  Unsynchronized access at PreparedStatement.java:[line 1756]
  ......
Warnings generated: 154
  ......

Learning to read the output of FindBugs takes a little time. What I do is just work through a certain error or warning when I’m bored or frustrated with the code that I should be writing. It’s my procrastination work. :-)

I have only picked out the things that as a developer strike me as problematic: “passes null for unconditionally dereferenced parameter”. Eek. NullPointerException anyone? Of course, this could well be test code, or even unused code that is still under development. How about this: “passes a nonconstant String to an execute method on an SQL statement”. Hmm. If left unchecked, this could be a vector for an SQL injection vulnerability.

I said earlier that FindBugs does not require you to have access to the source code of an application to find bugs in it. Just for laughs, let’s have a look at one of the cornerstones of our Java EE application servers: The Oracle JDBC driver.

$ findbugs -textui -effort:max ojdbc6.jar
  ......
M B Dm: oracle.sql.ConverterArchive.openArchiveforRead() invokes System.exit(...), which shuts down the entire virtual machine  At ConverterArchive.java:[line 375]
M B Dm: oracle.sql.ConverterArchive.closeArchiveforRead() invokes System.exit(...), which shuts down the entire virtual machine  At ConverterArchive.java:[line 390]
  ......
M B ES: Comparison of String objects using == or != in oracle.jdbc.connector.OracleConnectionRequestInfo.equals(Object)   At OracleConnectionRequestInfo.java:[line 104]
  ......
H C IL: There is an apparent infinite recursive loop in oracle.jdbc.rowset.OracleCachedRowSet.updateBlob(int, InputStream, long)  At OracleCachedRowSet.java:[line 6365]
H C IL: There is an apparent infinite recursive loop in oracle.jdbc.rowset.OracleCachedRowSet.updateClob(int, Reader, long)  At OracleCachedRowSet.java:[line 6445]
H C IL: There is an apparent infinite recursive loop in oracle.jdbc.rowset.OracleCachedRowSet.updateNClob(int, Reader, long)  At OracleCachedRowSet.java:[line 6535]
  ......
Warnings generated: 1028
  ......

That driver produces no less than 1028 warnings. Wow. I’m not suggesting that the Oracle JDBC driver is actually a bad piece of code. I just find that it smells a little. :-) Oracle’s developers might want to have a crack at resolving the findbugs-reported warnings. There are many little performance and stability suggestions in there.

And yes: findbugs checks for uses of System.gc().

PS. Please be aware that I used FindBugs 1.3.7. This version of FindBugs has a bug that causes it to generate false positives for cleaning up database resources.

PPS. Who am I kidding: I do think that the Oracle driver is bad. Infinite loops? System.exit()? Please.

Always help a … coder in need ;-)

Byron

Related Articles:

Related Whitepaper:

Software Architecture

This guide will introduce you to the world of Software Architecture!

This 162 page guide will cover topics within the field of software architecture including: software architecture as a solution balancing the concerns of different stakeholders, quality assurance, methods to describe and evaluate architectures, the influence of architecture on reuse, and the life cycle of a system and its architecture. This guide concludes with a comparison between the professions of software architect and software engineer.

Get it Now!  

One Response to "Using FindBugs to produce substantially less buggy code"

Leave a Reply


− 1 = three



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

15,153 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books