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)
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
inputDirectory
configuration 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
configurationString
during development (e.g.,DEVELOPMENT
)Increase the
verbosity
level to get more detailed information about the processing