Skip to content

Enable NullAway static null-safety analysis for util module#10046

Open
Apisapple wants to merge 30 commits intobesu-eth:mainfrom
Apisapple:main
Open

Enable NullAway static null-safety analysis for util module#10046
Apisapple wants to merge 30 commits intobesu-eth:mainfrom
Apisapple:main

Conversation

@Apisapple
Copy link
Contributor

@Apisapple Apisapple commented Mar 14, 2026

PR description

This PR enables NullAway static null-safety analysis for the util module as a pilot and fixes all violations surfaced by the check.

Summary of changes

  • Enable NullAway at ERROR severity for util production compilation via Error Prone.
  • Disable NullAway for util test compilation for this pilot.
  • Add dependency verification metadata entries required by NullAway and related transitive artifacts.
  • Apply null-safety fixes and JSpecify nullable contracts across util classes, including PlatformDetector, BesuVersionUtils, ExceptionUtils, MemoryBoundCache, RollingFileWriter, and StackTraceMatchFilter.
  • NullAway is compiler-only via Error Prone and does not add runtime artifacts to util.

Developer setup

  • In IntelliJ, set Build and run using to Gradle so NullAway diagnostics appear during normal IDE builds.
  • No additional Gradle wiring is required beyond the current Error Prone plus NullAway setup for this pilot.
  • If we expand to other modules later, shared NullAway options can be centralized in a common convention plugin.

Validation

  • spotless: ./gradlew spotlessApply
  • module build with NullAway: ./gradlew :util:build
  • optional broader compile check: ./gradlew build -x test

Fixed Issue(s)

fixes #10004

Thanks for sending a pull request! Have you done the following?

  • Checked out our contribution guidelines?
  • Considered documentation and added the doc-change-required label to this PR if updates are required.
  • Considered the changelog and included an update if required.
  • For database changes (e.g. KeyValueSegmentIdentifier) considered compatibility and performed forwards and backwards compatibility tests

Locally, you can run these tests to catch failures early:

  • spotless: ./gradlew spotlessApply
  • unit tests: ./gradlew build
  • acceptance tests: ./gradlew acceptanceTest
  • integration tests: ./gradlew integrationTest
  • reference tests: ./gradlew ethereum:referenceTests:referenceTests
  • hive tests: Engine or other RPCs modified?

Apisapple and others added 27 commits March 7, 2026 03:15
- Replace javax.annotation.Nullable and javax.annotation.CheckForNull with org.jspecify.annotations.Nullable across 18 Java files
- Update platform constraint to org.jspecify:jspecify:1.0.0
- Replace compileOnly com.google.code.findbugs:jsr305 with compileOnly org.jspecify:jspecify in affected modules

Signed-off-by: Mykim <38449976+Apisapple@users.noreply.github.com>
Migrate JSR305 nullness annotations to JSpecify
Signed-off-by: mykim <kimminyong2034@gmail.com>
- Add NullAway 0.12.4 to util errorprone dependencies
- Annotate nullable fields/returns in 6 util classes with @nullable
- Fix nullable dereferences: RollingFileWriter, StackTraceMatchFilter, PlatformDetector
- Enable NullAway:ERROR for util main compile, OFF for tests
- Add optional CI job (run-nullaway label) for gradual monitoring
- All util compilation passes with NullAway ERROR by default

Fixes:
  - MemoryBoundCache: mark getIfPresent() return as @nullable
  - ExceptionUtils: annotate rootCause() for nullable input/output
  - RollingFileWriter: guard Path.getParent() null dereference
  - PlatformDetector: make static fields @nullable, add fallback to UNKNOWN
  - BesuVersionUtils: mark VERSION/COMMIT fields as @nullable
  - StackTraceMatchFilter: fix nullable message comparison, builder fields
Signed-off-by: mykim <kimminyong2034@gmail.com>
…ilter

Signed-off-by: mykim <kimminyong2034@gmail.com>
… null

Replace null return with UNKNOWN to satisfy NullAway @nonnull contract.

Signed-off-by: mykim <kimminyong2034@gmail.com>
- Return null to account for existing code that expects and handles null values.

Signed-off-by: mykim <kimminyong2034@gmail.com>
- Remove the unnecessary -PenableNullAway flag

Signed-off-by: mykim <kimminyong2034@gmail.com>
- Update the Javadoc to reflect the actual behavior of the getGlibc function.

Signed-off-by: mykim <kimminyong2034@gmail.com>
Signed-off-by: mykim <kimminyong2034@gmail.com>
Signed-off-by: mykim <kimminyong2034@gmail.com>
Signed-off-by: mykim <kimminyong2034@gmail.com>
Copilot AI review requested due to automatic review settings March 14, 2026 19:16
@Apisapple Apisapple marked this pull request as draft March 14, 2026 19:16
Adjust indentation of GRADLEW_UNIT_TEST_ARGS in .github/workflows/pre-review.yml under unitTests.env to align with surrounding keys.

Signed-off-by: mykim <kimminyong2034@gmail.com>
@Apisapple Apisapple marked this pull request as ready for review March 14, 2026 19:19
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Enable NullAway (via Error Prone) for the util module and resolve the surfaced null-safety issues by adding JSpecify nullability contracts and small behavior tweaks.

Changes:

  • Turn on NullAway at ERROR severity for :util production compilation and disable it for :util test compilation (pilot).
  • Add NullAway (and transitive artifacts) to dependency verification metadata.
  • Apply null-safety fixes and nullable annotations across several util classes (platform detection, logging filter, IO writer, cache, version/helpers).

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
util/src/main/java/org/hyperledger/besu/util/platform/PlatformDetector.java Annotate cached fields nullable; harden property/version normalization; adjust JNA signature nullability.
util/src/main/java/org/hyperledger/besu/util/log4j/plugin/StackTraceMatchFilter.java Make config fields nullable; avoid NPE on throwable message; adjust matching/toString behavior.
util/src/main/java/org/hyperledger/besu/util/io/RollingFileWriter.java Guard against Path#getParent() returning null before mkdirs.
util/src/main/java/org/hyperledger/besu/util/cache/MemoryBoundCache.java Mark getIfPresent return value as nullable.
util/src/main/java/org/hyperledger/besu/util/ExceptionUtils.java Accept nullable input and return nullable root cause.
util/src/main/java/org/hyperledger/besu/util/BesuVersionUtils.java Mark version/commit as nullable and propagate via accessors.
util/build.gradle Enable/disable NullAway per source set; add NullAway to errorprone configuration.
gradle/verification-metadata.xml Add verification entries for NullAway and transitive dependencies.

Comment on lines +38 to +41
private static final @Nullable String VERSION;
private static final String OS = PlatformDetector.getOS();
private static final String VM = PlatformDetector.getVM();
private static final String COMMIT;
private static final @Nullable String COMMIT;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like we may need to modify the test code to apply this change, so I need to confirm whether it's okay to proceed with those updates.

Comment on lines +81 to 83
public static @Nullable String shortVersion() {
return VERSION;
}
Comment on lines +123 to 125
public static @Nullable String commit() {
return COMMIT;
}
public class StackTraceMatchFilter extends AbstractFilter {
private final String stackContains;
private final String messageEquals;
private final @Nullable String stackContains;
private StackTraceMatchFilter(
final String stackContains,
final String messageEquals,
final @Nullable String stackContains,
Comment on lines +78 to 82
return (messageEquals == null || Objects.equals(t.getMessage(), messageEquals))
&& stackContains != null
&& Arrays.stream(t.getStackTrace())
.map(StackTraceElement::getClassName)
.anyMatch(cn -> cn.contains(stackContains))
Comment on lines +54 to +60
final Path parentPath = firstOutputFile.getParent();
if (parentPath != null) {
final File parentDir = parentPath.toFile();
if (!parentDir.exists()) {
//noinspection ResultOfMethodCallIgnored
parentDir.mkdirs();
}
Comment on lines +331 to +334
final Pattern pattern = Pattern.compile("[-+]?[\\d]*\\.?[\\d]+");
final Matcher matcher = pattern.matcher(rawGlibcVersion);

return matcher.find() ? matcher.group() : null;
return matcher.find() ? matcher.group() : UNKNOWN;
@Apisapple Apisapple marked this pull request as draft March 15, 2026 17:15
@Apisapple Apisapple closed this Mar 15, 2026
@Apisapple Apisapple reopened this Mar 15, 2026
@Apisapple Apisapple marked this pull request as ready for review March 15, 2026 17:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Integrate NullAway for build-time null-safety checks

3 participants