The Cabe Maven Plugin
The Cabe Maven Plugin is a community-contributed plugin that integrates Cabe bytecode instrumentation with Maven projects. Cabe is a Java bytecode instrumentation tool that inserts runtime checks based on JSpecify annotations into your class files.
Purpose and Benefits
Cabe helps implement the Fail-Fast Principle by automatically adding runtime checks for annotated method parameters. This provides several benefits:
Early Detection: Violations of nullability contracts are detected immediately at the point of violation
Improved Debugging: Clear error messages that identify the exact parameter that violated the contract
Reduced Boilerplate: No need to manually write null checks for annotated parameters
Consistent Enforcement: Ensures that nullability contracts are enforced consistently across your codebase
Requirements
Java 17 or later
Maven 3.6.0 or later
JSpecify annotations (typically org.jspecify:jspecify:1.0.0)
Usage
1. Add the Plugin to Your POM
Add the Cabe Maven Plugin to your project's pom.xml:
2. Configure the Compiler to Use a Separate Output Directory
To avoid processing class files multiple times, configure the Maven Compiler Plugin to output compiled classes to a separate directory:
3. Configure the Cabe Plugin
Configure the Cabe plugin to process the unprocessed classes:
4. Add JSpecify Dependency
Add the JSpecify annotations to your project:
5. Use JSpecify Annotations in Your Code
Use JSpecify annotations in your code to specify nullability contracts:
Configuration Options
The Cabe Maven Plugin supports the following configuration options:
verbosity
Controls the level of logging output.
Possible values:
0: Show warnings and errors only (default)
1: Show basic processing information
2: Show detailed information
3: Show all information
inputDirectory
The directory containing the compiled class files to process.
Default: ${project.build.outputDirectory}
outputDirectory
The directory where processed class files will be written.
Default: ${project.build.outputDirectory}
configurationString
The configuration mode for Cabe processing.
Possible values:
STANDARD: Use standard assertions for private API methods, throw NullPointerException for public API methods (default)
DEVELOPMENT: Failed checks will always throw an AssertionError, also checks return values
NO_CHECKS: Do not add any null checks (class files are copied unchanged)
Custom configuration string: For advanced configuration (see Cabe documentation for details)
strict
Whether to enable strict mode for equals(Object) checks.
Default value is false. When set to true, instrumentation will fail if the equals(Object) contract is violated. When set to false, a warning will be logged instead.
Complete Example
Here's a complete example of a Maven project using the Cabe Maven Plugin:
Troubleshooting
Common Issues
Class Files Not Being Processed
If your class files aren't being processed, check:
The
inputDirectoryconfiguration is correctThe Maven Compiler Plugin is configured to output to the correct directory
The Cabe plugin is bound to the correct phase (default is
process-classes)
NoClassDefFoundError for JSpecify Annotations
If you get NoClassDefFoundError for JSpecify annotations at runtime, make sure:
The JSpecify dependency is correctly added to your project
The dependency scope is appropriate (usually
compile)
Unexpected NullPointerExceptions
If you're getting unexpected NullPointerExceptions:
Check that your code respects the nullability contracts specified by the annotations
Consider using a different
configurationStringduring development (e.g.,DEVELOPMENT)Increase the
verbositylevel to get more detailed information about the processing