{"record":{"id":"2dd8da2fc103427f","repo":"apache/shenyu","slug":"sdk-compatibility-error-failed-to-access-sdk-internal-fields","errorCode":null,"errorMessage":"SDK COMPATIBILITY ERROR: Failed to access SDK internal fields via reflection. This indicates the MCP SDK API has changed. Tested SDK version: ${SUPPORTED_SDK_VERSION}. Error: ${e.getMessage()}","messagePattern":"SDK COMPATIBILITY ERROR: Failed to access SDK internal fields via reflection\\. This indicates the MCP SDK API has changed\\. Tested SDK version: (.+?)\\. Error: (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"critical","filePath":"shenyu-plugin/shenyu-plugin-mcp-server/src/main/java/org/apache/shenyu/plugin/mcp/server/session/McpSessionHelper.java","lineNumber":184,"sourceCode":"     * @return the McpServerSession instance\n     * @throws IllegalStateException if SDK reflection fails (API incompatibility)\n     */\n    public static McpServerSession getSession(final McpSyncServerExchange mcpSyncServerExchange) {\n        checkReflectionAvailability();\n\n        try {\n            Object asyncExchange = asyncExchangeFieldCache.get(mcpSyncServerExchange);\n            if (Objects.isNull(asyncExchange)) {\n                throw new IllegalArgumentException(\"McpAsyncServerExchange is required in McpSyncServerExchange\");\n            }\n            McpAsyncServerExchange mcpAsyncServerExchange = (McpAsyncServerExchange) asyncExchange;\n            Object session = sessionFieldCache.get(mcpAsyncServerExchange);\n            if (Objects.isNull(session)) {\n                throw new IllegalArgumentException(\"Session is required in McpAsyncServerExchange\");\n            }\n            return (McpServerSession) session;\n        } catch (IllegalAccessException e) {\n            throw new IllegalStateException(\n                    \"SDK COMPATIBILITY ERROR: Failed to access SDK internal fields via reflection. \"\n                    + \"This indicates the MCP SDK API has changed. \"\n                    + \"Tested SDK version: \" + SUPPORTED_SDK_VERSION + \". \"\n                    + \"Error: \" + e.getMessage(), e);\n        }\n    }\n\n    /**\n     * Checks if reflection fields are available and throws an informative exception if not.\n     *\n     * @throws IllegalStateException if reflection fields are not available\n     */\n    private static void checkReflectionAvailability() {\n        if (!fieldsResolved || Objects.isNull(asyncExchangeFieldCache) || Objects.isNull(sessionFieldCache)) {\n            // Attempt to re-resolve fields in case of delayed class loading\n            synchronized (FIELD_RESOLVE_LOCK) {\n                if (!fieldsResolved) {\n                    resolveReflectionFields();","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/apache/shenyu/blob/567142e07261b3e615ae8850b30f4421f455cc5d/shenyu-plugin/shenyu-plugin-mcp-server/src/main/java/org/apache/shenyu/plugin/mcp/server/session/McpSessionHelper.java#L166-L202","documentation":"IllegalStateException thrown from McpSessionHelper.getSession's catch (IllegalAccessException) block, wrapped as an 'SDK COMPATIBILITY ERROR'. Field.get() via reflection can throw IllegalAccessException when setAccessible was blocked (security manager, JPMS module encapsulation) or the cached Field no longer matches the class; this indicates the MCP SDK API/layout changed or reflection is restricted. The message includes the tested SDK version (0.17.0) and the original error.","triggerScenarios":"asyncExchangeFieldCache.get(...) or sessionFieldCache.get(...) throws IllegalAccessException during getSession — reflection access to MCP SDK internals is denied at read time even though field resolution succeeded earlier.","commonSituations":"Upgrading the MCP SDK past 0.17.0 so field access is denied; running under a Java security manager or with strong module encapsulation (--illegal-access denied); JDK upgrade tightening reflective access to the SDK package.","solutions":["Pin io.modelcontextprotocol:mcp to 0.17.0 (and Spring AI 1.1.2) and rebuild","Add JVM flags to open the SDK packages, e.g. --add-opens io.modelcontextprotocol.spec/...=ALL-UNNAMED, if module encapsulation blocks access","Remove/disable the security manager or grant ReflectPermission(\"suppressAccessChecks\") in your environment","Upgrade the ShenYu mcp-server plugin to a release tested against your SDK version instead of relying on reflection"],"exampleFix":"// before (java args)\njava -jar shenyu-bootstrap.jar\n// after\njava --add-opens io.modelcontextprotocol.spec/io.modelcontextprotocol.spec=ALL-UNNAMED -jar shenyu-bootstrap.jar","handlingStrategy":"try-catch","validationCode":"if (!McpSessionHelper.isReflectionAvailable()) {\n    throw new IllegalStateException(\"Reflection blocked for MCP SDK; tested version \" + McpSessionHelper.getSupportedSdkVersion());\n}","typeGuard":null,"tryCatchPattern":"try {\n    String id = McpSessionHelper.getSessionId(exchange);\n} catch (IllegalStateException e) {\n    if (e.getMessage().startsWith(\"SDK COMPATIBILITY ERROR\")) {\n        LOG.error(\"MCP SDK reflection denied; check JDK module opens/security manager\", e.getCause());\n    } else throw e;\n}","preventionTips":["Avoid security managers in the gateway JVM","Add --add-opens flags for io.modelcontextprotocol packages on JDK 16+","Pin SDK 0.17.0 and re-run integration tests after any JDK upgrade"],"tags":["mcp","reflection","sdk-compatibility","illegal-access"],"backgroundTag":"deprecated-api-usage","analyzedSha":"567142e07261b3e615ae8850b30f4421f455cc5d","analyzedAt":"2026-09-12T10:08:21.293Z","contentChangedAt":"2026-09-12T10:08:21.293Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}