views:

242

answers:

6

When I run FindBug on this code, it reports NO issues.

boolean _closed = false;

public void m1(@Nullable String text) {
    if(_closed)
        return;

    System.out.println(text.toLowerCase());
}

While here it finds issue as expected:

public void m1(@Nullable String text) {
    System.out.println(text.toLowerCase());  // FindBugs: text must be nonnull but is marked as nullable
}

Why does it fail in first case?

A: 

@Nullable only on those parameters, methods or fields that you want to allow to be null.

Seems like you are allowing null values for the text variable. You probably should use @NonNull instead.

Edit

I tried this out for my self and got the same result.

The text in the findbugs error (from the second method that does give the nullpointer bug) report says:

This parameter is always used in a way that requires it to be nonnull, but the parameter is explicitly annotated as being Nullable. Either the use of the parameter or the annotation is wrong.

My guess would be that since it is not a final Parameter FindBugs cannot/will not make any assumptions about the value of _closed since you can change it at a later time. I did even try to make the _closed variabel method scoped inside the m1-method, and it still doesnt report it as a bug.

Jarle Hansen
Consider that I want to be able to call m1() with 'null' values. So I mark 'text' as @Nullable. m1 by itself should handle 'null' values, but it does not. So I expect the FindBug to report an issue, and it does, but only in very simple case.
alex2k8
Confused by the answer... Do you want to say that FindBugs is reporting a bug when you run my code with if(_closed) condition?
alex2k8
Sorry about that, I did get the same result as you. Tried to make the answer clearer now
Jarle Hansen
A: 

Run JavaLint - I suspect it will tell you that

System.out.println(text.toLowerCase());

in the first example is unreachable. Since it is unreachable, I'm guessing FindBug doesn't care that it could cause a NullPointerException

DrewM
Notice, that _closed is 'false'. Also, _closed is not final, so it may be changed by some other method... As so the code is reachable.
alex2k8
+1  A: 

You want to use @CheckForNull instead of @Nullable

Michael Donohue
Same result on my tests.
alex2k8
A: 

I agree with alex2k8. It is probably because of the _closed data member. Its initialization is irrelevant as long as it is not declared as final. Static analysis has no generic means for determining the actual values of _closed at runtime, and no software can ever do it (it is equivalent to the Halting problem).

Eyal Schneider
Actually I believe that static-analyser should look into all branches, and warn if any one has an issue.
alex2k8
A: 

I took FindBugs sources and searched for

NP_PARAMETER_MUST_BE_NONNULL_BUT_MARKED_AS_NULLABLE

Found two files:

  1. BuildUnconditionalParamDerefDatabase.java
  2. InconsistentAnnotations.java

Both consider "unconditional params dereferencing" only.

Looks like FindBugs is NOT so useful to find null-pointer issues :-(

P.S.

public void m1(@CheckForNull String text) {
    if(_closed) // FindBugs: text must be nonnull but is marked as nullable
        System.out.println(text.toUpperCase());
    else
        System.out.println(text.toLowerCase());
}
alex2k8
A: 

edu.umd.cs.findbugs.annotations.Nullable [Target] Field, Method, Parameter

The annotated element could be null under some circumstances. In general, this means developers will have to read the documentation to determine when a null value is acceptable and whether it is neccessary to check for a null value. FindBugs will treat the annotated items as though they had no annotation.

In pratice this annotation is useful only for overriding an overarching NonNull annotation.

http://findbugs.sourceforge.net/manual/annotations.html

Tim Bender
In reality they consider and report issues for this annotation in some cases. And Nullable or CheckForNull worked in the same way for me.
alex2k8