This is a slow detector.
]]>java.net.URL
resolve
the domain name. As a result, these operations can be very expensive, and this
detector looks for places where those methods might be invoked.
]]>
|
and &
instead of
||
and &&
).
]]>
Comparator
.
]]>
java.util.concurrent
)
locks which are acquired, but not released on all paths out of the method.
It is a moderately fast detector. Note that in order to use this
detector, you need to have the java.util.concurrent
package
in the auxiliary classpath (or be analyzing the package itself).
]]>
java.lang.String
)
where comparing reference values is generally an error. It is a slow detector.
]]>
This is a slow detector.
]]>This is a slow detector.
]]>This is a slow detector.
]]>java.lang.Object
to see if the argument's type is related to the collection's
parameter. Arguments with unrelated class types are never going
to be in the collection. For example, if foo
is a
List<String>
and bar
is a
StringBuffer
, the call foo.contains(bar)
will always return false. This is a fast detector.
]]>
FindBugs looks only for the most blatant, obvious cases of HTTP response splitting. If FindBugs found any, you almost certainly have more vulnerabilities that FindBugs doesn't report. If you are concerned about HTTP response splitting, you should seriously consider using a commercial static analysis or pen-testing tool.
]]>FindBugs looks only for the most blatant, obvious cases of HTTP response splitting. If FindBugs found any, you almost certainly have more vulnerabilities that FindBugs doesn't report. If you are concerned about HTTP response splitting, you should seriously consider using a commercial static analysis or pen-testing tool.
]]>FindBugs looks only for the most blatant, obvious cases of relative path traversal. If FindBugs found any, you almost certainly have more vulnerabilities that FindBugs doesn't report. If you are concerned about relative path traversal, you should seriously consider using a commercial static analysis or pen-testing tool.
]]>FindBugs looks only for the most blatant, obvious cases of absolute path traversal. If FindBugs found any, you almost certainly have more vulnerabilities that FindBugs doesn't report. If you are concerned about absolute path traversal, you should seriously consider using a commercial static analysis or pen-testing tool.
]]>FindBugs looks only for the most blatant, obvious cases of cross site scripting. If FindBugs found any, you almost certainly have more cross site scripting vulnerabilities that FindBugs doesn't report. If you are concerned about cross site scripting, you should seriously consider using a commercial static analysis or pen-testing tool.
]]>FindBugs looks only for the most blatant, obvious cases of cross site scripting. If FindBugs found any, you almost certainly have more cross site scripting vulnerabilities that FindBugs doesn't report. If you are concerned about cross site scripting, you should seriously consider using a commercial static analysis or pen-testing tool.
]]>FindBugs looks only for the most blatant, obvious cases of cross site scripting. If FindBugs found any, you almost certainly have more cross site scripting vulnerabilities that FindBugs doesn't report. If you are concerned about cross site scripting, you should seriously consider using a commercial static analysis or pen-testing tool.
]]>this.getClass().getResource(...)
could give
results other than expected if this class is extended by a class in
another package.
]]>
x == 0 || x == 0
). Perhaps the second occurrence is intended to be something else
(e.g., x == 0 || y == 0
).
]]>
putNextEntry()
, immediately
followed by a call to closeEntry()
. This results
in an empty ZipFile entry. The contents of the entry
should be written to the ZipFile between the calls to
putNextEntry()
and
closeEntry()
.
]]>
putNextEntry()
, immediately
followed by a call to closeEntry()
. This results
in an empty JarFile entry. The contents of the entry
should be written to the JarFile between the calls to
putNextEntry()
and
closeEntry()
.
]]>
Number[] arr = new Integer[10];
arr[0] = 1.0;
Consider changing the type of created array or the field type.
]]>Number[] arr = new Integer[10];
arr[0] = 1.0;
Consider changing the type of created array or the local variable type.
]]>Consider changing the type of created array or the method return type.
]]>If all clone() methods call super.clone(), then they are guaranteed to use Object.clone(), which always returns an object of the correct type.
]]>java.net.URI
instead.
]]>
java.net.URI
instead.
]]>
java.lang.String(String)
constructor wastes memory
because the object so constructed will be functionally indistinguishable
from the String
passed as a parameter. Just use the
argument String
directly.
]]>
java.lang.String
object using the
no-argument constructor wastes memory because the object so created will
be functionally indistinguishable from the empty string constant
""
. Java guarantees that identical string constants
will be represented by the same String
object. Therefore,
you should just use the empty string constant directly.
]]>
String.toString()
is just a redundant operation.
Just use the String.
]]>
In the past, situations where people have explicitly invoked the garbage collector in routines such as close or finalize methods has led to huge performance black holes. Garbage collection can be expensive. Any situation that forces hundreds or thousands of garbage collections will bring the machine to a crawl.
]]>java.lang.Boolean
wastes
memory, since Boolean
objects are immutable and there are
only two useful values of this type. Use the Boolean.valueOf()
method (or Java 1.5 autoboxing) to create Boolean
objects instead.
]]>
new Integer(int)
is guaranteed to always result in a new object whereas
Integer.valueOf(int)
allows caching of values to be done by the compiler, class library, or JVM.
Using of cached values avoids object allocation and the code will be faster.
Values between -128 and 127 are guaranteed to have corresponding cached instances
and using valueOf
is approximately 3.5 times faster than using constructor.
For values outside the constant range the performance of both styles is the same.
Unless the class must be compatible with JVMs predating Java 1.5,
use either autoboxing or the valueOf()
method when creating instances of
Long
, Integer
, Short
, Character
, and Byte
.
new Double(double)
is guaranteed to always result in a new object whereas
Double.valueOf(double)
allows caching of values to be done by the compiler, class library, or JVM.
Using of cached values avoids object allocation and the code will be faster.
Unless the class must be compatible with JVMs predating Java 1.5,
use either autoboxing or the valueOf()
method when creating instances of Double
and Float
.
versions instead.
]]> b ? e1 : e2
operator). The
semantics of Java mandate that if e1
and e2
are wrapped
numeric values, the values are unboxed and converted/coerced to their common type (e.g,
if e1
is of type Integer
and e2
is of type Float
, then e1
is unboxed,
converted to a floating point value, and boxed. See JLS Section 15.25.
]]>
new Double(d).intValue()
). Just perform direct primitive coercion (e.g., (int) d
).
]]>
Replace... | With this... |
---|---|
new Integer(1).toString() | Integer.toString(1) |
new Long(1).toString() | Long.toString(1) |
new Float(1.0).toString() | Float.toString(1.0) |
new Double(1.0).toString() | Double.toString(1.0) |
new Byte(1).toString() | Byte.toString(1) |
new Short(1).toString() | Short.toString(1) |
new Boolean(true).toString() | Boolean.toString(true) |
wait()
on a
java.util.concurrent.locks.Condition
object.
Waiting for a Condition
should be done using one of the await()
methods defined by the Condition
interface.
]]>
Random.nextInt(n)
method.
]]>
r
is a java.util.Random
, you can generate a random number from 0
to n-1
using r.nextInt(n)
, rather than using (int)(r.nextDouble() * n)
.
The argument to nextInt must be positive. If, for example, you want to generate a random
value from -99 to 0, use -r.nextInt(100)
.
To fix this problem consider storing the object into the local variable first and save it to the volatile field only after it's fully constructed.
]]>finalize()
method should have protected access,
not public.
]]>
finalize()
methods are useless, so they should
be deleted.
]]>
finalize()
method explicitly negates the
effect of any finalizer defined by its superclass. Any finalizer
actions defined for the superclass will not be performed.
Unless this is intended, delete this method.
]]>
finalize()
method does is call
the superclass's finalize()
method, making it
redundant. Delete it.
]]>
finalize()
method does not make a call to its
superclass's finalize()
method. So, any finalizer
actions defined for the superclass will not be performed.
Add a call to super.finalize()
.
]]>
finalize()
method on an object. Because finalizer methods are supposed to be
executed once, and only by the VM, this is a bad idea.
If a connected set of objects beings finalizable, then the VM will invoke the finalize method on all the finalizable object, possibly at the same time in different threads. Thus, it is a particularly bad idea, in the finalize method for a class X, invoke finalize on objects referenced by X, because they may already be getting finalized in a separate thread.
]]>public boolean equals(Object o) { if (o instanceof Foo) return name.equals(((Foo)o).name); else if (o instanceof String) return name.equals(o); else return false;
This is considered bad practice, as it makes it very hard to implement an equals method that is symmetric and transitive. Without those properties, very unexpected behaviors are possible.
]]>equals()
method, but inherits the normal equals(Object)
method
defined in the base java.lang.Object
class.
The class should probably define a boolean equals(Object)
method.
]]>
equals()
method, that doesn't override the normal equals(Object)
method
defined in the base java.lang.Object
class.
The class should probably define a boolean equals(Object)
method.
]]>
equals()
method, that doesn't override the normal equals(Object)
method
defined in the base java.lang.Object
class. Instead, it
inherits an equals(Object)
method from a superclass.
The class should probably define a boolean equals(Object)
method.
]]>
equals()
.
To correctly override the equals()
method in
java.lang.Object
, the parameter of equals()
must have type java.lang.Object
.
]]>
instanceof
in the determination of whether two objects are equal. This is fraught with peril,
since it is important that the equals method is symmetrical (in other words, a.equals(b) == b.equals(a)
).
If B is a subtype of A, and A's equals method checks that the argument is an instanceof A, and B's equals method
checks that the argument is an instanceof B, it is quite likely that the equivalence relation defined by these
methods is not symmetric.
]]>
Foo
it might check if Foo.class == o.getClass()
).
It is better to check if this.getClass() == o.getClass()
.
]]>
this
object. There might not be anything wrong with
this code, but it is worth reviewing.
]]>
The likely intended semantics are object identity: that an object is equal to itself. This is the behavior inherited from class Object
. If you need to override an equals inherited from a different
superclass, you can use use:
public boolean equals(Object o) { return this == o; }]]>
compareTo()
.
To correctly override the compareTo()
method in the
Comparable
interface, the parameter of compareTo()
must have type java.lang.Object
.
]]>
hashCode()
method but inherits its
equals()
method from java.lang.Object
(which defines equality by comparing object references). Although
this will probably satisfy the contract that equal objects must have
equal hashcodes, it is probably not what was intended by overriding
the hashCode()
method. (Overriding hashCode()
implies that the object's identity is based on criteria more complicated
than simple reference equality.)
If you don't think instances of this class will ever be inserted into a HashMap/HashTable,
the recommended hashCode
implementation to use is:
public int hashCode() { assert false : "hashCode not designed"; return 42; // any arbitrary constant will do }]]>
compareTo(...)
method but inherits its
equals()
method from java.lang.Object
.
Generally, the value of compareTo should return zero if and only if
equals returns true. If this is violated, weird and unpredictable
failures will occur in classes such as PriorityQueue.
In Java 5 the PriorityQueue.remove method uses the compareTo method,
while in Java 6 it uses the equals method.
From the JavaDoc for the compareTo method in the Comparable interface:
It is strongly recommended, but not strictly required that (x.compareTo(y)==0) == (x.equals(y))
.
Generally speaking, any class that implements the Comparable interface and violates this condition
should clearly indicate this fact. The recommended language
is "Note: this class has a natural ordering that is inconsistent with equals."
]]>
hashCode()
method but not an
equals()
method. Therefore, the class may
violate the invariant that equal objects must have equal hashcodes.
]]>
equals(Object)
, but does not
override hashCode()
, and inherits the implementation of
hashCode()
from java.lang.Object
(which returns
the identity hash code, an arbitrary value assigned to the object
by the VM). Therefore, the class is very likely to violate the
invariant that equal objects must have equal hashcodes.
If you don't think instances of this class will ever be inserted into a HashMap/HashTable,
the recommended hashCode
implementation to use is:
public int hashCode() { assert false : "hashCode not designed"; return 42; // any arbitrary constant will do }]]>
equals(Object)
from an abstract
superclass, and hashCode()
from
java.lang.Object
(which returns
the identity hash code, an arbitrary value assigned to the object
by the VM). Therefore, the class is very likely to violate the
invariant that equal objects must have equal hashcodes.
If you don't want to define a hashCode method, and/or don't
believe the object will ever be put into a HashMap/Hashtable,
define the hashCode()
method
to throw UnsupportedOperationException
.
equals(Object)
, but does not
override hashCode()
. Therefore, the class may violate the
invariant that equal objects must have equal hashcodes.
]]>
equals()
.
To correctly override the equals()
method in
java.lang.Object
, the parameter of equals()
must have type java.lang.Object
.
]]>
java.lang.String
objects for reference
equality using the == or != operators.
Unless both strings are either constants in a source file, or have been
interned using the String.intern()
method, the same string
value may be represented by two different String objects. Consider
using the equals(Object)
method instead.
]]>
java.lang.String
parameter for reference
equality using the == or != operators. Requiring callers to
pass only String constants or interned strings to a method is unnecessarily
fragile, and rarely leads to measurable performance gains. Consider
using the equals(Object)
method instead.
]]>
compareTo()
.
To correctly override the compareTo()
method in the
Comparable
interface, the parameter of compareTo()
must have type java.lang.Object
.
]]>
A typical bug matching this bug pattern is forgetting to synchronize one of the methods in a class that is intended to be thread-safe.
You can select the nodes labeled "Unsynchronized access" to show the code locations where the detector believed that a field was accessed without synchronization.
Note that there are various sources of inaccuracy in this detector; for example, the detector cannot statically detect all situations in which a lock is held. Also, even when the detector is accurate in distinguishing locked vs. unlocked accesses, the code in question may still be correct.
]]>notify()
or notifyAll()
was made without any (apparent) accompanying
modification to mutable object state. In general, calling a notify
method on a monitor is done because some condition another thread is
waiting for has become true. However, for the condition to be meaningful,
it must involve a heap object that is visible to both threads.
This bug does not necessarily indicate an error, since the change to mutable object state may have taken place in a method which then called the method containing the notification.
]]>run()
on an object.
In general, classes implement the Runnable
interface because
they are going to have their run()
method invoked in a new thread,
in which case Thread.start()
is the right method to call.
]]>
Non-short-circuit logic causes both sides of the expression to be evaluated even when the result can be inferred from knowing the left-hand side. This can be less efficient and can result in errors if the left-hand side guards cases when evaluating the right-hand side can generate an error.
See the Java Language Specification for details.
]]>See the Java Language Specification for details.
]]>java.lang.Object.wait()
which
is not guarded by conditional control flow. The code should
verify that condition it intends to wait for is not already satisfied
before calling wait; any previous notifications will be ignored.
]]>
To make this more concrete, consider the following classes:
abstract class A { int hashCode; abstract Object getValue(); A() { hashCode = getValue().hashCode(); } } class B extends A { Object value; B(Object v) { this.value = v; } Object getValue() { return value; } }
When a B
is constructed,
the constructor for the A
class is invoked
before the constructor for B
sets value
.
Thus, when the constructor for A
invokes getValue
,
an uninitialized value is read for value
.
foo
will be null.
public class CircularClassInitialization { static class InnerClassSingleton extends CircularClassInitialization { static InnerClassSingleton singleton = new InnerClassSingleton(); } static CircularClassInitialization foo = InnerClassSingleton.singleton; }]]>
java.util.Iterator
interface.
However, its next()
method is not capable of throwing
java.util.NoSuchElementException
. The next()
method should be changed so it throws NoSuchElementException
if is called when there are no more elements to return.
]]>
private static String LOCK = "LOCK"; ... synchronized(LOCK) { ...} ...
Constant Strings are interned and shared across all other classes loaded by the JVM. Thus, this code is locking on something that other code might also be locking. This could result in very strange and hard to diagnose blocking and deadlock behavior. See http://www.javalobby.org/java/forums/t96352.html and http://jira.codehaus.org/browse/JETTY-352.
See CERT CON08-J. Do not synchronize on objects that may be reused for more information.
]]>private static Boolean inited = Boolean.FALSE; ... synchronized(inited) { if (!inited) { init(); inited = Boolean.TRUE; } } ...
Since there normally exist only two Boolean objects, this code could be synchronizing on the same object as other, unrelated code, leading to unresponsiveness and possible deadlock.
See CERT CON08-J. Do not synchronize on objects that may be reused for more information.
]]>private static final Integer fileLock = new Integer(1); ... synchronized(fileLock) { .. do something .. } ...
It would be much better, in this code, to redeclare fileLock as
private static final Object fileLock = new Object();
The existing code might be OK, but it is confusing and a future refactoring, such as the "Remove Boxing" refactoring in IntelliJ, might replace this with the use of an interned Integer object shared throughout the JVM, leading to very confusing behavior and potential deadlock.
]]>private static Integer count = 0; ... synchronized(count) { count++; } ...
Since Integer objects can be cached and shared, this code could be synchronizing on the same object as other, unrelated code, leading to unresponsiveness and possible deadlock.
See CERT CON08-J. Do not synchronize on objects that may be reused for more information.
]]>synchronized() {}
Empty synchronized blocks are far more subtle and hard to use correctly than most people recognize, and empty synchronized blocks are almost never a better solution than less contrived solutions.
]]>A typical bug matching this bug pattern is forgetting to synchronize one of the methods in a class that is intended to be thread-safe.
Note that there are various sources of inaccuracy in this detector; for example, the detector cannot statically detect all situations in which a lock is held. Also, even when the detector is accurate in distinguishing locked vs. unlocked accesses, the code in question may still be correct.
]]>private Long myNtfSeqNbrCounter = new Long(0); private Long getNotificationSequenceNumber() { Long result = null; synchronized(myNtfSeqNbrCounter) { result = new Long(myNtfSeqNbrCounter.longValue() + 1); myNtfSeqNbrCounter = new Long(result.longValue()); } return result; }]]>
foo(17)
, which is defined in both a superclass and in an outer method.
By the Java semantics,
it will be resolved to invoke the inherited method, but this may not be what
you intend.
If you really intend to invoke the inherited method, invoke it by invoking the method on super (e.g., invoke super.foo(17)), and thus it will be clear to other readers of your code and to FindBugs that you want to invoke the inherited method, not the method in the outer class.
If you call this.foo(17)
, then the inherited method will be invoked. However, since FindBugs only looks at
classfiles, it
can't tell the difference between an invocation of this.foo(17)
and foo(17)
, it will still
complain about a potential ambiguous invocation.
alpha.Foo
extends beta.Foo
).
This can be exceptionally confusing, create lots of situations in which you have to look at import statements
to resolve references and creates many
opportunities to accidentally define methods that do not override methods in their superclasses.
]]>
alpha.Foo
extends beta.Foo
).
This can be exceptionally confusing, create lots of situations in which you have to look at import statements
to resolve references and creates many
opportunities to accidentally define methods that do not override methods in their superclasses.
]]>
import alpha.Foo; public class A { public int f(Foo x) { return 17; } } ---- import beta.Foo; public class B extends A { public int f(Foo x) { return 42; } }
The f(Foo)
method defined in class B
doesn't
override the
f(Foo)
method defined in class A
, because the argument
types are Foo
's from different packages.
import alpha.Foo; public class A { public int f(Foo x) { return 17; } } ---- import beta.Foo; public class B extends A { public int f(Foo x) { return 42; } public int f(alpha.Foo x) { return 27; } }
The f(Foo)
method defined in class B
doesn't
override the
f(Foo)
method defined in class A
, because the argument
types are Foo
's from different packages.
In this case, the subclass does define a method with a signature identical to the method in the superclass, so this is presumably understood. However, such methods are exceptionally confusing. You should strongly consider removing or deprecating the method with the similar but not identical signature.
]]>hashcode()
. This method
does not override the hashCode()
method in java.lang.Object
,
which is probably what was intended.
]]>
tostring()
. This method
does not override the toString()
method in java.lang.Object
,
which is probably what was intended.
]]>
equal(Object)
. This method does
not override the equals(Object)
method in java.lang.Object
,
which is probably what was intended.
]]>
java.io.InputStream.read()
which can return multiple bytes.
If the return value is not checked, the caller will not be able to correctly
handle the case where fewer bytes were read than the caller requested.
This is a particularly insidious kind of bug, because in many programs,
reads from input streams usually do read the full amount of data requested,
causing the program to fail only sporadically.
]]>
java.io.InputStream.skip()
which can skip multiple bytes.
If the return value is not checked, the caller will not be able to correctly
handle the case where fewer bytes were skipped than the caller requested.
This is a particularly insidious kind of bug, because in many programs,
skips from input streams usually do skip the full amount of data requested,
causing the program to fail only sporadically. With Buffered streams, however,
skip() will only skip data in the buffer, and will routinely fail to skip the
requested number of bytes.
]]>
Serializable
interface, and defines a method
for custom serialization/deserialization. But since that method isn't declared private,
it will be silently ignored by the serialization/deserialization API.
]]>
Externalizable
interface, but does
not define a void constructor. When Externalizable objects are deserialized,
they first need to be constructed by invoking the void
constructor. Since this class does not have one,
serialization and deserialization will fail at runtime.
]]>
Serializable
interface
and its superclass does not. When such an object is deserialized,
the fields of the superclass need to be initialized by
invoking the void constructor of the superclass.
Since the superclass does not have one,
serialization and deserialization will fail at runtime.
]]>
Serializable
interface, but does
not define a serialVersionUID
field.
A change as simple as adding a reference to a .class object
will add synthetic fields to the class,
which will unfortunately change the implicit
serialVersionUID (e.g., adding a reference to String.class
will generate a static field class$java$lang$String
).
Also, different source code to bytecode compilers may use different
naming conventions for synthetic variables generated for
references to class objects or inner classes.
To ensure interoperability of Serializable across versions,
consider adding an explicit serialVersionUID.
]]>
Comparator
interface. You
should consider whether or not it should also implement the Serializable
interface. If a comparator is used to construct an ordered collection
such as a TreeMap
, then the TreeMap
will be serializable only if the comparator is also serializable.
As most comparators have little or no state, making them serializable
is generally easy and good defensive programming.
]]>
Because the analysis only looks at the generated bytecode, this warning can be incorrect triggered if the default case is at the end of the switch statement and the switch statement doesn't contain break statements for other cases. ]]>
writeObject()
method which is synchronized;
however, no other method of the class is synchronized.
]]>
readObject()
which is
synchronized. By definition, an object created by deserialization
is only reachable by one thread, and thus there is no need for
readObject()
to be synchronized. If the readObject()
method itself is causing the object to become visible to another thread,
that is an example of very dubious coding style.
]]>
serialVersionUID
field that is not static.
The field should be made static
if it is intended to specify
the version UID for purposes of serialization.
]]>
serialVersionUID
field that is not final.
The field should be made final
if it is intended to specify
the version UID for purposes of serialization.
]]>
serialVersionUID
field that is not long.
The field should be made long
if it is intended to specify
the version UID for purposes of serialization.
]]>
java.lang.Object
, and does not appear to implement
the Externalizable
interface or the
readObject()
and writeObject()
methods.
Objects of this class will not be deserialized correctly if a non-Serializable
object is stored in this field.
]]>
If possible, making the inner class a static inner class should solve the problem. Making the outer class serializable might also work, but that would mean serializing an instance of the inner class would always also serialize the instance of the outer class, which it often not what you really want. ]]>
java.lang.Object.wait()
which is not in a loop. If the monitor is used for multiple conditions,
the condition the caller intended to wait for might not be the one
that actually occurred.
]]>
java.util.concurrent.await()
(or variants)
which is not in a loop. If the object is used for multiple conditions,
the condition the caller intended to wait for might not be the one
that actually occurred.
]]>
notify()
rather than notifyAll()
.
Java monitors are often used for multiple conditions. Calling notify()
only wakes up one thread, meaning that the thread woken up might not be the
one waiting for the condition that the caller just satisfied.
]]>
We are trying to reduce the false positives as much as possible, but in some cases this warning might be wrong. Common false-positive cases include:
- The method is intended to trigger loading of some class which may have a side effect.
- The method is intended to implicitly throw some obscure exception.
]]>This analysis rarely produces false-positives. Common false-positive cases include:
- This object used to implicitly throw some obscure exception.
- This object used as a stub to generalize the code.
- This object used to hold strong references to weak/soft-referenced objects.
]]>String.toLowerCase()
).
We are guessing that ignoring the return value might be a bad idea just from a simple analysis of the body of the method. You can use a @CheckReturnValue annotation to instruct FindBugs as to whether ignoring the return value of this method is important or acceptable.
Please investigate this closely to decide whether it is OK to ignore the return value.
]]>We are trying to reduce the false positives as much as possible, but in some cases this warning might be wrong. Common false-positive cases include:
- The method is designed to be overridden and produce a side effect in other projects which are out of the scope of the analysis.
- The method is called to trigger the class loading which may have a side effect.
- The method is called just to get some exception.
If you feel that our assumption is incorrect, you can use a @CheckReturnValue annotation to instruct FindBugs that ignoring the return value of this method is acceptable.
]]>String dateString = getHeaderField(name); dateString.trim();
the programmer seems to be thinking that the trim() method will update the String referenced by dateString. But since Strings are immutable, the trim() function returns a new String value, which is being ignored here. The code should be corrected to:
]]>String dateString = getHeaderField(name); dateString = dateString.trim();
File.delete()
method returns false
if the file could not be successfully deleted (rather than
throwing an Exception).
If you don't check the result, you won't notice if the method invocation
signals unexpected behavior by returning an atypical return value.
]]>
if (x < 0) new IllegalArgumentException("x must be nonnegative");
It was probably the intent of the programmer to throw the created exception:
]]>if (x < 0) throw new IllegalArgumentException("x must be nonnegative");
NullPointerException
when the code is executed.
]]>
NullPointerException
when the code is executed.
Note that because FindBugs currently does not prune infeasible exception paths,
this may be a false warning.
Also note that FindBugs considers the default case of a switch statement to be an exception path, since the default case is often infeasible.
]]>NullPointerException
when the code is executed.
Of course, the problem might be that the branch or statement is infeasible and that
the null pointer exception can't ever be executed; deciding that is beyond the ability of FindBugs.
]]>
NullPointerException
when the code is executed.
Of course, the problem might be that the branch or statement is infeasible and that
the null pointer exception can't ever be executed; deciding that is beyond the ability of FindBugs.
Due to the fact that this value had been previously tested for nullness,
this is a definite possibility.
]]>
NullPointerException
when the code is executed.
Note that because FindBugs currently does not prune infeasible exception paths,
this may be a false warning.
Also note that FindBugs considers the default case of a switch statement to be an exception path, since the default case is often infeasible.
]]>NullPointerException
when the code is executed.
]]>
Note that a check such as
if (x == null) throw new NullPointerException();
is treated as a dereference of x
.
finally
block to ensure that streams are
closed.
]]>
finally
block to ensure that streams are
closed.
]]>
On the other hand, using null to indicate
"there is no answer to this question" is probably appropriate.
For example, File.listFiles()
returns an empty list
if given a directory containing no files, and returns null if the file
is not a directory.
if
statement:
if (argv.length == 0) { // TODO: handle this case }]]>
if
statement, e.g.:
if (argv.length == 1); System.out.println("Hello, " + argv[0]);]]>
This particular warning generally indicates that a value known not to be null was checked against null. While the check is not necessary, it may simply be a case of defensive programming.
]]>java.util.concurrent
) lock,
but does not release it on all paths out of the method. In general, the correct idiom
for using a JSR-166 lock is:
Lock l = ...; l.lock(); try { // do something } finally { l.unlock(); }]]>
java.util.concurrent
) lock,
but does not release it on all exception paths out of the method. In general, the correct idiom
for using a JSR-166 lock is:
Lock l = ...; l.lock(); try { // do something } finally { l.unlock(); }]]>
new Boolean(b)
constructor. It is best to avoid such objects, but if they do exist,
then checking Boolean objects for equality using == or != will give results
than are different than you would get using .equals(...)
.
]]>
false
.
]]>
IllegalMonitorStateException
being thrown.
]]>
IllegalMonitorStateException
being thrown.
]]>
int foo; public void setFoo(int foo) { foo = foo; }
The assignment is useless. Did you mean to assign to the field instead?
]]>public void foo() { int x = 3; x = x; }
Such assignments are useless, and may indicate a logic error or typo.
]]>int x; public void foo() { x = x; }
Such assignments are useless, and may indicate a logic error or typo.
]]>int x,y; public void foo() { x = x = 17; }
Assigning to a field twice is useless, and may indicate a logic error or typo.
]]>public void foo() { int x,y; x = x = 17; }
Assigning the same value to a variable twice is useless, and may indicate a logic error or typo.
]]>Preconditions.checkNotNull("message", message)
has reserved arguments: the value to be checked is the first argument.
]]>
If it is important that the generated Random numbers not be guessable, you must not create a new Random for each random number; the values are too easily guessable. You should strongly consider using a java.security.SecureRandom instead (and avoid allocating a new SecureRandom for each random number needed).
]]>Integer.MIN_VALUE
, then the result will be negative as well (since
Math.abs(Integer.MIN_VALUE) == Integer.MIN_VALUE
). (Same problem arises for long values as well).
]]>
Integer.MIN_VALUE
, then the result will be negative as well (since
Math.abs(Integer.MIN_VALUE) == Integer.MIN_VALUE
).
One out of 2^32 strings have a hashCode of Integer.MIN_VALUE, including "polygenelubricants" "GydZG_" and ""DESIGNING WORKHOUSES".
]]> Assuming you want to ensure that the result of your computation is nonnegative,
you may need to change your code.
If you know the divisor is a power of 2,
you can use a bitwise and operator instead (i.e., instead of
using x.hashCode()%n
, use x.hashCode()&(n-1)
).
This is probably faster than computing the remainder as well.
If you don't know that the divisor is a power of 2, take the absolute
value of the result of the remainder operation (i.e., use
Math.abs(x.hashCode()%n)
).
b
to an unsigned value in the range 0..255,
use 0xff & b
.
]]>
v & 0xffffffff
).
]]>
b[0]
contains the value 0xff
, and
x
is initially 0, then the code
((x << 8) | b[0])
will sign extend 0xff
to get 0xffffffff
, and thus give the value
0xffffffff
as the result.
In particular, the following code for packing a byte array into an int is badly wrong:
int result = 0; for(int i = 0; i < 4; i++) result = ((result << 8) | b[i]);
The following idiom will work instead:
int result = 0; for(int i = 0; i < 4; i++) result = ((result << 8) | (b[i] & 0xff));]]>
b[0]
contains the value 0xff
, and
x
is initially 0, then the code
((x << 8) + b[0])
will sign extend 0xff
to get 0xffffffff
, and thus give the value
0xffffffff
as the result.
In particular, the following code for packing a byte array into an int is badly wrong:
int result = 0; for(int i = 0; i < 4; i++) result = ((result << 8) + b[i]);
The following idiom will work instead:
int result = 0; for(int i = 0; i < 4; i++) result = ((result << 8) + (b[i] & 0xff));]]>
((event.detail & SWT.SELECTED) > 0)
.
Using bit arithmetic and then comparing with the greater than operator can
lead to unexpected results (of course depending on the value of
SWT.SELECTED). If SWT.SELECTED is a negative number, this is a candidate
for a bug. Even when SWT.SELECTED is not negative, it seems good practice
to use '!= 0' instead of '> 0'.
]]>
((val & CONSTANT) > 0)
where CONSTANT is the negative number.
Using bit arithmetic and then comparing with the greater than operator can
lead to unexpected results. This comparison is unlikely to work as expected. The good practice is
to use '!= 0' instead of '> 0'.
]]>
(e & 0)
to 0,
which will always compare equal.
This may indicate a logic error or typo.
]]>
(e | C)
to D.
which will always compare unequal
due to the specific values of constants C and D.
This may indicate a logic error or typo.
Typically, this bug occurs because the code wants to perform a membership test in a bit set, but uses the bitwise OR operator ("|") instead of bitwise AND ("&").
Also such bug may appear in expressions like (e & A | B) == C
which is parsed like ((e & A) | B) == C
while (e & (A | B)) == C
was intended.
Even if you feel confident that the method is never called by multiple threads, it might be better to not set the static field until the value you are setting it to is fully populated/initialized. ]]>
acquire()
/release()
rather
than using the synchronized (...)
construct.
]]>
wait()
,
notify()
or
notifyAll()()
on an object that also provides an
await()
,
signal()
,
signalAll()
method (such as util.concurrent Condition objects).
This probably isn't what you want, and even if you do want it, you should consider changing
your design, as other developers will find it exceptionally confusing.
]]>
synchronized
. For example,
synchronizing on an AtomicBoolean
will not prevent other threads
from modifying the AtomicBoolean
.
Such code may be correct, but should be carefully reviewed and documented, and may confuse people who have to maintain the code at a later date.
]]>Better performance can be obtained by using a StringBuffer (or StringBuilder in Java 1.5) explicitly.
For example:
// This is bad String s = ""; for (int i = 0; i < field.length; ++i) { s = s + field[i]; } // This is better StringBuffer buf = new StringBuffer(); for (int i = 0; i < field.length; ++i) { buf.append(field[i]); } String s = buf.toString();]]>
myString.indexOf('.')
instead of myString.indexOf(".")
]]>
myString.lastIndexOf('.')
instead of myString.lastIndexOf(".")
]]>
myCollection.toArray(new Foo[myCollection.size()])
If the array passed in is big enough to store all of the
elements of the collection, then it is populated and returned
directly. This avoids the need to create a second array
(by reflection) to return as the result.
]]>
public static junit.framework.Test suite()or
public static junit.framework.TestSuite suite()]]>
java.util.Arrays.equals(Object[], Object[])
.
To compare the addresses of the arrays, it would be
less confusing to explicitly check pointer equality using ==
.
]]>
Note that Sun's javac compiler often generates dead stores for final local variables. Because FindBugs is a bytecode-based tool, there is no easy way to eliminate these false positives.
]]>return x++;
.
A postfix increment/decrement does not impact the value of the expression,
so this increment/decrement has no effect.
Please verify that this statement does the right thing.
]]>
Foo.class
would force the static initializer
for Foo
to be executed, if it has not been executed already.
In Java 5 and later, it does not.
See Sun's article on Java SE compatibility for more details and examples, and suggestions on how to force class initialization in Java 5.
]]>A better approach is to either explicitly catch the specific exceptions that are thrown, or to explicitly catch RuntimeException exception, rethrow it, and then catch all non-Runtime Exceptions, as shown below:
try { ... } catch (RuntimeException e) { throw e; } catch (Exception e) { ... deal with all non-runtime exceptions ... }]]>
if (x == Double.NaN)
). However,
because of the special semantics of NaN
, no value
is equal to Nan
, including NaN
. Thus,
x == Double.NaN
always evaluates to false.
To check to see if a value contained in x
is the special Not A Number value, use
Double.isNaN(x)
(or Float.isNaN(x)
if
x
is floating point precision).
]]>
if ( Math.abs(x - y) < .0000001 )
.
See the Java Language Specification, section 4.2.4.
]]>
Method | Parameter |
---|---|
abs | -any- |
acos | 0.0 or 1.0 |
asin | 0.0 or 1.0 |
atan | 0.0 or 1.0 |
atan2 | 0.0 |
cbrt | 0.0 or 1.0 |
ceil | -any- |
cos | 0.0 |
cosh | 0.0 |
exp | 0.0 or 1.0 |
expm1 | 0.0 |
floor | -any- |
log | 0.0 or 1.0 |
log10 | 0.0 or 1.0 |
rint | -any- |
round | -any- |
sin | 0.0 |
sinh | 0.0 |
sqrt | 0.0 or 1.0 |
tan | 0.0 |
tanh | 0.0 |
toDegrees | 0.0 or 1.0 |
toRadians | 0.0 |
long convertDaysToMilliseconds(int days) { return 1000*3600*24*days; }
If the multiplication is done using long arithmetic, you can avoid the possibility that the result will overflow. For example, you could fix the above code to:
long convertDaysToMilliseconds(int days) { return 1000L*3600*24*days; }or
static final long MILLISECONDS_PER_DAY = 24L*3600*1000; long convertDaysToMilliseconds(int days) { return days * MILLISECONDS_PER_DAY; }]]>
Date getDate(int seconds) { return new Date(seconds * 1000); }
The multiplication is done using 32-bit arithmetic, and then converted to a 64-bit value. When a 32-bit value is converted to 64-bits and used to express an absolute time value, only dates in December 1969 and January 1970 can be represented.
Correct implementations for the above method are:
// Fails for dates after 2037 Date getDate(int seconds) { return new Date(seconds * 1000L); } // better, works for all dates Date getDate(long seconds) { return new Date(seconds * 1000); }]]>
]]>int x = 2; int y = 5; // Wrong: yields result 0.0 double value1 = x / y; // Right: yields result 0.4 double value2 = x / (double) y;
formatter.format("%<s %s", "a", "b")
would throw a MissingFormatArgumentException when executed.
]]>String.format("%d", "1")
will generate an exception, since
the String "1" is incompatible with the format specifier %d.
]]>
Arrays.asList(...)
before handling it off to a formatted.
]]>
System.out.println("%d\n", "hello");
The %d placeholder requires a numeric argument, but a string value is passed instead. A runtime exception will occur when this statement is executed.
]]>equals(Object o)
method shouldn't make any assumptions
about the type of o
. It should simply return
false if o
is not the same type as this
.
]]>
List
, Set
, or Map
).
Ensure that you are guaranteed that the object is of the type
you are casting to. If all you need is to be able
to iterate through a collection, you don't need to cast it to a Set or List.
]]>
toArray()
on a collection
to a type more specific than Object[]
, as in:
String[] getAsArray(Collection<String> c) { return (String[]) c.toArray(); }
This will usually fail by throwing a ClassCastException. The toArray()
of almost all collections return an Object[]
. They can't really do anything else,
since the Collection object has no reference to the declared generic type of the collection.
The correct way to do get an array of a specific type from a collection is to use
c.toArray(new String[]);
or c.toArray(new String[c.size()]);
(the latter is slightly more efficient).
There is one common/known exception to this. The toArray()
method of lists returned by Arrays.asList(...)
will return a covariantly
typed array. For example, Arrays.asArray(new String[] { "a" }).toArray()
will return a String []
. FindBugs attempts to detect and suppress
such cases, but may miss some.
File.separator
where a regular expression is required. This will fail on Windows
platforms, where the File.separator
is a backslash, which is interpreted in a
regular expression as an escape character. Among other options, you can just use
File.separatorChar=='\\' ? "\\\\" : File.separator
instead of
File.separator
]]>
i++
) and then
immediately overwrites it. For example, i = i++
immediately
overwrites the incremented value with the original value.
]]>
a
,
use java.util.Arrays.hashCode(a)
.
]]>
(low+high)/2
,
use (low+high) >>> 1
This bug exists in many earlier implementations of binary search and merge sort. Martin Buchholz found and fixed it in the JDK libraries, and Joshua Bloch widely publicized the bug pattern.
]]>new File("/home/dannyc/workspace/j2ee/src/share/com/sun/enterprise/deployment");
]]>
for details.
]]>In general, instances of two unrelated classes are not equal.
For example, if the Foo
and Bar
classes
are not related by subtyping, then an instance of Foo
should not be equal to an instance of Bar
.
Among other issues, doing so will likely result in an equals method
that is not symmetrical. For example, if you define the Foo
class
so that a Foo
can be equal to a String
,
your equals method isn't symmetrical since a String
can only be equal
to a String
.
In rare cases, people do define nonsymmetrical equals methods and still manage to make
their code work. Although none of the APIs document or guarantee it, it is typically
the case that if you check if a Collection<String>
contains
a Foo
, the equals method of argument (e.g., the equals method of the
Foo
class) used to perform the equality checks.
s.contains(s)
were true). This is unlikely to be true and would cause
problems if it were true (such as the computation of the hash code resulting in infinite recursion).
It is likely that the wrong value is being passed as a parameter.
]]>
c
, calling c.containsAll(c)
should
always be true, and c.retainAll(c)
should have no effect.
]]>
m
returns
such an iterator for an entrySet, then
c.addAll(m.entrySet())
will go badly wrong. All of
the Map implementations in OpenJDK 1.7 have been rewritten to avoid this,
you should to.
]]>
c
, use c.clear
,
not c.removeAll(c)
. Calling c.removeAll(c)
to clear a collection
is less clear, susceptible to errors from typos, less efficient and
for some collections, might throw a ConcurrentModificationException
.
]]>
You may also experience serialization problems.
Using an instance field is recommended.
For more information on this see JDK Bug #6231579 and JDK Bug #6178997.
]]>For more information on this see JDK Bug #6231579 and JDK Bug #6178997.
]]>You may also experience serialization problems.
Using an instance field is recommended.
For more information on this see JDK Bug #6231579 and JDK Bug #6178997.
]]>For more information on this see JDK Bug #6231579 and JDK Bug #6178997.
]]>More precisely, a value annotated with a type qualifier specifying when=ALWAYS is compared with a value that where the same type qualifier specifies when=NEVER.
For example, say that @NonNegative is a nickname for the type qualifier annotation @Negative(when=When.NEVER). The following code will generate this warning because the return statement requires a @NonNegative value, but receives one that is marked as @Negative.
]]>public boolean example(@Negative Integer value1, @NonNegative Integer value2) { return value1.equals(value2); }
More precisely, a value annotated with a type qualifier specifying when=ALWAYS is guaranteed to reach a use or uses where the same type qualifier specifies when=NEVER.
For example, say that @NonNegative is a nickname for the type qualifier annotation @Negative(when=When.NEVER). The following code will generate this warning because the return statement requires a @NonNegative value, but receives one that is marked as @Negative.
]]>public @NonNegative Integer example(@Negative Integer value) { return value; }
To coerce a value to have a strict annotation, define an identity function where the return value is annotated with the strict annotation. This is the only way to turn a non-annotated value into a value with a strict type qualifier annotation.
]]>More precisely, a value annotated with a type qualifier specifying when=NEVER is guaranteed to reach a use or uses where the same type qualifier specifies when=ALWAYS.
TODO: example
]]>The only situation in which opening a file in append mode and the writing an object output stream could work is if on reading the file you plan to open it in random access mode and seek to the byte offset where the append started.
TODO: example.
]]>this.getClass()
. If this class is subclassed,
subclasses will synchronize on the class object for the subclass, which isn't likely what was intended.
For example, consider this code from java.awt.Label:
private static final String base = "label"; private static int nameCounter = 0; String constructComponentName() { synchronized (getClass()) { return base + nameCounter++; } }
Subclasses of Label
won't synchronize on the same subclass, giving rise to a datarace.
Instead, this code should be synchronizing on Label.class
private static final String base = "label"; private static int nameCounter = 0; String constructComponentName() { synchronized (Label.class) { return base + nameCounter++; } }
Bug pattern contributed by Jason Mehrens
]]>In general, if a method opens a stream or other resource, the method should use a try/finally block to ensure that the stream or resource is cleaned up before the method returns.
This bug pattern is essentially the same as the OS_OPEN_STREAM and ODR_OPEN_DATABASE_RESOURCE bug patterns, but is based on a different (and hopefully better) static analysis technique. We are interested is getting feedback about the usefulness of this bug pattern. To send feedback, either:
In particular, the false-positive suppression heuristics for this bug pattern have not been extensively tuned, so reports about false positives are helpful to us.
See Weimer and Necula, Finding and Preventing Run-Time Error Handling Mistakes, for a description of the analysis technique.
]]>In general, if a method opens a stream or other resource, the method should use a try/finally block to ensure that the stream or resource is cleaned up before the method returns.
This bug pattern is essentially the same as the OS_OPEN_STREAM and ODR_OPEN_DATABASE_RESOURCE bug patterns, but is based on a different (and hopefully better) static analysis technique. We are interested is getting feedback about the usefulness of this bug pattern. To send feedback, either:
In particular, the false-positive suppression heuristics for this bug pattern have not been extensively tuned, so reports about false positives are helpful to us.
See Weimer and Necula, Finding and Preventing Run-Time Error Handling Mistakes, for a description of the analysis technique.
]]>public static void initLogging() throws Exception { Logger logger = Logger.getLogger("edu.umd.cs"); logger.addHandler(new FileHandler()); // call to change logger configuration logger.setUseParentHandlers(false); // another call to change logger configuration }
The logger reference is lost at the end of the method (it doesn't escape the method), so if you have a garbage collection cycle just after the call to initLogging, the logger configuration is lost (because Logger only keeps weak references).
public static void main(String[] args) throws Exception { initLogging(); // adds a file handler to the logger System.gc(); // logger configuration lost Logger.getLogger("edu.umd.cs").info("Some message"); // this isn't logged to the file as expected }
Ulf Ochsenfahrt and Eric Fellheimer
]]>