Skip to content

Commit c9efc05

Browse files
Apply Gemini review: null safety, ambiguity detection, List<T> test
- Fix potential NPE on SpringBeanName parameter with null value - Add overloaded method ambiguity detection with warn log - Improve exception handling: ClassNotFoundException/SecurityException at debug level, unexpected exceptions at warn level - Add List<String> test for generic type mapping (7 tests total) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 9573062 commit c9efc05

File tree

2 files changed

+45
-6
lines changed

2 files changed

+45
-6
lines changed

modules/openapi/src/main/java/org/apache/axis2/openapi/OpenApiSpecGenerator.java

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -626,8 +626,10 @@ private com.fasterxml.jackson.databind.node.ObjectNode generateSchemaFromService
626626
if (serviceClass == null && request != null) {
627627
try {
628628
String beanName = null;
629-
if (service.getParameter("SpringBeanName") != null) {
630-
beanName = (String) service.getParameter("SpringBeanName").getValue();
629+
org.apache.axis2.description.Parameter springBeanParam =
630+
service.getParameter("SpringBeanName");
631+
if (springBeanParam != null && springBeanParam.getValue() != null) {
632+
beanName = (String) springBeanParam.getValue();
631633
}
632634
if (beanName != null) {
633635
jakarta.servlet.ServletContext sc = request.getServletContext();
@@ -658,8 +660,14 @@ private com.fasterxml.jackson.databind.node.ObjectNode generateSchemaFromService
658660
java.lang.reflect.Method targetMethod = null;
659661
for (java.lang.reflect.Method m : serviceClass.getMethods()) {
660662
if (m.getName().equals(operationName) && m.getParameterCount() == 1) {
661-
targetMethod = m;
662-
break;
663+
if (targetMethod != null) {
664+
log.warn("[MCP] Ambiguous method '" + operationName
665+
+ "' in " + serviceClass.getName()
666+
+ " — multiple one-arg overloads, using first match");
667+
}
668+
if (targetMethod == null) {
669+
targetMethod = m;
670+
}
663671
}
664672
}
665673
if (targetMethod == null) return null;
@@ -698,9 +706,14 @@ private com.fasterxml.jackson.databind.node.ObjectNode generateSchemaFromService
698706
}
699707

700708
return schema;
701-
} catch (Exception e) {
709+
} catch (ClassNotFoundException | SecurityException e) {
702710
log.debug("[MCP] Could not auto-generate schema for " + service.getName()
703-
+ "/" + operationName + ": " + e.getMessage());
711+
+ "/" + operationName + ": " + e.getClass().getSimpleName()
712+
+ " - " + e.getMessage());
713+
return null;
714+
} catch (Exception e) {
715+
log.warn("[MCP] Unexpected error during auto-schema generation for "
716+
+ service.getName() + "/" + operationName, e);
704717
return null;
705718
}
706719
}

modules/openapi/src/test/java/org/apache/axis2/openapi/McpAutoSchemaTest.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ public static class SampleRequest {
5555
private double[] values;
5656
private double[][] matrix;
5757
private String requestId;
58+
private java.util.List<String> tags;
5859

5960
public int getCount() { return count; }
6061
public void setCount(int count) { this.count = count; }
@@ -72,6 +73,8 @@ public static class SampleRequest {
7273
public void setMatrix(double[][] matrix) { this.matrix = matrix; }
7374
public String getRequestId() { return requestId; }
7475
public void setRequestId(String requestId) { this.requestId = requestId; }
76+
public java.util.List<String> getTags() { return tags; }
77+
public void setTags(java.util.List<String> tags) { this.tags = tags; }
7578
}
7679

7780
public static class SampleResponse {
@@ -275,4 +278,27 @@ public void testBooleanIsGetterDetected() throws Exception {
275278
assertTrue("isActive() should produce active property", props.has("active"));
276279
assertEquals("boolean", props.get("active").get("type").asText());
277280
}
281+
282+
@Test
283+
public void testAutoSchemaGenericListType() throws Exception {
284+
AxisService service = createServiceWithClass("SampleService",
285+
McpAutoSchemaTest.SampleService.class.getName());
286+
addOperation(service, "calculate");
287+
288+
String catalog = generator.generateMcpCatalogJson(null);
289+
JsonNode root = jackson.readTree(catalog);
290+
JsonNode calcTool = null;
291+
for (JsonNode tool : root.get("tools")) {
292+
if ("calculate".equals(tool.get("name").asText())) {
293+
calcTool = tool;
294+
break;
295+
}
296+
}
297+
JsonNode props = calcTool.get("inputSchema").get("properties");
298+
299+
// List<String> -> array of strings
300+
assertTrue("should have tags property", props.has("tags"));
301+
assertEquals("array", props.get("tags").get("type").asText());
302+
assertEquals("string", props.get("tags").get("items").get("type").asText());
303+
}
278304
}

0 commit comments

Comments
 (0)