Pre-check

  • [x] I am sure that all the content I provide is in English.

Search before asking

  • [x] I had searched in the issues and found no similar issues.

Apache Dubbo Component

Java SDK (apache/dubbo)

Dubbo Version

Dubbo 3.3.4、 jdk 17

Steps to reproduce this issue

  1. use dubbo-sample-master use dubbo-samples-triple-grpc, the old protobuf file is follow:
syntax = "proto3";

option java_multiple_files = true;

package org.apache.dubbo.samples.tri.grpc;

message GreeterRequest {
  string name = 1;
}

message GreeterReply {
  string message = 1;
}

service Greeter{
 // key, the first letter is lowercase
  rpc greet(GreeterRequest) returns (GreeterReply);

  rpc biStream(stream GreeterRequest) returns (stream GreeterReply);

  rpc serverStream(GreeterRequest) returns (stream GreeterReply);

}

  1. update protobuf file
syntax = "proto3";

option java_multiple_files = true;

package org.apache.dubbo.samples.tri.grpc;

message GreeterRequest {
  string name = 1;
}

message GreeterReply {
  string message = 1;
}

service Greeter{
 // key, Convert the first letter to uppercase
  rpc Greet(GreeterRequest) returns (GreeterReply);

  rpc biStream(stream GreeterRequest) returns (stream GreeterReply);

  rpc serverStream(GreeterRequest) returns (stream GreeterReply);

}
  1. compile and run

  2. Requests starting with uppercase or lowercase letters, call on http The first http request detail (rpc method name is uppercase):

POST localhost:50053/org.apache.dubbo.samples.tri.grpc.Greeter/greet
Content-Type: application/json

{
  "name": "John"
}

Error details:

21:11:04.136 |-INFO  [NettyServerWorker-5-1] ing.transport.netty4.NettyChannelHandler:56  -|  [DUBBO] The connection [id: 0xade552f6, L:/127.0.0.1:50053 - R:/127.0.0.1:65057] of 127.0.0.1:65057 -> 127.0.0.1:50053 is established., dubbo version: 3.3.4, current host: 172.16.210.28
21:11:04.165 |-INFO  [NettyServerWorker-5-1] .tri.h12.AbstractServerTransportListener:252 -|  [DUBBO] An error occurred while processing the http request with DefaultHttp11ServerTransportListener, Http1Request{method='POST', path='/org.apache.dubbo.samples.tri.grpc.Greeter/greet', contentType='application/json'}, dubbo version: 3.3.4, current host: 172.16.210.28
org.apache.dubbo.remoting.http12.exception.HttpStatusException: Invoker not found
    at org.apache.dubbo.rpc.protocol.tri.h12.AbstractServerTransportListener.doRoute(AbstractServerTransportListener.java:124) ~[dubbo-3.3.4.jar:3.3.4]
    at org.apache.dubbo.rpc.protocol.tri.h12.AbstractServerTransportListener.onBeforeMetadata(AbstractServerTransportListener.java:118) [dubbo-3.3.4.jar:3.3.4]
    at org.apache.dubbo.rpc.protocol.tri.h12.AbstractServerTransportListener.onMetadata(AbstractServerTransportListener.java:85) [dubbo-3.3.4.jar:3.3.4]
    at org.apache.dubbo.rpc.protocol.tri.h12.AbstractServerTransportListener.onMetadata(AbstractServerTransportListener.java:54) [dubbo-3.3.4.jar:3.3.4]
    at org.apache.dubbo.remoting.http12.netty4.h1.NettyHttp1ConnectionHandler.channelRead0(NettyHttp1ConnectionHandler.java:56) [dubbo-3.3.4.jar:3.3.4]
    at org.apache.dubbo.remoting.http12.netty4.h1.NettyHttp1ConnectionHandler.channelRead0(NettyHttp1ConnectionHandler.java:29) [dubbo-3.3.4.jar:3.3.4]
    at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:99) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:93) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at org.apache.dubbo.remoting.http12.netty4.h1.NettyHttp1Codec.channelRead(NettyHttp1Codec.java:55) [dubbo-3.3.4.jar:3.3.4]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:107) [netty-codec-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:107) [netty-codec-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:346) [netty-codec-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:318) [netty-codec-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.handler.codec.ByteToMessageDecoder.handlerRemoved(ByteToMessageDecoder.java:266) [netty-codec-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:537) [netty-codec-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:469) [netty-codec-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:290) [netty-codec-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1357) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:868) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:796) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:732) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:658) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:998) [netty-common-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) [netty-common-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) [netty-common-4.1.118.Final.jar:4.1.118.Final]
    at java.lang.Thread.run(Thread.java:840) [?:?]

The second http request detail (rpc method name first letter is uppercase):

# change service method name 'greet' to 'Greet'
POST localhost:50053/org.apache.dubbo.samples.tri.grpc.Greeter/Greet
Content-Type: application/json

{
  "name": "John"
}

Error detials:

21:16:20.396 |-INFO  [NettyServerWorker-5-2] ing.transport.netty4.NettyChannelHandler:56  -|  [DUBBO] The connection [id: 0x5bbfa53a, L:/127.0.0.1:50053 - R:/127.0.0.1:52065] of 127.0.0.1:52065 -> 127.0.0.1:50053 is established., dubbo version: 3.3.4, current host: 172.16.210.28
21:16:20.398 |-INFO  [NettyServerWorker-5-2] .tri.h12.AbstractServerTransportListener:252 -|  [DUBBO] An error occurred while processing the http request with DefaultHttp11ServerTransportListener, Http1Request{method='POST', path='/org.apache.dubbo.samples.tri.grpc.Greeter/Greet', contentType='application/json'}, dubbo version: 3.3.4, current host: 172.16.210.28
org.apache.dubbo.remoting.http12.exception.HttpStatusException: Invoker not found
    at org.apache.dubbo.rpc.protocol.tri.h12.AbstractServerTransportListener.doRoute(AbstractServerTransportListener.java:124) ~[dubbo-3.3.4.jar:3.3.4]
    at org.apache.dubbo.rpc.protocol.tri.h12.AbstractServerTransportListener.onBeforeMetadata(AbstractServerTransportListener.java:118) [dubbo-3.3.4.jar:3.3.4]
    at org.apache.dubbo.rpc.protocol.tri.h12.AbstractServerTransportListener.onMetadata(AbstractServerTransportListener.java:85) [dubbo-3.3.4.jar:3.3.4]
    at org.apache.dubbo.rpc.protocol.tri.h12.AbstractServerTransportListener.onMetadata(AbstractServerTransportListener.java:54) [dubbo-3.3.4.jar:3.3.4]
    at org.apache.dubbo.remoting.http12.netty4.h1.NettyHttp1ConnectionHandler.channelRead0(NettyHttp1ConnectionHandler.java:56) [dubbo-3.3.4.jar:3.3.4]
    at org.apache.dubbo.remoting.http12.netty4.h1.NettyHttp1ConnectionHandler.channelRead0(NettyHttp1ConnectionHandler.java:29) [dubbo-3.3.4.jar:3.3.4]
    at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:99) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:93) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at org.apache.dubbo.remoting.http12.netty4.h1.NettyHttp1Codec.channelRead(NettyHttp1Codec.java:55) [dubbo-3.3.4.jar:3.3.4]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:107) [netty-codec-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:107) [netty-codec-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:346) [netty-codec-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:318) [netty-codec-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.handler.codec.ByteToMessageDecoder.handlerRemoved(ByteToMessageDecoder.java:266) [netty-codec-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:537) [netty-codec-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:469) [netty-codec-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:290) [netty-codec-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1357) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:868) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:796) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:732) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:658) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562) [netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:998) [netty-common-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) [netty-common-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) [netty-common-4.1.118.Final.jar:4.1.118.Final]
    at java.lang.Thread.run(Thread.java:840) [?:?]

What you expected to happen

Call 'localhost: 50053/org.apache.dubbo.samples.tri.grpc.Greeter/Greet' Or 'localhost: 50053/org.apache.dubbo.samples.tri.grpc.Greeter/greet' via HTTP succeeded, do not all fail

Anything else

General proto file specifications, The first character of the RPC method name is capitalized, and we have a large number of proto files with history that use RPC method names starting with uppercase characters

Are you willing to submit a pull request to fix on your own?

  • [x] Yes I am willing to submit a pull request on my own!

Code of Conduct

Comment From: zrlw

service Greeter{
 // key, Convert the first letter to uppercase
  rpc Greet(GreeterRequest) returns (GreeterReply);

  rpc biStream(stream GreeterRequest) returns (stream GreeterReply);

  rpc serverStream(GreeterRequest) returns (stream GreeterReply);

}

methods name biStream and serverStream do not comply with protobuf regulation: service names and method names should use TitleCase. see details at https://protobuf.dev/programming-guides/style

Image

Comment From: zrlw

you might refer to this proto: https://github.com/apache/dubbo/blob/3.3/dubbo-rpc/dubbo-rpc-triple/src/main/proto/health.proto

service Health {
...
  rpc Check(HealthCheckRequest) returns (HealthCheckResponse);
...
  rpc Watch(HealthCheckRequest) returns (stream HealthCheckResponse);
}

Comment From: zrlw

i tested on current dubbo 3.3 branch and didn't find the issue. here is my operations: 1. modify pom.xml of dubbo-demo-spring-boot-idl, (1) add dependencies

    <dependency>
      <groupId>com.google.protobuf</groupId>
      <artifactId>protobuf-java-util</artifactId>
      <version>3.25.6</version>
    </dependency>
    <dependency>
      <groupId>io.grpc</groupId>
      <artifactId>grpc-api</artifactId>
      <version>1.63.0</version>
    </dependency>
    <dependency>
      <groupId>io.grpc</groupId>
      <artifactId>grpc-stub</artifactId>
      <version>1.63.0</version>
    </dependency>
    <dependency>
      <groupId>io.grpc</groupId>
      <artifactId>grpc-protobuf</artifactId>
      <version>1.63.0</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>org.apache.tomcat.embed</groupId>
      <artifactId>tomcat-embed-core</artifactId>
      <version>9.0.83</version>
    </dependency>

(2) add plugins, set os.detected.classifier to windows-x86_64 since i test it on windows.

      <plugin>
        <groupId>org.xolstice.maven.plugins</groupId>
        <artifactId>protobuf-maven-plugin</artifactId>
        <version>0.6.1</version>
        <configuration>
          <protocArtifact>com.google.protobuf:protoc:3.25.6:exe:windows-x86_64
          </protocArtifact>
          <pluginId>grpc-java</pluginId>
          <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.63.0:exe:windows-x86_64
          </pluginArtifact>
          <protocPlugins>
            <protocPlugin>
              <id>dubbo</id>
              <groupId>org.apache.dubbo</groupId>
              <artifactId>dubbo-compiler</artifactId>
              <version>${project.version}</version>
              <mainClass>org.apache.dubbo.gen.tri.Dubbo3TripleGenerator</mainClass>
            </protocPlugin>
          </protocPlugins>
        </configuration>
        <executions>
          <execution>
            <goals>
              <goal>compile</goal>
              <goal>test-compile</goal>
              <goal>compile-custom</goal>
              <goal>test-compile-custom</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
  1. modify service methods name of dubbo-demo-spring-boot-idl-provider#helloworld.proto
service GreeterService {
    // Sends a greeting.
    rpc SayHello(HelloRequest) returns (HelloReply);

    rpc biStream(stream HelloRequest) returns (stream HelloReply);

    rpc serverStream(HelloRequest) returns (stream HelloReply);
}
  1. modify application.yml of dubbo-demo-spring-boot-idl-provider (1) change tri port from -1 to 50053,
  protocol:
    name: tri
    port: 50053

(2) add management and server port configurations,

management:
  endpoints:
    web:
      exposure:
        include: mappings
server:
  port: 8081
  1. run mvn compile of dubbo-demo-spring-boot-idl-provider
  2. add missing implements to dubbo-demo-spring-boot-idl-provider#GreeterServiceImpl
    @Override
    public void serverStream(HelloRequest request, StreamObserver<HelloReply> responseObserver) {
        // do nothing just for test.
    }

    @Override
    public StreamObserver<HelloRequest> biStream(StreamObserver<HelloReply> responseObserver) {
        // for test.
        return null;
    }
  1. start dubbo-demo-spring-boot-idl-provider#ProviderApplication
  2. test http post request by postman

sayHello

Comment From: lqscript

@zrlw I also encountered this issue.

I found that this problem does not occur if the service class directly implements the service interface (e.g., implements GreeterService) in dubbo-demo.

However, if the service extends the stub base class (e.g., DubboGreeterServiceTriple.GreeterServiceImplBase), which is the method described in the official documentation for Dubbo Triple services, it returns a 404 error whenever a lowerCamelCase method or an UpperCamelCase method is called.

Image

After debugging the source code, I found that the root cause is related to how Dubbo registers HTTP routes for Triple services.

When a service extends the generated base class, Dubbo uses a StubServiceDescriptor. org/apache/dubbo/config/ServiceConfig.java:565 Image

This descriptor stores method names using the original names from the .proto file, which are typically UpperCamelCase (e.g., SayHello).

Image

However, the actual method generated in the Java base class follows Java conventions and is lowerCamelCase (e.g., sayHello).

Image

When DefaultRequestMappingRegistry attempts to create HTTP mappings, it reflects on the service implementation and uses the method name (lowerCamelCase) to look up its corresponding ServiceDescriptor. This lookup fails because the registry is searching for a descriptor by its lowerCamelCase name, but the descriptor is keyed by the UpperCamelCase name.

Image

As a result, no HTTP mapping is registered for the method, causing all HTTP-based invocations to fail with a 404 error.

Comment From: zrlw

This descriptor stores method names using the original names from the .proto file, which are typically UpperCamelCase (e.g., SayHello).

pls submit a new issue and pr?

Comment From: lqscript

I create a new issue #15484

Comment From: oxsean

@paxxie2 Already working on it.