I have a class like this:
import javax.annotation.Nullable;
public class Nullness {
private #Nullable Object someObject;
public void foo() {
if (someObject != null) {
someObject.toString(); //error "Potential null pointer access: The field someObject is specified as #Nullable"
}
}
}
And when enable eclipse null analysis, an error is marked at the statement someObject.toString(); which reads Potential null pointer access: The field someObject is specified as #Nullable.
Eclipse has a quick fix that can change my code to be like this:
public void foo() {
final Object someObject2 = someObject;
if (someObject2 != null) {
someObject2.toString();
}
}
which can wipe out the error, note that, actually, the final modifier is not required to make the error disappear.
I don't understand why Eclipse does not allow me to use field variable directly in null-checking statement if (someObject != null) but force me to create additional local variable someObject2. Is this behavior just a bug or it is intended?
Must apologize the community by posting the question without doing carefully research. This issue is clearly mention in this wiki, which discuss that using field variable directly can cause unexpected effect in several ways.
with the following code I get NP_NULL_PARAM_DEREF: Method call passes null for nonnull parameter:
public void calledAnywhereIDoNotCare() {
//[...]
//parameter could be null but shouldn't ever be by logic
method(parameter); //FindBugs says the problem is here
//[...]
}
public final ReturnType method(final ParameterType parameter) {
//this method do nothing but simply call anotherMethod()
return anotherMethod(parameter, false);
}
public final ReturnType anotherMethod(final ParameterType parameter, boolean boolParam) {
if (parameter == null) {
//just in case logic is wrong
throw new NullPointerException("I know it shouldn't be null by logic, but it is null!");
}
//do something very usefull
//[...]
}
So, my question is: Why did I get this NP_NULL_PARAM_DEREF and what changes would be better?
Did I get this because of declaring the parameter final? Or because of not catching the NullPointerException? I don't want to catch it, it should be catched somewhere out there. Maybe I should declare throwing NullPointerException in calledAnywhereIDoNotCare()?
Thank you for your help.
TARL
In your comment you write that the parameter "could" be null but never will because of the program logic. FindBugs doesn't know/understand the logic. The best way would be to let FindBugs ignore the NP_NULL_PARAM_DEREF in this method using the edu.umd.cs.findbugs.annotations.SuppressWarnings annotation. See http://findbugs.sourceforge.net/manual/annotations.html
I have some code which is similar to the following snippet:
public void foo(Order o) {
...
checkInput(o, "some error message");
doSomehing(o.getId());
}
private void checkInput(Object o, String message) {
if (o == null) {
throw new SomeRuntimeException(message);
}
}
And I got Findbugs reporting an 'NP_NULL_ON_SOME_PATH' issue.
Here is the description:
There is a branch of statement that, if executed, guarantees that a null value will be dereferenced, which would generate a 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.
My questions are:
Can I treat it as a false positive in this example?
Is it a good practice to put the null test in a separate method? The actual null check method is a bit longer than the sample method so I don't want to repeat the code everywhere.
Thanks!
It looks like FindBugs is not able to detect this case, at least with 2.0.2 in Eclipse. One workaround is to return the value from checkError and annotate the method with #Nonnull.
public void foo(Order o) {
...
doSomehing(checkInput(o, "some error message").getId());
}
#Nonnull
private Order checkInput(Order o, String message) {
if (o == null) {
throw new SomeRuntimeException(message);
}
...
return o;
}
I have a method where a parameter is marked with the #Nonnull annotation. The code which calls the method has to check whether the value is null. Rather than just a straight x != null check, it is calling a utility method on another class. (In the real code, the utility method also checks whether it is a blank String).
My problem is that Intellij Idea is showing an inspection warning on the Nonnull method call, saying that my variable "might be null". I know it cannot be null because of the utility method check - how can I tell the inspector that?
Since that is a bit abstract, here's a minimal example of what I mean:
package org.ethelred.ideatest;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
/**
* tests annotations
*/
public class AnnotationChecker
{
public static void main(String[] args)
{
String x = null;
if(args.length > 0)
{
x = args[0];
}
if(!isNull(x))
{
useObject(x);
}
if(x != null)
{
useObject(x);
}
}
public static boolean isNull(#CheckForNull Object o)
{
return o == null;
}
public static void useObject(#Nonnull Object o)
{
System.out.println(o);
}
}
This uses the JSR 305 annotations.
In this example, in the first call to useObject Intellij puts a warning on the x parameter saying "Argument 'x' might be null". In the second call, there is no warning.
In IDEA 13 very fancy feature was added, called Method Contracts. For example, you could have a method, that throws validation exception if it encounters null:
#Contract("null -> fail")
public static void validateNull(#Nullable final Object object) {
if (object == null) {
throw new ValidationException();
}
}
IDEA will analyze the annotation and won't show up warnings, if you call it before possible NPE:
validateNull(user);
user.setSomething("something"); // no warning
You have full documentation in IDEA's settings (just search for Method Contract). For this to work you need additional dependency on jetbrain's annotations jar:
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>13.0</version>
</dependency>
With IDEA 12 you can configure the NotNull-check methods:
http://youtrack.jetbrains.com/issue/IDEA-35808#tab=Comments
I don't believe there's any way to resolve the warning with the code written as it is. I was hoping to find that IntelliJ supports a value for #SuppressWarnings that you could use on the useObject(x) statement, but according to this source it does not. You may just have to bite the bullet and change your code to something like the following:
if (x != null && !isBlank(x)) {
useObject(x);
}
Notice that I renamed the method isNull to isBlank since it is my understanding that the actual method you're calling that does the check for null checks other conditions as well.
I've dealt with this issue by using a static method to whitelist object calls:
/** Wrapper to mask NullPointerException warnings. */
private static <T> T _(T obj) {
return obj;
}
The method name is intended to not interfere with readability. Thus,
mObject.method();
becomes
_(mObject).method();
Furthermore, if a NullPointerException does occur it will still refer to the same line number.
This is the second time I found myself writing this kind of code, and decided that there must be a more readable way to accomplish this:
My code tries to figure something out, that's not exactly well defined, or there are many ways to accomplish it. I want my code to try out several ways to figure it out, until it succeeds, or it runs out of strategies. But I haven't found a way to make this neat and readable.
My particular case: I need to find a particular type of method from an interface. It can be annotated for explicitness, but it can also be the only suitable method around (per its arguments).
So, my code currently reads like so:
Method candidateMethod = getMethodByAnnotation(clazz);
if (candidateMethod == null) {
candidateMethod = getMethodByBeingOnlyMethod(clazz);
}
if (candidateMethod == null) {
candidateMethod = getMethodByBeingOnlySuitableMethod(clazz);
}
if (candidateMethod == null) {
throw new NoSuitableMethodFoundException(clazz);
}
There must be a better way…
Edit: The methods return a method if found, null otherwise. I could switch that to try/catch logic, but that hardly makes it more readable.
Edit2: Unfortunately, I can accept only one answer :(
To me it is readable and understandable. I'd simply extract the ugly part of the code to a separate method (following some basic principles from "Robert C.Martin: Clean Code") and add some javadoc (and apologies, if necessary) like that:
//...
try {
Method method = MethodFinder.findMethodIn(clazz);
catch (NoSuitableMethodException oops) {
// handle exception
}
and later on in MethodFinder.java
/**
* Will find the most suitable method in the given class or throw an exception if
* no such method exists (...)
*/
public static Method findMethodIn(Class<?> clazz) throws NoSuitableMethodException {
// all your effort to get a method is hidden here,
// protected with unit tests and no need for anyone to read it
// in order to understand the 'main' part of the algorithm.
}
I think for a small set of methods what you're doing is fine.
For a larger set, I might be inclined to build a Chain of Responsibility, which captures the base concept of trying a sequence of things until one works.
I don't think that this is such a bad way of doing it. It is a bit verbose, but it clearly conveys what you are doing, and is easy to change.
Still, if you want to make it more concise, you can wrap the methods getMethod* into a class which implements an interface ("IMethodFinder") or similar:
public interface IMethodFinder{
public Method findMethod(...);
}
Then you can create instances of you class, put them into a collection and loop over it:
...
Method candidateMethod;
findLoop:
for (IMethodFinder mf: myMethodFinders){
candidateMethod = mf.findMethod(clazz);
if (candidateMethod!=null){
break findLoop;
}
}
if (candidateMethod!=null){
// method found
} else {
// not found :-(
}
While arguably somewhat more complicated, this will be easier to handle if you e.g. need to do more work between calling the findMethods* methods (such as more verification that the method is appropriate), or if the list of ways to find methods is configurable at runtime...
Still, your approach is probably OK as well.
I'm sorry to say, but the method you use seems to be the widely accepted one. I see a lot of code like that in the code base of large libraries like Spring, Maven etc.
However, an alternative would be to introduce a helper interface that can convert from a given input to a given output. Something like this:
public interface Converter<I, O> {
boolean canConvert(I input);
O convert(I input);
}
and a helper method
public static <I, O> O getDataFromConverters(
final I input,
final Converter<I, O>... converters
){
O result = null;
for(final Converter<I, O> converter : converters){
if(converter.canConvert(input)){
result = converter.convert(input);
break;
}
}
return result;
}
So then you could write reusable converters that implement your logic. Each of the converters would have to implement the canConvert(input) method to decide whether it's conversion routines will be used.
Actually: what your request reminds me of is the Try.these(a,b,c) method in Prototype (Javascript).
Usage example for your case:
Let's say you have some beans that have validation methods. There are several strategies to find these validation methods. First we'll check whether this annotation is present on the type:
// retention, target etc. stripped
public #interface ValidationMethod {
String value();
}
Then we'll check whether there's a method called "validate". To make things easier I assume, that all methods define a single parameter of type Object. You may choose a different pattern. Anyway, here's sample code:
// converter using the annotation
public static final class ValidationMethodAnnotationConverter implements
Converter<Class<?>, Method>{
#Override
public boolean canConvert(final Class<?> input){
return input.isAnnotationPresent(ValidationMethod.class);
}
#Override
public Method convert(final Class<?> input){
final String methodName =
input.getAnnotation(ValidationMethod.class).value();
try{
return input.getDeclaredMethod(methodName, Object.class);
} catch(final Exception e){
throw new IllegalStateException(e);
}
}
}
// converter using the method name convention
public static class MethodNameConventionConverter implements
Converter<Class<?>, Method>{
private static final String METHOD_NAME = "validate";
#Override
public boolean canConvert(final Class<?> input){
return findMethod(input) != null;
}
private Method findMethod(final Class<?> input){
try{
return input.getDeclaredMethod(METHOD_NAME, Object.class);
} catch(final SecurityException e){
throw new IllegalStateException(e);
} catch(final NoSuchMethodException e){
return null;
}
}
#Override
public Method convert(final Class<?> input){
return findMethod(input);
}
}
// find the validation method on a class using the two above converters
public static Method findValidationMethod(final Class<?> beanClass){
return getDataFromConverters(beanClass,
new ValidationMethodAnnotationConverter(),
new MethodNameConventionConverter()
);
}
// example bean class with validation method found by annotation
#ValidationMethod("doValidate")
public class BeanA{
public void doValidate(final Object input){
}
}
// example bean class with validation method found by convention
public class BeanB{
public void validate(final Object input){
}
}
You may use Decorator Design Pattern to accomplish different ways of finding out how to find something.
public interface FindMethod
{
public Method get(Class clazz);
}
public class FindMethodByAnnotation implements FindMethod
{
private final FindMethod findMethod;
public FindMethodByAnnotation(FindMethod findMethod)
{
this.findMethod = findMethod;
}
private Method findByAnnotation(Class clazz)
{
return getMethodByAnnotation(clazz);
}
public Method get(Class clazz)
{
Method r = null == findMethod ? null : findMethod.get(clazz);
return r == null ? findByAnnotation(clazz) : r;
}
}
public class FindMethodByOnlyMethod implements FindMethod
{
private final FindMethod findMethod;
public FindMethodByOnlyMethod(FindMethod findMethod)
{
this.findMethod = findMethod;
}
private Method findByOnlyMethod(Class clazz)
{
return getMethodOnlyMethod(clazz);
}
public Method get(Class clazz)
{
Method r = null == findMethod ? null : findMethod.get(clazz);
return r == null ? findByOnlyMethod(clazz) : r;
}
}
Usage is quite simple
FindMethod finder = new FindMethodByOnlyMethod(new FindMethodByAnnotation(null));
finder.get(clazz);
... I could switch that to try/catch logic, but that hardly makes it more readable.
Changing the signature of the get... methods so you can use try / catch would be a really bad idea. Exceptions are expensive and should only be used for "exceptional" conditions. And as you say, the code would be less readable.
What is bothering you is the repeating pattern used for flow control--and it should bother you--but there isn't too much to be done about it in Java.
I get really annoyed at repeated code & patterns like this, so for me it would probably be worth it to extract the repeated copy & paste control code and put it in it's own method:
public Method findMethod(Class clazz)
int i=0;
Method candidateMethod = null;
while(candidateMethod == null) {
switch(i++) {
case 0:
candidateMethod = getMethodByAnnotation(clazz);
break;
case 1:
candidateMethod = getMethodByBeingOnlyMethod(clazz);
break;
case 2:
candidateMethod = getMethodByBeingOnlySuitableMethod(clazz);
break;
default:
throw new NoSuitableMethodFoundException(clazz);
}
return clazz;
}
Which has the disadvantage of being unconventional and possibly more verbose, but the advantage of not having as much repeated code (less typos) and reads easier because of there being a little less clutter in the "Meat".
Besides, once the logic has been extracted into it's own class, verbose doesn't matter at all, it's clarity for reading/editing and for me this gives that (once you understand what the while loop is doing)
I do have this nasty desire to do this:
case 0: candidateMethod = getMethodByAnnotation(clazz); break;
case 1: candidateMethod = getMethodByBeingOnlyMethod(clazz); break;
case 2: candidateMethod = getMethodByBeingOnlySuitableMethod(clazz); break;
default: throw new NoSuitableMethodFoundException(clazz);
To highlight what's actually being done (in order), but in Java this is completely unacceptable--you'd actually find it common or preferred in some other languages.
PS. This would be downright elegant (damn I hate that word) in groovy:
actualMethod = getMethodByAnnotation(clazz) ?:
getMethodByBeingOnlyMethod(clazz) ?:
getMethodByBeingOnlySuitableMethod(clazz) ?:
throw new NoSuitableMethodFoundException(clazz) ;
The elvis operator rules. Note, the last line may not actually work, but it would be a trivial patch if it doesn't.