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

  1. Pin/align the grpc-java version supported by this ShenYu release (check pom dependency management)
  2. Verify MethodDescriptor still declares the private fullMethodName field via reflection debugging
  3. Open the module system / add --add-opens for io.grpc if JPMS restricts reflection
  4. 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

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


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 = ServerServiceDefinition

View on GitHub (pinned to 567142e072)