apache/shenyu · error · RuntimeException

dynamic build JsonMarshaller descriptor is fail

Error message

dynamic build JsonMarshaller descriptor is fail

What it means

JsonMessage.jsonDescriptor builds a protobuf FileDescriptor at runtime from a generated FileDescriptorProto for the JSON message type. If Descriptors.FileDescriptor.buildFrom throws DescriptorValidationException, the dynamically constructed descriptor is invalid, and the code logs the cause and rethrows a RuntimeException with this message. This typically means the embedded proto definition is malformed or inconsistent.

Solutions

  1. Read the logged DescriptorValidationException message (the 'Caused by' in the stack trace) to identify the exact invalid element, then fix the descriptor/proto resource.
  2. Use a consistent, unmodified shenyu-protocol-grpc artifact; restore the original JSON descriptor proto resources if they were customized.
  3. Align the protobuf-java runtime version with the one the descriptors were generated for.
  4. Clear stale build artifacts and rebuild shenyu-protocol-grpc so descriptor resources regenerate cleanly.
Defensive patterns

Strategy: try-catch

Try / catch

try {
    return jsonDescriptor();
} catch (RuntimeException e) {
    if ("dynamic build JsonMarshaller descriptor is fail".equals(e.getMessage())) {
        LOG.error("descriptor build failed; check protobuf resources/version", e.getCause());
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling JsonMessage.jsonDescriptor()/buildJsonMarshallerDescriptor when the FileDescriptorProto for GrpcConstants.JSON_DESCRIPTOR_PROTO_NAME fails validation — e.g. dependency type references not resolvable, duplicate type names, or a corrupted/modified proto descriptor resource.

Common situations: Mismatches between the shenyu-protocol-grpc version and the proto assets it bundles; custom builds where JSON_DESCRIPTOR_PROTO resources were modified; protobuf-java runtime version incompatibilities with descriptor features used in the generated proto.

Related errors


AI-assisted analysis of apache/shenyu@567142e072 (2026-09-12). Data as JSON: /api/errors/31035cb4ce01b864. Report an issue: GitHub.

Appendix: source

Thrown at shenyu-protocol/shenyu-protocol-grpc/src/main/java/org/apache/shenyu/protocol/grpc/message/JsonMessage.java:77

        DescriptorProtos.DescriptorProto.Builder jsonMarshaller = DescriptorProtos.DescriptorProto.newBuilder();
        jsonMarshaller.setName(GrpcConstants.JSON_DESCRIPTOR_PROTO_NAME);
        jsonMarshaller.addFieldBuilder()
                .setName(GrpcConstants.JSON_DESCRIPTOR_PROTO_FIELD_NAME)
                .setNumber(1)
                .setType(DescriptorProtos.FieldDescriptorProto.Type.TYPE_STRING);

        // build File Descriptor Proto
        DescriptorProtos.FileDescriptorProto.Builder fileDescriptorProtoBuilder = DescriptorProtos.FileDescriptorProto.newBuilder();
        fileDescriptorProtoBuilder.addMessageType(jsonMarshaller);

        DescriptorProtos.FileDescriptorProto fileDescriptorProto = fileDescriptorProtoBuilder.build();
        try {
            Descriptors.FileDescriptor fileDescriptor = Descriptors.FileDescriptor
                    .buildFrom(fileDescriptorProto, new Descriptors.FileDescriptor[0]);
            return fileDescriptor.findMessageTypeByName(GrpcConstants.JSON_DESCRIPTOR_PROTO_NAME);
        } catch (Descriptors.DescriptorValidationException e) {
            LOG.error("dynamic build JsonMarshaller descriptor is fail: {}", e.getMessage());
            throw new RuntimeException("dynamic build JsonMarshaller descriptor is fail", e);
        }
    }

    /**
     * buildJsonMessage.
     *
     * @param jsonParamMap jsonParamMap
     * @return DynamicMessageList
     */
    public static List<DynamicMessage> buildJsonMessageList(final Map<String, Object> jsonParamMap) {
        ParamCheckUtils.checkParamsLength(jsonParamMap.size(), GrpcConstants.JSON_DESCRIPTOR_PROTO_FIELD_NUM);
        JsonArray jsonParams = (JsonArray) jsonParamMap.get(GrpcConstants.JSON_DESCRIPTOR_PROTO_FIELD_NAME);
        List<DynamicMessage> jsonMessageList = new ArrayList<>(jsonParams.size());
        jsonParams.forEach(jsonParam -> {
            DynamicMessage jsonMessage = buildJsonMessage(GsonUtils.getInstance().toJson(jsonParam));
            jsonMessageList.add(jsonMessage);
        });

View on GitHub (pinned to 567142e072)