{"record":{"id":"445a9439bb7ed226","repo":"apache/shenyu","slug":"can-not-get-fullmethodname-field-of-s","errorCode":null,"errorMessage":"can not get fullMethodName Field of %s","messagePattern":"can not get fullMethodName Field of (.+?)","errorType":"exception","errorClass":"ShenyuException","httpStatus":null,"severity":"error","filePath":"shenyu-client/shenyu-client-grpc/src/main/java/org/apache/shenyu/client/grpc/json/JsonServerServiceInterceptor.java","lineNumber":118,"sourceCode":"            METHOD_TYPE_MAP.put(fullMethodName, methodType);\n\n            String[] splitMethodName = fullMethodName.split(\"/\");\n            fullMethodName = splitMethodName[0] + GrpcConstants.GRPC_JSON_SERVICE + \"/\" + splitMethodName[1];\n            REQUEST_CLAZZ_MAP.put(fullMethodName, grpcRequestParamClass);\n\n            final MethodDescriptor<?, ?> originalMethodDescriptor = definition.getMethodDescriptor();\n            final MethodDescriptor<T, T> wrappedMethodDescriptor = originalMethodDescriptor\n                    .toBuilder(marshaller, marshaller).build();\n            wrappedDescriptors.add(wrappedMethodDescriptor);\n            wrappedMethods.add(wrapMethod(definition, wrappedMethodDescriptor));\n        }\n\n        // Build the new service descriptor\n        ServiceDescriptor.Builder build = ServiceDescriptor.newBuilder(serviceDef.getServiceDescriptor().getName() + GrpcConstants.GRPC_JSON_SERVICE);\n        for (MethodDescriptor<?, ?> md : wrappedDescriptors) {\n            Field fullMethodNameField = ReflectUtils.getField(md.getClass(), \"fullMethodName\");\n            if (Objects.isNull(fullMethodNameField)) {\n                throw new ShenyuException(String.format(\"can not get fullMethodName Field of %s\", md.getClass()));\n            }\n            fullMethodNameField.setAccessible(true);\n            String fullMethodName = (String) fullMethodNameField.get(md);\n            String[] splitMethodName = fullMethodName.split(\"/\");\n            fullMethodName = splitMethodName[0] + GrpcConstants.GRPC_JSON_SERVICE + \"/\" + splitMethodName[1];\n            fullMethodNameField.set(md, fullMethodName);\n\n            // Compatible with lower versions. Lower versions do not have this field. eg: grpc 1.6.0\n            Field serviceNameField = ReflectUtils.getField(md.getClass(), \"serviceName\");\n            if (Objects.nonNull(serviceNameField)) {\n                serviceNameField.setAccessible(true);\n                String serviceName = (String) serviceNameField.get(md);\n                serviceName = serviceName + GrpcConstants.GRPC_JSON_SERVICE;\n                serviceNameField.set(md, serviceName);\n            }\n            build.addMethod(md);\n        }\n        final ServerServiceDefinition.Builder serviceBuilder = ServerServiceDefinition","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/apache/shenyu/blob/567142e07261b3e615ae8850b30f4421f455cc5d/shenyu-client/shenyu-client-grpc/src/main/java/org/apache/shenyu/client/grpc/json/JsonServerServiceInterceptor.java#L100-L136","documentation":"In useMarshalledMessages, each wrapped MethodDescriptor's private 'fullMethodName' field is retrieved via reflection so the JSON service suffix can be injected into the method name. If ReflectUtils.getField cannot find that field (grpc internals changed or descriptor is of an unexpected subclass), the interceptor cannot rewrite method names and throws ShenyuException.","triggerScenarios":"Calling useJsonMessages on descriptors where md.getClass() (or its hierarchy) lacks a 'fullMethodName' field — typically after a grpc-java upgrade that renamed/removed the private field.","commonSituations":"Upgrading grpc-java to a version where MethodDescriptor internals changed; custom MethodDescriptor subclasses; security managers or module restrictions hiding private fields.","solutions":["Pin/align the grpc-java version supported by this ShenYu release (check pom dependency management)","Verify MethodDescriptor still declares the private fullMethodName field via reflection debugging","Open the module system / add --add-opens for io.grpc if JPMS restricts reflection","Disable json transcoding mode so descriptors are not rewritten"],"exampleFix":"// before\n<grpc.version>9.9.9</grpc.version>\n// after\n<grpc.version>1.58.0</grpc.version> <!-- version whose MethodDescriptor has fullMethodName field -->","handlingStrategy":"try-catch","validationCode":"if (ReflectUtils.getField(MethodDescriptor.class, \"fullMethodName\") == null\n        && ReflectUtils.getField(md.getClass(), \"fullMethodName\") == null) {\n    throw new IllegalStateException(\"grpc version incompatible with json transcoding\");\n}","typeGuard":null,"tryCatchPattern":"try { interceptor.useJsonMessages(md); }\ncatch (ShenyuException e) { /* fall back to native grpc proxying */ }","preventionTips":["Pin the grpc-java version matching the ShenYu release","Re-run json-mode integration tests after grpc upgrades","Avoid custom MethodDescriptor subclasses in transcoded services"],"tags":["grpc","reflection","version-compatibility"],"backgroundTag":"incompatible-source-type","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"}