Error Prone Support is a Picnic-opinionated extension of Google's Error Prone. It aims to improve code quality, focussing on maintainability, consistency and avoidance of common pitfalls.
Error Prone is a static analysis tool for Java that catches common programming mistakes at compile-time.
To learn more about Error Prone (Support), how you can start using Error Prone in practice, and how we use it at Picnic, watch the conference talk Automating away bugs with Error Prone in practice. Also consider checking out the blog post Picnic loves Error Prone: producing high-quality and consistent Java code.
Getting started • Developing Error Prone Support • How it works • Contributing
This library is built on top of Error Prone. To use it, read the installation guide for Maven or Gradle below. The library requires that your build is executed using JDK 17 or above, but supports builds that target older versions of Java.
Next, edit your pom.xml
file to add one or more Error Prone Support
modules to the annotationProcessorPaths
of the maven-compiler-plugin
:
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<!-- Prefer using the latest release. -->
<version>3.12.0</version>
<configuration>
<annotationProcessorPaths>
<!-- Error Prone itself. -->
<path>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_core</artifactId>
<version>${error-prone.version}</version>
</path>
<!-- Error Prone Support's additional bug checkers. -->
<path>
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>error-prone-contrib</artifactId>
<version>${error-prone-support.version}</version>
</path>
<!-- Error Prone Support's Refaster rules. -->
<path>
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>refaster-runner</artifactId>
<version>${error-prone-support.version}</version>
</path>
</annotationProcessorPaths>
<compilerArgs>
<arg>
-Xplugin:ErrorProne
<!-- Add other Error Prone flags here. See
https://errorprone.info/docs/flags. -->
</arg>
<arg>-XDcompilePolicy=simple</arg>
</compilerArgs>
<!-- Enable this if you'd like to fail your build upon warnings. -->
<!-- <failOnWarning>true</failOnWarning> -->
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
gradle-errorprone-plugin
.Next, edit your build.gradle
file to add one or more Error Prone Support
modules:
dependencies {
// Error Prone itself.
errorprone("com.google.errorprone:error_prone_core:${errorProneVersion}")
// Error Prone Support's additional bug checkers.
errorprone("tech.picnic.error-prone-support:error-prone-contrib:${errorProneSupportVersion}")
// Error Prone Support's Refaster rules.
errorprone("tech.picnic.error-prone-support:refaster-runner:${errorProneSupportVersion}")
}
tasks.withType(JavaCompile).configureEach {
options.errorprone.disableWarningsInGeneratedCode = true
// Add other Error Prone flags here. See:
// - https://github.com/tbroyer/gradle-errorprone-plugin#configuration
// - https://errorprone.info/docs/flags
}
Consider the following example code:
import com.google.common.collect.ImmutableSet;
import java.math.BigDecimal;
public class Example {
static BigDecimal getNumber() {
return BigDecimal.valueOf(0);
}
public ImmutableSet<Integer> getSet() {
ImmutableSet<Integer> set = ImmutableSet.of(1);
return ImmutableSet.copyOf(set);
}
}
If the installation was successful, then building the above code with Maven should yield two compiler warnings:
$ mvn clean install
...
[INFO] Example.java:[9,34] [Refaster Rule] BigDecimalRules.BigDecimalZero: Refactoring opportunity
(see https://error-prone.picnic.tech/refasterrules/BigDecimalRules#BigDecimalZero)
Did you mean 'return BigDecimal.ZERO;'?
...
[WARNING] Example.java:[13,35] [IdentityConversion] This method invocation appears redundant; remove it or suppress this warning and add a comment explaining its purpose
(see https://error-prone.picnic.tech/bugpatterns/IdentityConversion)
Did you mean 'return set;' or '@SuppressWarnings("IdentityConversion") public ImmutableSet<Integer> getSet() {'?
...
Two things are kicking in here:
BugChecker
that flags unnecessary
identity conversions.BigDecimal.valueOf(0)
and new BigDecimal(0)
to BigDecimal.ZERO
.Be sure to check out all bug checks and refaster rules.
This is a Maven project, so running mvn clean install
performs a
full clean build and installs the library to your local Maven repository.
Once you've made changes, the build may fail due to a warning or error emitted by static code analysis. The flags and commands listed below allow you to suppress or (in a large subset of cases) automatically fix such cases. Make sure to carefully check the available options, as this can save you significant amounts of development time!
Relevant Maven build parameters:
-Dverification.warn
makes the warnings and errors emitted by various
plugins and the Java compiler non-fatal, where possible.-Dverification.skip
disables various non-essential plugins and compiles the
code with minimal checks (i.e. without linting, Error Prone checks, etc.).-Dversion.error-prone=some-version
runs the build using the specified
version of Error Prone. This is useful e.g. when testing a locally built
Error Prone SNAPSHOT.-Perror-prone-fork
runs the build using Picnic's Error Prone
fork, hosted on Jitpack.
This fork generally contains a few changes on top of the latest Error Prone
release.-Pself-check
runs the checks defined by this project against itself.
Pending a release of google/error-prone#3301, this
flag must currently be used in combination with -Perror-prone-fork
.Other highly relevant commands:
mvn fmt:format
formats the code using
google-java-format
../run-full-build.sh
builds the project twice,
where the second pass validates compatbility with Picnic's Error Prone
fork and compliance of the code with any rules
defined within this project. (Consider running this before opening a pull
request, as the PR checks also perform this
validation.)./apply-error-prone-suggestions.sh
applies Error Prone and Error Prone Support code suggestions to this project.
Before running this command, make sure to have installed the project (mvn clean install
) and make sure that the current working directory does not
contain unstaged or uncommited changes../run-branch-mutation-tests.sh
uses
Pitest to run mutation tests against code that is modified relative
to the upstream default branch. The results can be reviewed by opening the
respective target/pit-reports/index.html
files. One can use
./run-mutation-tests.sh
to run mutation tests
against all code in the current working directory. For more information
check the PIT Maven plugin.When running the project's tests in IntelliJ IDEA, you might see the following error:
java: exporting a package from system module jdk.compiler is not allowed with --release
If this happens, go to Settings -> Build, Execution, Deployment -> Compiler -> Java Compiler and deselect the option Use '--release' option for cross-compilation (Java 9 and later). See IDEA-288052 for details.
This project provides additional BugChecker
implementations.
Want to report or fix a bug, suggest or add a new feature, or improve the documentation? That's awesome! Please read our contribution guidelines.
If you want to report a security vulnerability, please do so through a private channel; please see our security policy for details.