Skip to content

fix: mark InstrumentationState callback params as @Nullable - #4435

Open
arimu1 wants to merge 1 commit into
graphql-java:masterfrom
arimu1:fix/4433-nullable-instrumentation-state
Open

fix: mark InstrumentationState callback params as @Nullable#4435
arimu1 wants to merge 1 commit into
graphql-java:masterfrom
arimu1:fix/4433-nullable-instrumentation-state

Conversation

@arimu1

@arimu1 arimu1 commented Aug 5, 2026

Copy link
Copy Markdown

Summary

Fixes #4433

After the JSpecify instrumentation annotations in #4272, SimplePerformantInstrumentation (and related @NullMarked instrumentation types) exposed unannotated InstrumentationState callback parameters as non-null to Kotlin. At runtime, createState() / createStateAsync() remain nullable and SimplePerformantInstrumentation.createState() returns null by default, so Kotlin subclasses that override hooks without providing a marker state fail with:

Parameter specified as non-null is null: method … beginExecution, parameter state

This change annotates callback state parameters as @Nullable to match the existing optional-state runtime contract (preferred fix from the issue).

Changes

  • Annotate InstrumentationState callback parameters @Nullable on Instrumentation, SimplePerformantInstrumentation, ChainedInstrumentation, NoContextChainedInstrumentation, and built-in implementors that override those hooks
  • ChainedInstrumentation asserts non-null when casting to its own ChainedInstrumentationState (always materialized via createStateAsync)
  • Spock coverage for null default createState and full execution with a stateless SimplePerformantInstrumentation subclass

Test plan

  • ./gradlew test --tests graphql.execution.instrumentation.InstrumentationDefaultMethodsTest --tests graphql.execution.instrumentation.InstrumentationTest --tests graphql.execution.instrumentation.ChainedInstrumentationStateTest --tests graphql.execution.instrumentation.NoContextChainedInstrumentationTest --tests graphql.execution.instrumentation.TracingInstrumentationTest (36 tests, Temurin 21)
  • ./gradlew compileJava (NullAway / ErrorProne clean)

createState()/createStateAsync() may return null, and the default
SimplePerformantInstrumentation.createState() does. After @NullMarked
on instrumentation classes (graphql-java#4272), unannotated state parameters were
treated as non-null in Kotlin, causing NPEs for stateless subclasses.

Annotate callback state parameters as @nullable to match the optional-
state runtime contract. ChainedInstrumentation asserts non-null when
casting its own materialized ChainedInstrumentationState.

Fixes graphql-java#4433
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.

SimplePerformantInstrumentation hooks declares InstrumentationState non-null but createState returns null by default

1 participant