Skip to content

fix(native): register DefaultMetaProvider reflection hint to unbreak nativeTest - #172

Open
adityamparikh wants to merge 3 commits into
apache:mainfrom
adityamparikh:fix/native-defaultmetaprovider-hint
Open

fix(native): register DefaultMetaProvider reflection hint to unbreak nativeTest#172
adityamparikh wants to merge 3 commits into
apache:mainfrom
adityamparikh:fix/native-defaultmetaprovider-hint

Conversation

@adityamparikh

@adityamparikh adityamparikh commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Summary

./gradlew nativeTest -Pnative fails on every branch and PR (e.g. PR #159's run: 68 test failures). All failures collapse to a single root cause during ApplicationContext refresh:

IllegalArgumentException: Required no-arg constructor not found in
  org.springaicommunity.mcp.context.DefaultMetaProvider
    at org.springaicommunity.mcp.MetaUtils.getMeta(MetaUtils.java:63)
    at org.springaicommunity.mcp.provider.resource.SyncStatelessMcpResourceProvider.lambda$getResourceSpecifications$2(...)
...
Caused by: java.lang.NoSuchMethodException:
  org.springaicommunity.mcp.context.DefaultMetaProvider.<init>()

The context fails to load 8 times and the remaining ~60 tests cascade-fail on ApplicationContext failure threshold (1) exceeded.

Root cause

Spring AI 1.1.6 introduced a MetaUtils.getMeta() call path in the sync resource providers that reflectively invokes the no-arg constructor of DefaultMetaProvider when building the resourceSpecs bean. Spring AOT does not generate a reflection hint for it, so the constructor is invisible in GraalVM's closed world. Because resourceSpecs is part of the real application context (not just tests), the native server binary is affected too — currently masked in CI because the docker integration tests fail earlier on an image-tag mismatch (companion PR: #173).

Changes

  1. fix(native): register MemberCategory.INVOKE_DECLARED_CONSTRUCTORS for org.springaicommunity.mcp.context.DefaultMetaProvider in SolrNativeHints, alongside the existing SolrJ and MCP response-record hints. registerTypeIfPresent keeps it a no-op if a future Spring AI release removes or relocates the class.
  2. test(config): @DisabledInNativeImage on SolrConfigAuthTest. It reflects into SolrJ's private basicAuthAuthorizationStr field, which is not registered for reflection in the closed world, so its 5 tests fail in nativeTest (they pass on the JVM, which fully covers the basic-auth wiring). This second gap is currently masked by the DefaultMetaProvider failure — fixing only that one would leave nativeTest red with these 5.

Verification (local, GraalVM CE 25 / macOS arm64)

  • Before: nativeTest -Pnative reproduces CI's failure (every @SpringBootTest fails on DefaultMetaProvider; with only the hint fix applied, 5 SolrConfigAuthTest failures remain).
  • After both commits: nativeTest -Pnative → 213 tests successful, 0 failed (136 skipped: the Mockito/@DisabledInNativeImage set).
  • ./gradlew spotlessCheck build passes (JVM path unaffected).
  • Additionally verified the pair with fix(test): restore docker image tag suffix for native integration tests #173 end-to-end: bootBuildImage -Pnative + dockerIntegrationTest -Pnative → the native stdio image passes the MCP protocol suite (39 tests) and smoke tests. The http leg as well: dockerIntegrationTest -Pnative -Pprofile=httpDockerImageHttpIntegrationTest (6 tests) passes against solr-mcp:1.0.0-SNAPSHOT-native-http.

Merge order

This PR and #173 are independent to review but jointly required for a green native.yml: this one fixes the nativeTest job; the companion fixes the image tag the docker jobs resolve. Suggest merging this one first (its docker jobs will still be red on the pre-existing tag mismatch), then the companion turns the matrix fully green.

🤖 Generated with Claude Code

adityamparikh and others added 2 commits July 30, 2026 22:32
Spring AI 1.1.6 introduced a MetaUtils.getMeta() call path in the sync
resource providers that reflectively invokes the no-arg constructor on
org.springaicommunity.mcp.context.DefaultMetaProvider. AOT does not
generate this hint, so every @SpringBootTest fails in nativeTest with:

    IllegalArgumentException: Required no-arg constructor not found in
    org.springaicommunity.mcp.context.DefaultMetaProvider
    ...
    Caused by: NoSuchMethodException:
    org.springaicommunity.mcp.context.DefaultMetaProvider.<init>()

during ApplicationContext refresh, and the remaining tests cascade-fail
on "ApplicationContext failure threshold (1) exceeded".

Register the constructor hint in SolrNativeHints alongside the existing
SolrJ and MCP response-record hints. registerTypeIfPresent keeps it a
no-op if a future Spring AI release removes or relocates the class.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Aditya Parikh <aditya.m.parikh@gmail.com>
The test reflects into SolrJ's private basicAuthAuthorizationStr field to
verify basic-auth wiring. That field is not registered for reflection under
GraalVM's closed-world model, so ReflectionUtils.findField returns null and
the assertion fails in nativeTest (it passes on the JVM). The basic-auth
wiring logic itself is fully covered by the JVM test run, so disable the
reflection-based assertions in native image, matching the repo convention
for tests that don't survive the closed-world assumption.

This failure is currently masked in CI: every @SpringBootTest fails first
on the DefaultMetaProvider reflection gap fixed in the previous commit.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Aditya Parikh <aditya.m.parikh@gmail.com>
…icates

Review follow-up on this PR. The hints were previously exercised only by
nativeTest -Pnative (a full GraalVM build), so an accidentally removed
registration would surface as a hard-to-diagnose native-only startup
failure. SolrNativeHintsTest pins the DefaultMetaProvider constructor
hint, a representative SolrJ type, an MCP response record, and the
logback.xml resource pattern on the plain JVM path, where a regression
fails in seconds.

Also moves the SolrConfigAuthTest disable rationale above the annotation
so spotless stops mangling the comment wrap.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Aditya Parikh <aditya.m.parikh@gmail.com>
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.

1 participant