apache/shenyu · error · ShenyuException
can not get defaultInstance Field of
Error message
can not get defaultInstance Field of %s
What it means
JsonServerServiceInterceptor.useMarshalledMessages wraps gRPC method descriptors for JSON transcoding. It needs the request message's default instance: first via a 'defaultInstanceField' reflection field, falling back to MethodDescriptor.PrototypeMarshaller.getMessagePrototype(). If neither is available, it cannot determine the request type and throws ShenyuException naming the marshaller class.
Solutions
- Use standard protobuf-generated marshallers (ProtoUtils.marshaller) for the service methods
- Ensure the marshaller's getMessagePrototype() returns a non-null prototype when implementing PrototypeMarshaller
- Upgrade/align grpc version so defaultInstance reflection works as expected
- Catch ShenyuException and fall back to native (non-json) gRPC proxying
Defensive patterns
Strategy: validation
Validate before calling
MethodDescriptor.PrototypeMarshaller<?> pm =
marshaller instanceof MethodDescriptor.PrototypeMarshaller
? (MethodDescriptor.PrototypeMarshaller<?>) marshaller : null;
if (pm == null && ReflectUtils.getField(marshaller.getClass(), "defaultInstance") == null) {
throw new IllegalStateException("marshaller exposes neither defaultInstance nor prototype");
} Try / catch
try { interceptor.useJsonMessages(methodDescriptor); }
catch (ShenyuException e) { log.error("json mode unsupported for this marshaller", e); } Prevention
- Use ProtoUtils.marshaller-generated marshallers for json transcoding
- Implement PrototypeMarshaller.getMessagePrototype() when writing custom marshallers
- Test json mode after grpc version upgrades
When it happens
Trigger: Calling useJsonMessages on a MethodDescriptor whose request marshaller is neither a ProtoLiteUtils marshaller exposing a defaultInstance field nor a PrototypeMarshaller with a non-null message prototype (grpc 1.6.0-era compatibility path).
Common situations: Custom marshallers not generated by grpc's protoc plugin; very old or very new grpc versions where field names/behavior changed; services using hand-written Marshallers.
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 fullMethodName 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/328b54454653c5a8.
Report an issue: GitHub.
Appendix: source
Thrown at shenyu-client/shenyu-client-grpc/src/main/java/org/apache/shenyu/client/grpc/json/JsonServerServiceInterceptor.java:89
* @throws IllegalAccessException IllegalAccessException
*/
public static <T> ServerServiceDefinition useMarshalledMessages(final ServerServiceDefinition serviceDef,
final MethodDescriptor.Marshaller<T> marshaller)
throws IllegalArgumentException, IllegalAccessException {
List<ServerMethodDefinition<?, ?>> wrappedMethods = new ArrayList<>();
List<MethodDescriptor<?, ?>> wrappedDescriptors = new ArrayList<>();
// Wrap the descriptors
for (final ServerMethodDefinition<?, ?> definition : serviceDef.getMethods()) {
MethodDescriptor.Marshaller<?> requestMarshaller = definition.getMethodDescriptor().getRequestMarshaller();
Field defaultInstanceField = ReflectUtils.getField(requestMarshaller.getClass(), "defaultInstance");
Class<?> grpcRequestParamClass = null;
if (Objects.isNull(defaultInstanceField)) {
// Compatible with lower versions. eg: grpc 1.6.0
if (requestMarshaller instanceof MethodDescriptor.PrototypeMarshaller) {
MethodDescriptor.PrototypeMarshaller<?> prototypeMarshaller = (PrototypeMarshaller<?>) requestMarshaller;
if (Objects.isNull(prototypeMarshaller.getMessagePrototype())) {
throw new ShenyuException(String.format("can not get defaultInstance Field of %s", requestMarshaller.getClass()));
}
grpcRequestParamClass = prototypeMarshaller.getMessagePrototype().getClass();
}
} else {
defaultInstanceField.setAccessible(true);
grpcRequestParamClass = defaultInstanceField.get(requestMarshaller).getClass();
}
String fullMethodName = definition.getMethodDescriptor().getFullMethodName();
MethodDescriptor.MethodType methodType = definition.getMethodDescriptor().getType();
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 = originalMethodDescriptorView on GitHub (pinned to 567142e072)