greetings,
FindBugs release 1.1.0-rc6 is now available at
http://findbugs.sourceforge.net/
The Eclipse plugin is available from the same location.
Alternatively, the Eclipse plugin may also be obtained
from the FindBugs Eclipse plugin update site at
http://findbugs.cs.umd.edu/eclipse
and FindBugs may be run via Java Web Start from
http://findbugs.sourceforge.net/jnlp/findbugs.jnlp (old gui)
or http://findbugs.sourceforge.net/jnlp/gui2.jnlp (new "gui2,"
requires Java5)
I said last time that rc5 would likely be the last
candidate before the final 1.1.0 release. Now
I say the same about rc6. :-)
The most obvious change from rc5 is that gui2
is now the default gui on systems with Java5.
Run "findbugs -gui1" from the shell or dos box
if you want the older gui.
Questions and comments are welcome.
-Brian Cole
Changes since version 1.0.0:
* Overall, the change from FindBugs 1.0.0 to FindBugs 1.1.0 has
been a big change. We've done a lot of work in a lot of areas, and
aren't even going to try to enumerate all the changes.
* We spent a lot of time reviewing the results generated by
FindBugs for open source and commercial code bases, and made a number
of changes, small and large, to minimize the number of false
positives. Our primary focus for this was warnings reported as high
and medium priority correctness warnings. Our internal evaluation is
that we produce very few high/medium priority correctness warnings
where the analysis is actually wrong, and that more than 75% of the
high/medium priority correctness warnings correspond to real coding
defects that need addressing in the source code. The remaining 25%
are largely cases such as a branch or statement that if taken would
lead to an error, but in fact is a dead branch or statement that can
never be taken. Such coding is confusing and hard to maintain, so it
should arguably be fixed, but it is unlikely to actually result in an
error during execution. Thus, some might classify those warnings as
false positives.
* We've substantially improved the analysis for errors that
could result in null pointer dereferences. Overall, our experience
has been that these changes have roughly doubled the number of null
pointer errors we detect, without increasing the number of false
positives (in fact, our false positive rate has gone down). The
improvements are due to four factors:
o By default, we now do some interprocedural analysis to
determine methods that unconditionally dereference their parameters.
o FindBugs also comes with a model of which JDK methods
unconditionally dereference their parameters.
o We do limited tracking of fields, so that we can detect
null values stored in fields that lead to exceptions.
o We implemented a new analysis technique to find
guaranteed dereferences. Consider the following example:
public int f(Object x, boolean b) {
int result = 0;
if (x == null) result++;
else result--;
// at this point, we know x is null on a simple path
if (b) {
// at this point, x is only null on a complex path
// we don't know if the path in which x is null and
b is true is feasible
return result + x.hashCode();
}
else {
// at this point, x is only null on a complex path
// we don't know if the path in which x is null and
b is false is feasible
return result - x.hashCode();
}
FindBugs 1.0 used forward dataflow analysis to determine
whether each value is definitely null, null on a simple path,
possible null on a complex path, or definitely nonnull. Thus, at the
statement where result is decremented, we know that x is definitely
null, and at the point before if (b) , we know that x is null on a
simple path. If x were to be dereferenced here, we would generate a
warning, because if the else branch of the if (x == null) were ever
taken, a null pointer exception would result.
However, in both the then and else branches of the if
(b) statement, x is only null on a complex path that may be
infeasible. It might be that the program logic is such that if x is
null, then b is never true, so generating a warning about the
dereference in the then clause might be a false positive. We could
try to analyze the program to determine whether it is possible for x
to be null and b to be true, but that can be a hard analysis problem.
However, x is dereferenced in both the then and else
branches of the if (b) statement. So at the point immediately before
if (b) , we know that x is null on a simple path and that x is
guaranteed to be dereferenced on all paths from this point forward.
FindBugs 1.1 performs a backwards data flow analysis to determine the
values that are guaranteed to be dereferenced, and will generate a
warning in this case.
* Preliminary support for detectors using the frameworks other
than BCEL, such as the ASM bytecode framework. You may experiment
with writing ASM-based detectors, but beware the API may still change
(which could possibly also affect BCEL-based detectors). In general,
we've started trying to move away from a deep dependence on BCEL, but
that change is only partially complete. Probably best to just avoid
this until we complete more work on this. This change is only visible
to FindBugs plugin developers, and shouldn't be visible to FindBugs
users.
*
Bug categories (CORRECTNESS, MT_CORRECTNESS, etc.) are no
longer hard-coded, but rather defined in xml files associated with
plugins, including the core plugin which defines the standard
categories. Third-party plugins can define their own categories.
*
Several bug patterns have been moved from CORRECTNESS and
STYLE into a new category, BAD_PRACTICE. The English localization of
STYLE has changed from "Style" to "Dodgy."
In general, we've worked very hard to limit CORRECTNESS bugs
to be real programming errors and sins of commission. We have
reclassified as BAD_PRACTICE a number of bad design practices that
result in overly fragile code, such as defining an equals method that
doesn't accept null or defining class with a equals method that
inherits hashCode from class Object.
In general, our guidelines for deciding whether a bug should
be classified as CORRECTNESS, BAD_PRACTICE or STYLE are:
CORRECTNESS
A problem that we can recognize with high confidence and
is an issue that we believe almost all developers would want to
examine and address. We recommend that software teams review all high
and medium priority warnings in their entire code base.
BAD_PRACTICE
A problem that we can recognize with high confidence and
represents a clear violation of recommended and standard coding
practice. We believe each software team should decide which bad
practices identified by FindBugs it wants to prohibit in the team's
coding standard, and take action to remedy violations of those coding
standards.
STYLE
These are places where something strange or dodgy is going
on, such as a dead store to a local variable. Typically, less than
half of these represent actionable programming defects. Reviewing
these warnings in any code under active development is probably a
good idea, but reviewing all such warnings in your entire code base
might be appropriate only in some situations. Individual or team
programming styles can substantially influence the effectiveness of
each of these warnings (e.g., you might have a coding practice or
style in your group that confuses one of the detectors into
generating a lot of STYLE warnings); you will likely want to
selectively suppress or report the STYLE warnings that are effective
for your group.
* Released a preliminary version of a new GUI (known internally
as GUI2 -- not very creative, huh?)
* Provided standard ways to mark user designations of bug
warnings (e.g., as NOT_A_BUG or SHOULD_FIX). The internal logic now
records this, it is represented in the XML file, and GUI2 allows the
designations to be applied (along with free-form user annotations
about each warning). The user designations and annotations are not
yet supported by the Eclipse plugin, but we clearly want to support
it in Eclipse shortly.
* Added a check for a bad comparison with a signed byte with a
value not in the range -128..127. For example:
boolean find200(byte b[]) {
for(int i = 0; i < b.length; i++) if (b[i] == 200) return i;
return -1;
}
* Added a checking for testing if a value is equal to Double.NaN
(no value is equal to NaN, not even NaN).
* Added a check for using a class with an equals method but no
hashCode method in a hashed data structure.
* Added check for uncallable method of an anonymous inner class.
For example, in the following code, it is impossible to invoke the
initalValue method (because the name is misspelled and as a result is
doesn't override a method in ThreadLocal).
private static ThreadLocal serialNum = new ThreadLocal() {
protected synchronized Object initalValue() {
return new Integer(nextSerialNum++);
}
};
* Added check for a dead local store caused by a switch
statement fallthrough
* Added check for computing the absolute value of a random 32
bit integer or of a hashcode. This is broken because Math.abs
(Integer.MIN_VALUE) == Integer.MIN_VALUE , and thus result of calling
Math.abs, which is expected to be nonnegative, will in fact be
negative one time out of 2 32 , which will invariably be the time
your boss is demoing the software to your customers.
* More careful resolution of inherited methods and fields. Some
of the shortcuts we were taking in FindBugs 1.0.0 were leading to
inaccurate results, and it was fairly easy to address this by making
the analysis more accurate.
* Overall, analysis times are about 1.6 times longer in FindBugs
1.1.0 than in FindBugs 1.0.0. This is because we have enabled
substantial additional analysis at the default effort level (the
actual analysis engine is significantly faster than in FindBugs 1.0).
On a recent AMD Athlon processor, analyzing JDK1.6.0 (about 1 million
lines of code) requires about 15 minutes of wall clock time.
* Provided class and script (printClass) to print classfile in
the human readable format produced by BCEL
* Provided -findSource option to setBugDatabaseInfo
|