apache/shenyu · error · ShenyuException
can not get fullMethodName Field of
Error message
can not get fullMethodName Field of %s
What it means
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.
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
Example fix
// before <grpc.version>9.9.9</grpc.version> // after <grpc.version>1.58.0</grpc.version> <!-- version whose MethodDescriptor has fullMethodName field -->
Defensive patterns
Strategy: try-catch
Validate before calling
if (ReflectUtils.getField(MethodDescriptor.class, "fullMethodName") == null
&& ReflectUtils.getField(md.getClass(), "fullMethodName") == null) {
throw new IllegalStateException("grpc version incompatible with json transcoding");
} Try / catch
try { interceptor.useJsonMessages(md); }
catch (ShenyuException e) { /* fall back to native grpc proxying */ } Prevention
- 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
When it happens
Trigger: 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.
Common situations: Upgrading grpc-java to a version where MethodDescriptor internals changed; custom MethodDescriptor subclasses; security managers or module restrictions hiding private fields.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- build json response message is error, newBuilder method is…
- can not get defaultInstance Field of
- the validation ExistProviderMethod invoked error
- grpc client must config the contextPath, ipAndPort
- args.length < types.length
AI-assisted analysis of apache/shenyu@567142e072 (2026-09-12).
Data as JSON: /api/errors/445a9439bb7ed226.
Report an issue: GitHub.
Appendix: source
Thrown at shenyu-client/shenyu-client-grpc/src/main/java/org/apache/shenyu/client/grpc/json/JsonServerServiceInterceptor.java:118
METHOD_TYPE_MAP.put(fullMethodName, methodType);
String[] splitMethodName = fullMethodName.split("/");
fullMethodName = splitMethodName[0] + GrpcConstants.GRPC_JSON_SERVICE + "/" + splitMethodName[1];
REQUEST_CLAZZ_MAP.put(fullMethodName, grpcRequestParamClass);
final MethodDescriptor<?, ?> originalMethodDescriptor = definition.getMethodDescriptor();
final MethodDescriptor<T, T> wrappedMethodDescriptor = originalMethodDescriptor
.toBuilder(marshaller, marshaller).build();
wrappedDescriptors.add(wrappedMethodDescriptor);
wrappedMethods.add(wrapMethod(definition, wrappedMethodDescriptor));
}
// Build the new service descriptor
ServiceDescriptor.Builder build = ServiceDescriptor.newBuilder(serviceDef.getServiceDescriptor().getName() + GrpcConstants.GRPC_JSON_SERVICE);
for (MethodDescriptor<?, ?> md : wrappedDescriptors) {
Field fullMethodNameField = ReflectUtils.getField(md.getClass(), "fullMethodName");
if (Objects.isNull(fullMethodNameField)) {
throw new ShenyuException(String.format("can not get fullMethodName Field of %s", md.getClass()));
}
fullMethodNameField.setAccessible(true);
String fullMethodName = (String) fullMethodNameField.get(md);
String[] splitMethodName = fullMethodName.split("/");
fullMethodName = splitMethodName[0] + GrpcConstants.GRPC_JSON_SERVICE + "/" + splitMethodName[1];
fullMethodNameField.set(md, fullMethodName);
// Compatible with lower versions. Lower versions do not have this field. eg: grpc 1.6.0
Field serviceNameField = ReflectUtils.getField(md.getClass(), "serviceName");
if (Objects.nonNull(serviceNameField)) {
serviceNameField.setAccessible(true);
String serviceName = (String) serviceNameField.get(md);
serviceName = serviceName + GrpcConstants.GRPC_JSON_SERVICE;
serviceNameField.set(md, serviceName);
}
build.addMethod(md);
}
final ServerServiceDefinition.Builder serviceBuilder = ServerServiceDefinitionView on GitHub (pinned to 567142e072)