I discovered error-prone some years ago, but didn’t take a chance to use it, but this week I was reminded about it by someone on Twitter and decided now it was time.
What is error prone
?
Error Prone is a static analysis tool for Java, developed by Google, designed to identify and correct bugs in Java code at compile-time.
Key features include:
- Bug Pattern Detection: Scans for common mistakes based on experienced developers’ insights.
- Compile-Time Integration: Operates during compilation, catching errors earlier than later.
- Customizable: Comes with default checks but can be extended for project-specific needs, for example with the picnic support library.
- Automated Fixes: Can apply fixes, called refaster templates.
Use it with Maven
At work, we use Maven and Java 17, so I will explain here how to use Error Prone with these two. We also use Lombok and MapStruct that have their own annotation processors.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>17</source>
<target>17</target>
<encoding>UTF-8</encoding>
<!-- Display warnings in the logs, otherwise you won't know about some
things discovered by Error Prone -->
<showWarnings>true</showWarnings>
<!-- Whether you want to fail the build if any warning is found,
I don't, because I prefer to lift a rule to level ERROR for specific rules -->
<failOnWarning>false</failOnWarning>
<compilerArgs>
<!-- this is for JDK 16+ -->
<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED</arg>
<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED</arg>
<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED</arg>
<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED</arg>
<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED</arg>
<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED</arg>
<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED</arg>
<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED</arg>
<arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED</arg>
<arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED</arg>
<!-- this is for Error Prone -->
<arg>-XDcompilePolicy=simple</arg>
<arg>-Xplugin:ErrorProne -XepExcludedPaths:.*/target/.* -Xep:BigDecimalEquals:ERROR -Xep:BigDecimalLiteralDouble:ERROR</arg>
<!-- here comes your own javac parameters -->
<arg>-parameters</arg>
<arg>-Amapstruct.defaultComponentModel=spring</arg>
</compilerArgs>
<annotationProcessorPaths>
<path>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_core</artifactId>
<version>2.23.0</version>
</path>
<path>
<groupId>tech.picninc.error-prone-support</groupId>
<artifactId>error-prone-contrib</artifactId>
<version>0.14.0</version>
</path>
<!-- .. your other processors: mapstruct, lombok, jpamodelgen, ... -->
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
Some difficulties that I encountered while trying to install it based on the installation guide, are:
- The
.mvn/.jvmconfig
file works well with Maven, and for IntelliJ only if your project is a simple maven module, if you have a multi-module then it is apparently not supported by IntelliJ yet, this is why I decided to pass the parameters tojavac
as<arg>
in the maven config - You enable Error Prone using
-Xplugin:ErrorProne
as an<arg>
value - You can (and should) discard some directories like
target/
because it may contain generated code that you don’t have control on (for example OpenAPI generated source code). - You can lift the level of the bug patterns, for example above I decided that we should not use
equals
to compareBigDecimal
, this is checked by the bug pattern named BigDecimalEquals, but this pattern has a default level ofWARNING
, so you can lift it toERROR
using-Xep:BigDecimalEquals:ERROR
.
What is more important to know is that if you want to change the level of multiple patterns, they all have to be put in the same <arg>
XML tag.
Using the panic contrib
You can see above that I included Error Prone Support from Picnic which contains a set of additional bug patterns and refaster rules.
Build time
Just know that it adds a significant amount of time to the build, at work I am working on multiple projects, the main one is taking 35 seconds to compile, but when Error Prone is enabled it will take almost 1min30, this is why I moved this behind a maven profile named error-prone
so that we can use it or not depending on the case.
Until next time!