Sounds like it should be simple, right?
And the reality is, in small programs, or stand-alone client applications, it really isn’t a big issue. But in large server-side applications, Denial of Service (DoS) attacks from the outside are a real and constant threat, so why would anybody want to continue running the risk of being their own DoS vector, even without a bad guy in the picture?
Code review and runtime analyzers can certainly be applied to this problem, as can the ever popular mantra of continuing education. But while code review remains expensive to implement well, and runtime analyzers are completely dependent on the code being exercised in every possible way that might occur in “real life,” and continuing education, whilst laudable, can’t possibly stop the “palm to forehead” mistakes developers introduce to their code all the time, there is a very real and easily available solution at hand.
Source Code Analysis (SCA), also known as static analysis, is a technique that’s quickly becoming prevalent in professional development environments. Unlike runtime analysis tools, such as profilers, memory leak analyzers, or code coverage analyzers, source code analysis doesn’t require the code to be executed in order to do its job. Much like a normal compiler, the source code analyzer “builds” your software and produces an executable representation. In the case of javac, that representation is byte code. SCA tools, on the other hand, produce databases that are analyzed for incorrect behavior.
In the context of the design pattern, the SCA tool is going to be used to find resource allocators that are allowed to decrement their reference count to zero before being explicitly closed.
In order to do so, the tool must be able to apply several different techniques in analyzing the code at hand, namely control flow and data flow. In other words, the ability to understand real code paths from paths that can’t happen, and the ability to project object lifetime down each of those real code paths, looking for situations that match the problem domain.
The first place to start with any tools-based project is, of course, in the open source domain. Luckily, SCA has a
very able representative in that community called FindBugs—there are others, of course—but in general
they are not as capable, or not focused on the kind of analysis required for tracking this pattern.
The step into the commercial domain is accompanied not only by financial obligation, but also by a related increase in capability, notably dealing with object lifetime that spans method boundaries, i.e., resource allocator objects that get created in one class and used before collection in another class. This kind of “whole program” or inter-procedural analysis is the domain of prevalent commercial products such as those made by Klocwork and others.
Given that the Java language doesn’t support this important design pattern, and that the mechanisms in place to deal with resource collection can’t be modified to understand resources other than memory, smart developers reach for tools that can help them deliver code that works reliably over the long haul.
Whether it’s open source or commercial, try an SCA tool on your code today. You might be surprised at what you find.