Discover NullPointerException bugs using FindBugs - java

When I run FindBugs 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?

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).

I took FindBugs sources and searched for
NP_PARAMETER_MUST_BE_NONNULL_BUT_MARKED_AS_NULLABLE
Found two files:
BuildUnconditionalParamDerefDatabase.java
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());
}

You want to use #CheckForNull instead of #Nullable

#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.

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

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

Related

Is there any reason for expression like !Boolean.FALSE.equals()?

When browsing the Spring's source code, I encountered code like if (!Boolean.FALSE.equals(pv.conversionNecessary)) {...}
After some research, I also found codes like !Boolean.FALSE.equals and !Boolean.TRUE.equals exist in other open-source projects too.
I wonder what's the possible reasons for not using the apparently concise expression?
There are various reasons why this kind of thing might be necessary.
In this example, pv is an instance of PropertyValue which declares the conversionNecessary as follows:
/** Package-visible field that indicates whether conversion is necessary. */
#Nullable
volatile Boolean conversionNecessary;
(source code)
From this, we can infer that it is not unexpected for conversionNecessary to be null.
So ... the verbose form if (!Boolean.FALSE.equals(pv.conversionNecessary)) {...} is dealing with the null case. Boolean.FALSE.equals(null) is false.
By contrast, the more concise form if (!pv.conversionNecessary) {...} would throw an NPE.
It is also worth noting that since conversionNecessary is volatile here, an alternative version that did an explicit null check would need to use a temporary variable to avoid race conditions; e.g.
Boolean necessary = pv.conversionNecessary;
if (necessary == null || necessary) { ... }
Another scenario where you might do this kind of thing is if the declared type of the variable is Object rather than Boolean.

Which is better to use Lombok's #NonNull or Objects.requireNonNull? [duplicate]

What is the difference between following two code snippets.
public Integer getId(#Nonnull SomeObject obj){
// do some stuff
return id;
}
public Integer getId(SomeObject obj){
Objects.requireNonNull(SomeObject, "SomeObject is null");
// do some stuff
return id;
}
What are the significant differences between them. And what is the correct way to do the null-check in these situations.
The two are complementary: #Nonnull annotation documents the fact that obj must be non-null, while Objects.requireNonNull call ensures that obj is non-null at run-time.
You should combine the two, like this:
public Integer getId(#Nonnull SomeObject obj){
Objects.requireNonNull(SomeObject, "SomeObject is null");
// do some stuff
return id;
}
Relevant documentation on #Nonnull can be found here:
Optional Type Annotations are not a substitute for runtime validation
Before Type Annotations, the primary location for describing things like nullability or ranges was in the javadoc. With Type annotations, this communication comes into the bytecode in a way for compile-time verification.
Your code should still perform runtime validation.
The difference is that in the first case it's a hint for a compiler and IDE that the argument should not be null, so when you write getId(null)you'll get an error. But someone may pass null value in runtime.
As for the second case, it's a kind of defensive programming, when you fail-fast with a precondition that the argument should not be null.
One of these is an annotation which implements JSR-305, but is meant more for static analysis as opposed to a runtime guard. As I recall it, JSR-305 is a good idea in principle and a lot of things actually leverage it in some way, but it loses a lot of its bark when its utility only ever comes in the form of static analysis.
Case in point: your IDE can leverage this to warn you of situations in which you're passing something you shouldn't, but it can't prevent you from passing null into this method when you compile.
Objects.requireNonNull is a runtime enforcement that whatever it's passed will be a non-null reference. The compiler can't enforce this either, but at runtime should you receive a null value, you will get a NullPointerException upon executing that line of code.
In terms of correctness, using Objects.requireNonNull is a good idea, but that depends on what your obligation is when running the application. If you must fail on a null value, then using that is fine as it will generate a runtime exception to deal with. If you can't fail on a null value, then using an if check instead would be better.

javax.annotation.Nonnull vs assert

I'm using Findbugs and javax.annotation.Nonnull on method parameters.
On private methods I usually add an assert line to check for nullness like
private void myMethod(#Nonnull String str) {
assert str != null
....
Latest Netbeans version (7.3rc2) is reporting that the assert check is not necessary (because of the Nonnull annotation). I'm not fully sure this is a Netbeans bug or not.
Can the assert line be removed because I specified the #Nonnull annotation ?
As far as I understand, the annotation is used only during static analysis while assert is, when enabled, active during execution so the twos are not alternative.
The assert is evaluated at runtime, the annotation helps FindBugs catch problems during the analysis before runtime. As both checks are not really conflicting you could keep them both. I would find it annoying if my IDE told me to remove the assert.
Netbeans is right. If you think it can be null: remove the annotation. If you know it can't: remove the assert.
If there's ANY chance that your method could be called with a null value, then #Nonnull annotation shouldn't be there.
Like you said, that annotation doesn't actually do anything at runtime: it is only used by IDEs and static code analysis tools. It doesn't ensure that things aren't null.
Since this is private method, we can ensure that annotated parameter cannot be null. I think you can remove this assertion.
If NetBeans warns to public method, I think it has problem. I recommend you to put assertion.
If you still feel that assertion in private method is necessary, I think you can use bytecode injection.
For instance, here is a maven plugin to inject null check. Sorry this is my personal project, but it works to me. I guess it can suit your need.
https://github.com/KengoTODA/jsr305-maven-plugin
I found a different solution, as I was thinking about my IDE warnings.
Initially, I felt that the IDE was wrong. I'm a paranoid programmer, and want to have the label for documentation & static analysis AND a runtime check in case I ever use it from reflection, or another JVM language or something that isn't statically analyzable, so I thought it was wrong to give me a warning and tell me the assert(x != null) statement wasn't needed.
But then I thought about how asserts can be removed depending on the status of the -ea flag passed to Java at Runtime, and that in some ways assert and #Nonnull are really both development-only checks.
Turns out, there's an actual runtime check that can be inserted (Java 7+) Objects.requireNonNull which will throw a NullPointerException and cannot be removed with an -ea assertion. I think I'm going to prefer this to my assert(x != null); use(x); pattern.
public ConstructorForClass(#Nonnull Type x) {
this.x = Objects.requireNonNull(x);
//...
}

What's the best to handle unaccepted method arguments in Java?

When writing a method, say, inside one of your DAO objects, and you dont want this method to accept certain input, for discussions sake, say it does not allow null arguments. How do you go about implementing that, taking into account this method is likely to be reused in the future by new team members.
The way I do it is:
In the interface, I document inside the method javadoc that arguments a, b and c cannot be null.
Inside the method I check for null values first thing, and if any of a, b or c are null then I throw an IllegalArgumentException.
But, what if some developer in the future just reads off the method signature and decides that it what he/she needs and starts using it, without paying attention to this detail, and worse testing does not reveal it. NULL pointer exception won't occur and we are getting a useful error message, but we are still getting an error in production that could've been avoided.
Is there a way to enforce this at compile time? I doubt it, but what would be the safest and most bad-developer-proof way to go about doing this?
I don't think you can enforce this compile time, but you can certainly make the method signatures easy to understand.
If you don't mine adding a dependency on one of the validations frameworks you can use JSR 303's #NotNull or similar tools like Preconditions.
With JSR 303 you can do suff like:
#NotNull
#Size(min = 2, max = 14)
#UpperCase
private String licensePlate;
or
#NotNull
#NotEmpty
public String foo(#NotNull #Pattern(regexp="[0-9]") String param) {
...
}
Have a look at the Getting started with JSR 303 Bean Validation for more comprehensive examples.
You can use jsr305 with static code check tools like findbugs to check it before commit/release.
public String method(#NonNull String parameter ){
...
}
findbugs manual on annotation
As closest as you can get in enforcing things at compile time is by throwing checked exceptions which will force the caller to handle the exception at compile time. This might make them read the doc. The IllegalArgumentException is unchecked and can go unnoticed.
Normal practice in safeguarding on unusable values is by returning at the point we identify something unusable and add an error message for display. This will prevent the exception on production that might happen if the execution continued in that method, but might not altogether avoid it.

Some java method are null safe, some are not, how do I know?

Some java method is null safe, but some are not. How to distinguish them?
I assume you mean in terms of the parameters? The documentation should state whether or not the arguments can be null, and when they can be null, what semantic meaning is inferred from nullity.
Unfortunately not all documentation is clear like this - and likewise it may not specify whether the return value might be null or not... in which case all you can do is experiment or look at the source code where possible :(
In general, I would suggest that you assume that you cannot pass null as a parameter unless the documentation clearly states that you can and what the corresponding behaviour is.
A problem with taking the default assumption that a parameter might be "null-safe" is that, even if that turns out to be true, it's not always clear without documentation what the corresponding behaviour actually is. "Not throwing an exception" doesn't actually indicate what alternative behaviour/default parameter/assumptions are then going to occur instead.
If you're designing an API, then where is's practical, I would suggest not actually encouraging null to be passed as a parameter to exposed methods/constructors, but rather have separate method signatures that include or not the various optional parameters. And in any case, you may then need to document in some way what actual behaviour is being taken to make up for the missing parameter.
If you're lucky, the parameter will be documented or annotated, or both. Unfortunately, most Java APIs lack both.
Some static analysis tools can use annotations to check whether you're passing a null value inappropriately. For example, the FindBugs tool includes support for these annotations:
#NonNull - The value must not be null
#CheckForNull - The value may contain null.
#Nullable - Whether the value may contain null or not depends on context.
Read the javadocs of the methods you are trying to call. If the javadocs don't specify this, then trial and error in a unit test is probably your best bet.

Categories

Resources