This is an automated email from the ASF dual-hosted git repository.

epugh pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/solr-mcp.git


The following commit(s) were added to refs/heads/main by this push:
     new 2809af2  fix(native): register DefaultMetaProvider reflection hint to 
unbreak nativeTest (#172)
2809af2 is described below

commit 2809af25414a9e92b539a7b77295e0ac48e83dc9
Author: Aditya Parikh <[email protected]>
AuthorDate: Tue Aug 18 16:40:52 2026 -0400

    fix(native): register DefaultMetaProvider reflection hint to unbreak 
nativeTest (#172)
    
    * fix(native): register reflection hint for DefaultMetaProvider
    
    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 <[email protected]>
    Signed-off-by: Aditya Parikh <[email protected]>
    
    * test(config): disable SolrConfigAuthTest in native image
    
    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 <[email protected]>
    Signed-off-by: Aditya Parikh <[email protected]>
    
    * test(native): pin SolrNativeHints registrations with 
RuntimeHintsPredicates
    
    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 <[email protected]>
    Signed-off-by: Aditya Parikh <[email protected]>
    
    ---------
    
    Signed-off-by: Aditya Parikh <[email protected]>
    Co-authored-by: Claude Opus 4.8 <[email protected]>
---
 .../solr/mcp/server/config/SolrNativeHints.java    |  7 ++
 .../solr/mcp/server/config/SolrConfigAuthTest.java |  5 ++
 .../mcp/server/config/SolrNativeHintsTest.java     | 79 ++++++++++++++++++++++
 3 files changed, 91 insertions(+)

diff --git 
a/src/main/java/org/apache/solr/mcp/server/config/SolrNativeHints.java 
b/src/main/java/org/apache/solr/mcp/server/config/SolrNativeHints.java
index 2390626..f8133bf 100644
--- a/src/main/java/org/apache/solr/mcp/server/config/SolrNativeHints.java
+++ b/src/main/java/org/apache/solr/mcp/server/config/SolrNativeHints.java
@@ -115,6 +115,13 @@ public class SolrNativeHints {
                                
hints.reflection().registerTypeIfPresent(classLoader, className, categories);
                        }
 
+                       // Spring AI MCP reflectively instantiates 
DefaultMetaProvider via its
+                       // no-arg constructor in MetaUtils.getMeta() when 
building resource
+                       // specifications. AOT does not generate this hint 
automatically.
+                       hints.reflection().registerTypeIfPresent(classLoader,
+                                       
"org.springaicommunity.mcp.context.DefaultMetaProvider",
+                                       
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
+
                        // Include logback.xml in the native image so logback's 
early
                        // initialization (before Spring Boot) finds it and 
applies the
                        // NopStatusListener. Without this, logback falls 
through to
diff --git 
a/src/test/java/org/apache/solr/mcp/server/config/SolrConfigAuthTest.java 
b/src/test/java/org/apache/solr/mcp/server/config/SolrConfigAuthTest.java
index 8dd5740..7110455 100644
--- a/src/test/java/org/apache/solr/mcp/server/config/SolrConfigAuthTest.java
+++ b/src/test/java/org/apache/solr/mcp/server/config/SolrConfigAuthTest.java
@@ -28,6 +28,7 @@ import java.util.Base64;
 import org.apache.solr.client.solrj.SolrClient;
 import org.apache.solr.client.solrj.impl.HttpJdkSolrClient;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.DisabledInNativeImage;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.CsvSource;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -45,6 +46,10 @@ import org.springframework.util.ReflectionUtils;
  * encoding.
  */
 @JsonTest
+// Reflects into SolrJ's private basicAuthAuthorizationStr field, which is not
+// registered for reflection under GraalVM's closed-world model. The basic-auth
+// wiring logic itself is fully covered by the JVM test run.
+@DisabledInNativeImage
 class SolrConfigAuthTest {
 
        @Autowired
diff --git 
a/src/test/java/org/apache/solr/mcp/server/config/SolrNativeHintsTest.java 
b/src/test/java/org/apache/solr/mcp/server/config/SolrNativeHintsTest.java
new file mode 100644
index 0000000..3e12d09
--- /dev/null
+++ b/src/test/java/org/apache/solr/mcp/server/config/SolrNativeHintsTest.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.solr.mcp.server.config;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.apache.solr.client.solrj.response.QueryResponse;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.aot.hint.MemberCategory;
+import org.springframework.aot.hint.RuntimeHints;
+import org.springframework.aot.hint.TypeReference;
+import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
+
+/**
+ * Verifies that {@link SolrNativeHints.Registrar} registers the reflection and
+ * resource hints the native image depends on.
+ *
+ * <p>
+ * The hints are otherwise only exercised by {@code nativeTest -Pnative} (a 
full
+ * GraalVM build), so an accidentally removed registration would surface as a
+ * hard-to-diagnose native-only startup failure. This test pins the
+ * registrations on the plain JVM path where a regression fails in seconds.
+ */
+class SolrNativeHintsTest {
+
+       private final RuntimeHints hints = new RuntimeHints();
+
+       @BeforeEach
+       void registerHints() {
+               new SolrNativeHints.Registrar().registerHints(hints, 
getClass().getClassLoader());
+       }
+
+       @Test
+       void registersDefaultMetaProviderConstructorHint() {
+               // Spring AI MCP instantiates DefaultMetaProvider reflectively 
in
+               // MetaUtils.getMeta(); without this hint every Spring context 
refresh
+               // fails in native image with "Required no-arg constructor not 
found".
+               assertTrue(RuntimeHintsPredicates.reflection()
+                               
.onType(TypeReference.of("org.springaicommunity.mcp.context.DefaultMetaProvider"))
+                               
.withMemberCategory(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS).test(hints));
+       }
+
+       @Test
+       void registersSolrjResponseTypeHints() {
+               
assertTrue(RuntimeHintsPredicates.reflection().onType(QueryResponse.class)
+                               
.withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
+                                               
MemberCategory.INVOKE_DECLARED_METHODS, MemberCategory.DECLARED_FIELDS)
+                               .test(hints));
+       }
+
+       @Test
+       void registersMcpResponseRecordHints() {
+               assertTrue(RuntimeHintsPredicates.reflection()
+                               
.onType(TypeReference.of("org.apache.solr.mcp.server.search.SearchResponse"))
+                               
.withMemberCategory(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS).test(hints));
+       }
+
+       @Test
+       void registersLogbackXmlResourceHint() {
+               // Required so logback's pre-Spring initialization finds 
logback.xml and
+               // stays silent on stdout (MCP STDIO framing).
+               
assertTrue(RuntimeHintsPredicates.resource().forResource("logback.xml").test(hints));
+       }
+}

Reply via email to