Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
166 views
in Technique[技术] by (71.8m points)

java - Set findbugs NotNull as default for all classes under a package

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>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...