I have the simple code below for testing the FindBugs @NonNull
annotation with Maven. I execute
mvn clean install
And it correctly fails to build because print(null)
violates the non-null condition.
You can set NonNull
as default for all method parameters inside a class using the class annotation
@DefaultAnnotation(NonNull.class)
How can I set NonNull
as default for all method parameters inside all classes under a given package (and sub-packages)?
src/main/java/test/Hello.java
package test;
import edu.umd.cs.findbugs.annotations.NonNull;
public class Hello {
static public void print(@NonNull Object value) {
System.out.println("value: " + value.toString());
}
static public void main(String[] args) {
if (args.length > 0) {
print(args[0]);
} else {
print(null);
}
}
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>hello</groupId>
<artifactId>hello</artifactId>
<version>1.0</version>
<dependencies>
<dependency>
<groupId>net.sourceforge.findbugs</groupId>
<artifactId>annotations</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>net.sourceforge.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>1.3.7</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>2.5.2</version>
<configuration>
<includeTests>true</includeTests>
</configuration>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
<execution>
<id>findbugs-test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
You can do this to parameters, fileds and method return value simultaneously by putting these lines in your package-info.java:
@DefaultAnnotation(NonNull.class)
package com.my.package;
When findbugs runs on the code in that package, all methods and fields are assumed to be non-null unless you annotate them with @CheckForNull.
I also do not know of a way to make this apply to sub-packages. I do this for each package.
You can do this for individual packages, but I haven't found a way to have it propagate to subpackages. For method parameters use the built-in package annotation @ParametersAreNonnullByDefault
. Apply the annotation to the package in its package-info.java
file inside the package's directory.
Note that I'm using the
javax.annotation
annotations from JSR-305 which FindBugs honors.
com/example/foo/package-info.java
/**
* Package that doesn't allow null values as method parameters.
*/
@ParametersAreNonnullByDefault
package com.example.foo;
import javax.annotation.ParametersAreNonnullByDefault;
For fields and method return values you'll need to create your own annotations. I did this by copying the source for ParametersAreNonnullByDefault
and changing the ElementType
enum.
com/example/util/FieldsAreNonnullByDefault.java
package com.example.util;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import javax.annotation.Nonnull;
import javax.annotation.meta.TypeQualifierDefault;
/**
* Applies the {@link Nonnull} annotation to every class field unless overridden.
*/
@Documented
@Nonnull
@TypeQualifierDefault(ElementType.FIELD) // <-- use METHOD for return values
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldsAreNonnullByDefault
{
// nothing to add
}
I began rewriting a fairly complex system from scratch a couple months ago, and every package has these three annotations applied (fields, parameters, and return values). One benefit that's come out of the incentive to avoid null
values is using the Null Object pattern where appropriate. That combined with favoring final fields as much as possible and small classes that do one thing only has really kept the code clean.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With