wh
diff --git a/java_interop/protobuf-triple/README.md b/java_interop/protobuf-triple/README.md
new file mode 100644
index 0000000..2f93bd5
--- /dev/null
+++ b/java_interop/protobuf-triple/README.md
@@ -0,0 +1,31 @@
+# dubbogo-java
+
+## Contents
+- protobuf: Using the struct definitions from proto files
+- server
+- client
+Please note that this sample is coded using dubbo-go 3.2.0-rc1.
+The combinations we have tested include the following:
+
+- [x] java-client communicating with a dubbogo-server
+- [x] java-server communicating with a dubbogo-client
+
+## Running the Application
+1. Start the server:
+    - Use goland to start triple/gojava-go-server
+    - Execute `sh run.sh` in the java-server folder to start the java server
+2. Start the client
+    - Use goland to start triple/gojava-go-client
+    - Execute `sh run.sh` under the java-client folder to start the java client
+
+## Notes
+1. Interface naming must be consistent
+   - java-server: GreeterImpl
+   - go-client: The configuration should be similarly defined as follows
+   ```yml
+     Consumer:
+       services:
+         GreeterConsumer:
+           # interface is for registry
+           interface: org.apache.dubbo.sample.GreeterImpl
+   ```
\ No newline at end of file
diff --git a/java_interop/protobuf-triple/README_zh.md b/java_interop/protobuf-triple/README_zh.md
new file mode 100644
index 0000000..01fbd57
--- /dev/null
+++ b/java_interop/protobuf-triple/README_zh.md
@@ -0,0 +1,34 @@
+# dubbogo-java
+
+## Contents
+
+- protobuf: 使用 proto 文件的结构体定义
+- server
+- client
+
+请注意,该样例使用dubbo-go 3.2.0-rc1编写
+我们测试的组合包括:
+
+- [x] java-client -> dubbogo-server
+- [x] java-server -> dubbogo-client
+
+## 运行
+1. 启动服务端
+   - 使用 goland 启动 triple/gojava-go-server
+   - 在 java-server 文件夹下执行 `sh run.sh` 启动 java server
+2. 启动客户端
+   - 使用 goland 启动 triple/gojava-go-client
+   - 在 java-client 文件夹下执行 `sh run.sh` 启动 java client
+
+## 注意
+1. 接口命名须一致
+   - java-server: GreeterImpl
+   - go-client: 在conf中应类似如下定义
+   ```yml
+     Consumer:
+       services:
+         GreeterConsumer:
+           # interface is for registry
+           interface: org.apache.dubbo.sample.GreeterImpl
+   ```
+      
\ No newline at end of file
diff --git a/java_interop/protobuf-triple/go/go-client/cmd/client.go b/java_interop/protobuf-triple/go/go-client/cmd/client.go
new file mode 100644
index 0000000..acf859e
--- /dev/null
+++ b/java_interop/protobuf-triple/go/go-client/cmd/client.go
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package main
+
+import (
+	"context"
+	"dubbo.apache.org/dubbo-go/v3/client"
+	_ "dubbo.apache.org/dubbo-go/v3/imports"
+	greet "github.com/apache/dubbo-go-samples/java_interop/protobuf-triple/go/proto"
+	"github.com/dubbogo/gost/log/logger"
+)
+
+// export DUBBO_GO_CONFIG_PATH=$PATH_TO_SAMPLES/rpc/triple/pb/dubbogo-java/go-client/conf/dubbogo.yml
+func main() {
+
+	cli, err := client.NewClient(
+		client.WithClientURL("127.0.0.1:36969"),
+	)
+	if err != nil {
+		panic(err)
+	}
+	if err != nil {
+		panic(err)
+	}
+
+	if err != nil {
+		panic(err)
+	}
+
+	svc, err := greet.NewGreeter(cli)
+	if err != nil {
+		panic(err)
+	}
+
+	resp, err := svc.SayHello(context.Background(), &greet.HelloRequest{Name: "hello world"})
+	if err != nil {
+		logger.Error(err)
+	}
+	logger.Infof("Greet response: %s", resp.Message)
+}
diff --git a/java_interop/protobuf-triple/go/go-client/conf/dubbogo.yml b/java_interop/protobuf-triple/go/go-client/conf/dubbogo.yml
new file mode 100644
index 0000000..eba9ff3
--- /dev/null
+++ b/java_interop/protobuf-triple/go/go-client/conf/dubbogo.yml
@@ -0,0 +1,9 @@
+dubbo:
+  registries:
+    zk:
+      address: zookeeper://127.0.0.1:2181
+  Consumer:
+    services:
+      GreeterConsumer:
+        # interface is for registry
+        interface: org.apache.dubbo.demo.GreeterImpl
\ No newline at end of file
diff --git a/java_interop/protobuf-triple/go/go-server/cmd/server.go b/java_interop/protobuf-triple/go/go-server/cmd/server.go
new file mode 100644
index 0000000..4ebf4a9
--- /dev/null
+++ b/java_interop/protobuf-triple/go/go-server/cmd/server.go
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package main
+
+import (
+	"context"
+	"dubbo.apache.org/dubbo-go/v3"
+	_ "dubbo.apache.org/dubbo-go/v3/imports"
+	"dubbo.apache.org/dubbo-go/v3/protocol"
+	"dubbo.apache.org/dubbo-go/v3/registry"
+	greet "github.com/apache/dubbo-go-samples/java_interop/protobuf-triple/go/proto"
+)
+
+// export DUBBO_GO_CONFIG_PATH=$PATH_TO_SAMPLES/rpc/triple/pb/dubbogo-java/go-client/conf/dubbogo.yml
+
+type GreetTripleServer struct {
+}
+
+func (srv *GreetTripleServer) SayHello(ctx context.Context, req *greet.HelloRequest) (*greet.HelloReply, error) {
+	resp := &greet.HelloReply{Message: req.Name}
+	return resp, nil
+}
+
+func main() {
+	ins, err := dubbo.NewInstance(
+		dubbo.WithName("org.apache.dubbo.sample.GreeterImpl"),
+		dubbo.WithRegistry(
+			registry.WithZookeeper(),
+			registry.WithAddress("127.0.0.1:2181"),
+		),
+		dubbo.WithProtocol(
+			protocol.WithTriple(),
+			protocol.WithPort(50052),
+		),
+	)
+	// create a server with registry and protocol set above
+	srv, err := ins.NewServer()
+	if err != nil {
+		panic(err)
+	}
+	// register a service to server
+	if err := greet.RegisterGreeterHandler(srv, &GreetTripleServer{}); err != nil {
+		panic(err)
+	}
+	// start the server
+	if err := srv.Serve(); err != nil {
+		panic(err)
+	}
+}
diff --git a/java_interop/protobuf-triple/go/go-server/conf/dubbogo.yml b/java_interop/protobuf-triple/go/go-server/conf/dubbogo.yml
new file mode 100644
index 0000000..7853beb
--- /dev/null
+++ b/java_interop/protobuf-triple/go/go-server/conf/dubbogo.yml
@@ -0,0 +1,13 @@
+dubbo:
+  registries:
+    zk:
+      address: zookeeper://127.0.0.1:2181
+  protocols:
+    triple:
+      name: tri
+      port: 50052
+  provider:
+    services:
+      GreeterProvider:
+        # interface is for registry
+        interface: org.apache.dubbo.demo.GreeterImpl
\ No newline at end of file
diff --git a/java_interop/protobuf-triple/go/proto/greet.pb.go b/java_interop/protobuf-triple/go/proto/greet.pb.go
new file mode 100644
index 0000000..02ec604
--- /dev/null
+++ b/java_interop/protobuf-triple/go/proto/greet.pb.go
@@ -0,0 +1,237 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//protoc --go_out=. --go_opt=paths=source_relative --go-triple_out=. greet.proto
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.33.0
+// 	protoc        v5.26.0--rc3
+// source: greet.proto
+
+package proto
+
+import (
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	reflect "reflect"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+// The request message containing the user's name.
+type HelloRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+}
+
+func (x *HelloRequest) Reset() {
+	*x = HelloRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_greet_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *HelloRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*HelloRequest) ProtoMessage() {}
+
+func (x *HelloRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_greet_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use HelloRequest.ProtoReflect.Descriptor instead.
+func (*HelloRequest) Descriptor() ([]byte, []int) {
+	return file_greet_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *HelloRequest) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+// The response message containing the greetings
+type HelloReply struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
+}
+
+func (x *HelloReply) Reset() {
+	*x = HelloReply{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_greet_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *HelloReply) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*HelloReply) ProtoMessage() {}
+
+func (x *HelloReply) ProtoReflect() protoreflect.Message {
+	mi := &file_greet_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use HelloReply.ProtoReflect.Descriptor instead.
+func (*HelloReply) Descriptor() ([]byte, []int) {
+	return file_greet_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *HelloReply) GetMessage() string {
+	if x != nil {
+		return x.Message
+	}
+	return ""
+}
+
+var File_greet_proto protoreflect.FileDescriptor
+
+var file_greet_proto_rawDesc = []byte{
+	0x0a, 0x0b, 0x67, 0x72, 0x65, 0x65, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x18, 0x6f,
+	0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e,
+	0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x22, 0x22, 0x0a, 0x0c, 0x48, 0x65, 0x6c, 0x6c, 0x6f,
+	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x26, 0x0a, 0x0a, 0x48,
+	0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73,
+	0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73,
+	0x61, 0x67, 0x65, 0x32, 0x63, 0x0a, 0x07, 0x47, 0x72, 0x65, 0x65, 0x74, 0x65, 0x72, 0x12, 0x58,
+	0x0a, 0x08, 0x53, 0x61, 0x79, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x12, 0x26, 0x2e, 0x6f, 0x72, 0x67,
+	0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x73, 0x61,
+	0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x1a, 0x24, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e,
+	0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x48, 0x65,
+	0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x42, 0x3f, 0x0a, 0x17, 0x6f, 0x72, 0x67, 0x2e,
+	0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x73, 0x61, 0x6d,
+	0x70, 0x6c, 0x65, 0x42, 0x0f, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x50,
+	0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x0c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0xa2, 0x02, 0x02, 0x57, 0x48, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x33,
+}
+
+var (
+	file_greet_proto_rawDescOnce sync.Once
+	file_greet_proto_rawDescData = file_greet_proto_rawDesc
+)
+
+func file_greet_proto_rawDescGZIP() []byte {
+	file_greet_proto_rawDescOnce.Do(func() {
+		file_greet_proto_rawDescData = protoimpl.X.CompressGZIP(file_greet_proto_rawDescData)
+	})
+	return file_greet_proto_rawDescData
+}
+
+var file_greet_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
+var file_greet_proto_goTypes = []interface{}{
+	(*HelloRequest)(nil), // 0: org.apache.dubbo.samples.HelloRequest
+	(*HelloReply)(nil),   // 1: org.apache.dubbo.samples.HelloReply
+}
+var file_greet_proto_depIdxs = []int32{
+	0, // 0: org.apache.dubbo.samples.Greeter.SayHello:input_type -> org.apache.dubbo.samples.HelloRequest
+	1, // 1: org.apache.dubbo.samples.Greeter.SayHello:output_type -> org.apache.dubbo.samples.HelloReply
+	1, // [1:2] is the sub-list for method output_type
+	0, // [0:1] is the sub-list for method input_type
+	0, // [0:0] is the sub-list for extension type_name
+	0, // [0:0] is the sub-list for extension extendee
+	0, // [0:0] is the sub-list for field type_name
+}
+
+func init() { file_greet_proto_init() }
+func file_greet_proto_init() {
+	if File_greet_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_greet_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*HelloRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_greet_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*HelloReply); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_greet_proto_rawDesc,
+			NumEnums:      0,
+			NumMessages:   2,
+			NumExtensions: 0,
+			NumServices:   1,
+		},
+		GoTypes:           file_greet_proto_goTypes,
+		DependencyIndexes: file_greet_proto_depIdxs,
+		MessageInfos:      file_greet_proto_msgTypes,
+	}.Build()
+	File_greet_proto = out.File
+	file_greet_proto_rawDesc = nil
+	file_greet_proto_goTypes = nil
+	file_greet_proto_depIdxs = nil
+}
diff --git a/java_interop/protobuf-triple/go/proto/greet.proto b/java_interop/protobuf-triple/go/proto/greet.proto
new file mode 100644
index 0000000..59ec39e
--- /dev/null
+++ b/java_interop/protobuf-triple/go/proto/greet.proto
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//protoc --go_out=. --go_opt=paths=source_relative --go-triple_out=. greet.proto
+syntax = "proto3";
+package org.apache.dubbo.samples;
+
+option go_package = "/proto;proto";
+//package of go
+option java_package = 'org.apache.dubbo.sample';
+option java_multiple_files = true;
+option java_outer_classname = "HelloWorldProto";
+option objc_class_prefix = "WH";
+
+// The greeting service definition.
+service Greeter {
+  // Sends a greeting
+  rpc SayHello(HelloRequest) returns (HelloReply);
+  // Sends a greeting via stream
+  //  rpc SayHelloStream (stream HelloRequest) returns (stream HelloReply) {}
+}
+
+// The request message containing the user's name.
+message HelloRequest {
+  string name = 1;
+}
+
+// The response message containing the greetings
+message HelloReply {
+  string message = 1;
+}
\ No newline at end of file
diff --git a/java_interop/protobuf-triple/go/proto/greet.triple.go b/java_interop/protobuf-triple/go/proto/greet.triple.go
new file mode 100644
index 0000000..531c430
--- /dev/null
+++ b/java_interop/protobuf-triple/go/proto/greet.triple.go
@@ -0,0 +1,122 @@
+// Code generated by protoc-gen-triple. DO NOT EDIT.
+//
+// Source: greet.proto
+package proto
+
+import (
+	"context"
+)
+
+import (
+	"dubbo.apache.org/dubbo-go/v3"
+	"dubbo.apache.org/dubbo-go/v3/client"
+	"dubbo.apache.org/dubbo-go/v3/common"
+	"dubbo.apache.org/dubbo-go/v3/common/constant"
+	"dubbo.apache.org/dubbo-go/v3/protocol/triple/triple_protocol"
+	"dubbo.apache.org/dubbo-go/v3/server"
+)
+
+// This is a compile-time assertion to ensure that this generated file and the Triple package
+// are compatible. If you get a compiler error that this constant is not defined, this code was
+// generated with a version of Triple newer than the one compiled into your binary. You can fix the
+// problem by either regenerating this code with an older version of Triple or updating the Triple
+// version compiled into your binary.
+const _ = triple_protocol.IsAtLeastVersion0_1_0
+
+const (
+	// GreeterName is the fully-qualified name of the Greeter service.
+	GreeterName = "org.apache.dubbo.samples.Greeter"
+)
+
+// These constants are the fully-qualified names of the RPCs defined in this package. They're
+// exposed at runtime as procedure and as the final two segments of the HTTP route.
+//
+// Note that these are different from the fully-qualified method names used by
+// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to
+// reflection-formatted method names, remove the leading slash and convert the remaining slash to a
+// period.
+const (
+	// GreeterSayHelloProcedure is the fully-qualified name of the Greeter's SayHello RPC.
+	GreeterSayHelloProcedure = "/org.apache.dubbo.samples.Greeter/SayHello"
+)
+
+var (
+	_ Greeter = (*GreeterImpl)(nil)
+)
+
+// Greeter is a client for the org.apache.dubbo.samples.Greeter service.
+type Greeter interface {
+	SayHello(ctx context.Context, req *HelloRequest, opts ...client.CallOption) (*HelloReply, error)
+}
+
+// NewGreeter constructs a client for the proto.Greeter service.
+func NewGreeter(cli *client.Client, opts ...client.ReferenceOption) (Greeter, error) {
+	conn, err := cli.DialWithInfo("org.apache.dubbo.samples.Greeter", &Greeter_ClientInfo, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return &GreeterImpl{
+		conn: conn,
+	}, nil
+}
+
+func SetConsumerService(srv common.RPCService) {
+	dubbo.SetConsumerServiceWithInfo(srv, &Greeter_ClientInfo)
+}
+
+// GreeterImpl implements Greeter.
+type GreeterImpl struct {
+	conn *client.Connection
+}
+
+func (c *GreeterImpl) SayHello(ctx context.Context, req *HelloRequest, opts ...client.CallOption) (*HelloReply, error) {
+	resp := new(HelloReply)
+	if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "SayHello", opts...); err != nil {
+		return nil, err
+	}
+	return resp, nil
+}
+
+var Greeter_ClientInfo = client.ClientInfo{
+	InterfaceName: "org.apache.dubbo.samples.Greeter",
+	MethodNames:   []string{"SayHello"},
+	ConnectionInjectFunc: func(dubboCliRaw interface{}, conn *client.Connection) {
+		dubboCli := dubboCliRaw.(*GreeterImpl)
+		dubboCli.conn = conn
+	},
+}
+
+// GreeterHandler is an implementation of the org.apache.dubbo.samples.Greeter service.
+type GreeterHandler interface {
+	SayHello(context.Context, *HelloRequest) (*HelloReply, error)
+}
+
+func RegisterGreeterHandler(srv *server.Server, hdlr GreeterHandler, opts ...server.ServiceOption) error {
+	return srv.Register(hdlr, &Greeter_ServiceInfo, opts...)
+}
+
+func SetProviderService(srv common.RPCService) {
+	dubbo.SetProviderServiceWithInfo(srv, &Greeter_ServiceInfo)
+}
+
+var Greeter_ServiceInfo = server.ServiceInfo{
+	InterfaceName: "org.apache.dubbo.samples.Greeter",
+	ServiceType:   (*GreeterHandler)(nil),
+	Methods: []server.MethodInfo{
+		{
+			Name: "SayHello",
+			Type: constant.CallUnary,
+			ReqInitFunc: func() interface{} {
+				return new(HelloRequest)
+			},
+			MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) {
+				req := args[0].(*HelloRequest)
+				res, err := handler.(GreeterHandler).SayHello(ctx, req)
+				if err != nil {
+					return nil, err
+				}
+				return triple_protocol.NewResponse(res), nil
+			},
+		},
+	},
+}
diff --git a/java_interop/protobuf-triple/java/java-client/build/main/java/org/apache/dubbo/sample/DubboGreeterTriple.java b/java_interop/protobuf-triple/java/java-client/build/main/java/org/apache/dubbo/sample/DubboGreeterTriple.java
new file mode 100644
index 0000000..92541d3
--- /dev/null
+++ b/java_interop/protobuf-triple/java/java-client/build/main/java/org/apache/dubbo/sample/DubboGreeterTriple.java
@@ -0,0 +1,183 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License.  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+    package org.apache.dubbo.sample;
+
+import org.apache.dubbo.common.stream.StreamObserver;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.PathResolver;
+import org.apache.dubbo.rpc.RpcException;
+import org.apache.dubbo.rpc.ServerService;
+import org.apache.dubbo.rpc.TriRpcStatus;
+import org.apache.dubbo.rpc.model.MethodDescriptor;
+import org.apache.dubbo.rpc.model.ServiceDescriptor;
+import org.apache.dubbo.rpc.model.StubMethodDescriptor;
+import org.apache.dubbo.rpc.model.StubServiceDescriptor;
+import org.apache.dubbo.rpc.stub.BiStreamMethodHandler;
+import org.apache.dubbo.rpc.stub.ServerStreamMethodHandler;
+import org.apache.dubbo.rpc.stub.StubInvocationUtil;
+import org.apache.dubbo.rpc.stub.StubInvoker;
+import org.apache.dubbo.rpc.stub.StubMethodHandler;
+import org.apache.dubbo.rpc.stub.StubSuppliers;
+import org.apache.dubbo.rpc.stub.UnaryStubMethodHandler;
+
+import com.google.protobuf.Message;
+import org.apache.dubbo.sample.HelloWorldProto;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.BiConsumer;
+import java.util.concurrent.CompletableFuture;
+
+public final class DubboGreeterTriple {
+
+    public static final String SERVICE_NAME = Greeter.SERVICE_NAME;
+
+    private static final StubServiceDescriptor serviceDescriptor = new StubServiceDescriptor(SERVICE_NAME,Greeter.class);
+
+    static {
+        org.apache.dubbo.rpc.protocol.tri.service.SchemaDescriptorRegistry.addSchemaDescriptor(SERVICE_NAME, HelloWorldProto.getDescriptor());
+        StubSuppliers.addSupplier(SERVICE_NAME, DubboGreeterTriple::newStub);
+        StubSuppliers.addSupplier(Greeter.JAVA_SERVICE_NAME,  DubboGreeterTriple::newStub);
+        StubSuppliers.addDescriptor(SERVICE_NAME, serviceDescriptor);
+        StubSuppliers.addDescriptor(Greeter.JAVA_SERVICE_NAME, serviceDescriptor);
+    }
+
+    @SuppressWarnings("all")
+    public static Greeter newStub(Invoker<?> invoker) {
+        return new GreeterStub((Invoker<Greeter>)invoker);
+    }
+
+    /**
+         * <pre>
+         *  Sends a greeting
+         * </pre>
+         */
+    private static final StubMethodDescriptor sayHelloMethod = new StubMethodDescriptor("SayHello",
+    org.apache.dubbo.sample.HelloRequest.class, org.apache.dubbo.sample.HelloReply.class, serviceDescriptor, MethodDescriptor.RpcType.UNARY,
+    obj -> ((Message) obj).toByteArray(), obj -> ((Message) obj).toByteArray(), org.apache.dubbo.sample.HelloRequest::parseFrom,
+    org.apache.dubbo.sample.HelloReply::parseFrom);
+
+    private static final StubMethodDescriptor sayHelloAsyncMethod = new StubMethodDescriptor("SayHello",
+    org.apache.dubbo.sample.HelloRequest.class, CompletableFuture.class, serviceDescriptor, MethodDescriptor.RpcType.UNARY,
+    obj -> ((Message) obj).toByteArray(), obj -> ((Message) obj).toByteArray(), org.apache.dubbo.sample.HelloRequest::parseFrom,
+    org.apache.dubbo.sample.HelloReply::parseFrom);
+
+    private static final StubMethodDescriptor sayHelloProxyAsyncMethod = new StubMethodDescriptor("SayHelloAsync",
+    org.apache.dubbo.sample.HelloRequest.class, org.apache.dubbo.sample.HelloReply.class, serviceDescriptor, MethodDescriptor.RpcType.UNARY,
+    obj -> ((Message) obj).toByteArray(), obj -> ((Message) obj).toByteArray(), org.apache.dubbo.sample.HelloRequest::parseFrom,
+    org.apache.dubbo.sample.HelloReply::parseFrom);
+
+
+
+
+
+    public static class GreeterStub implements Greeter{
+        private final Invoker<Greeter> invoker;
+
+        public GreeterStub(Invoker<Greeter> invoker) {
+            this.invoker = invoker;
+        }
+
+            /**
+         * <pre>
+         *  Sends a greeting
+         * </pre>
+         */
+        @Override
+        public org.apache.dubbo.sample.HelloReply sayHello(org.apache.dubbo.sample.HelloRequest request){
+            return StubInvocationUtil.unaryCall(invoker, sayHelloMethod, request);
+        }
+
+        public CompletableFuture<org.apache.dubbo.sample.HelloReply> sayHelloAsync(org.apache.dubbo.sample.HelloRequest request){
+            return StubInvocationUtil.unaryCall(invoker, sayHelloAsyncMethod, request);
+        }
+
+            /**
+         * <pre>
+         *  Sends a greeting
+         * </pre>
+         */
+        @Override
+        public void sayHello(org.apache.dubbo.sample.HelloRequest request, StreamObserver<org.apache.dubbo.sample.HelloReply> responseObserver){
+            StubInvocationUtil.unaryCall(invoker, sayHelloMethod , request, responseObserver);
+        }
+
+
+
+    }
+
+    public static abstract class GreeterImplBase implements Greeter, ServerService<Greeter> {
+
+        private <T, R> BiConsumer<T, StreamObserver<R>> syncToAsync(java.util.function.Function<T, R> syncFun) {
+            return new BiConsumer<T, StreamObserver<R>>() {
+                @Override
+                public void accept(T t, StreamObserver<R> observer) {
+                    try {
+                        R ret = syncFun.apply(t);
+                        observer.onNext(ret);
+                        observer.onCompleted();
+                    } catch (Throwable e) {
+                        observer.onError(e);
+                    }
+                }
+            };
+        }
+
+        @Override
+        public final Invoker<Greeter> getInvoker(URL url) {
+            PathResolver pathResolver = url.getOrDefaultFrameworkModel()
+            .getExtensionLoader(PathResolver.class)
+            .getDefaultExtension();
+            Map<String,StubMethodHandler<?, ?>> handlers = new HashMap<>();
+
+            pathResolver.addNativeStub( "/" + SERVICE_NAME + "/SayHello" );
+            pathResolver.addNativeStub( "/" + SERVICE_NAME + "/SayHelloAsync" );
+
+            BiConsumer<org.apache.dubbo.sample.HelloRequest, StreamObserver<org.apache.dubbo.sample.HelloReply>> sayHelloFunc = this::sayHello;
+            handlers.put(sayHelloMethod.getMethodName(), new UnaryStubMethodHandler<>(sayHelloFunc));
+            BiConsumer<org.apache.dubbo.sample.HelloRequest, StreamObserver<org.apache.dubbo.sample.HelloReply>> sayHelloAsyncFunc = syncToAsync(this::sayHello);
+            handlers.put(sayHelloProxyAsyncMethod.getMethodName(), new UnaryStubMethodHandler<>(sayHelloAsyncFunc));
+
+
+
+
+            return new StubInvoker<>(this, url, Greeter.class, handlers);
+        }
+
+
+        @Override
+        public org.apache.dubbo.sample.HelloReply sayHello(org.apache.dubbo.sample.HelloRequest request){
+            throw unimplementedMethodException(sayHelloMethod);
+        }
+
+
+
+
+
+        @Override
+        public final ServiceDescriptor getServiceDescriptor() {
+            return serviceDescriptor;
+        }
+        private RpcException unimplementedMethodException(StubMethodDescriptor methodDescriptor) {
+            return TriRpcStatus.UNIMPLEMENTED.withDescription(String.format("Method %s is unimplemented",
+                "/" + serviceDescriptor.getInterfaceName() + "/" + methodDescriptor.getMethodName())).asException();
+        }
+    }
+
+}
diff --git a/java_interop/protobuf-triple/java/java-client/build/main/java/org/apache/dubbo/sample/Greeter.java b/java_interop/protobuf-triple/java/java-client/build/main/java/org/apache/dubbo/sample/Greeter.java
new file mode 100644
index 0000000..e783758
--- /dev/null
+++ b/java_interop/protobuf-triple/java/java-client/build/main/java/org/apache/dubbo/sample/Greeter.java
@@ -0,0 +1,64 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License.  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+    package org.apache.dubbo.sample;
+
+import org.apache.dubbo.common.stream.StreamObserver;
+import com.google.protobuf.Message;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.BiConsumer;
+import java.util.concurrent.CompletableFuture;
+
+public interface Greeter {
+
+    String JAVA_SERVICE_NAME = "org.apache.dubbo.sample.Greeter";
+    String SERVICE_NAME = "org.apache.dubbo.samples.Greeter";
+
+        /**
+         * <pre>
+         *  Sends a greeting
+         * </pre>
+         */
+    org.apache.dubbo.sample.HelloReply sayHello(org.apache.dubbo.sample.HelloRequest request);
+
+    default CompletableFuture<org.apache.dubbo.sample.HelloReply> sayHelloAsync(org.apache.dubbo.sample.HelloRequest request){
+        return CompletableFuture.completedFuture(sayHello(request));
+    }
+
+    /**
+    * This server stream type unary method is <b>only</b> used for generated stub to support async unary method.
+    * It will not be called if you are NOT using Dubbo3 generated triple stub and <b>DO NOT</b> implement this method.
+    */
+    default void sayHello(org.apache.dubbo.sample.HelloRequest request, StreamObserver<org.apache.dubbo.sample.HelloReply> responseObserver){
+        sayHelloAsync(request).whenComplete((r, t) -> {
+            if (t != null) {
+                responseObserver.onError(t);
+            } else {
+                responseObserver.onNext(r);
+                responseObserver.onCompleted();
+            }
+        });
+    }
+
+
+
+
+
+
+}
diff --git a/java_interop/protobuf-triple/java/java-client/build/main/java/org/apache/dubbo/sample/HelloReply.java b/java_interop/protobuf-triple/java/java-client/build/main/java/org/apache/dubbo/sample/HelloReply.java
new file mode 100644
index 0000000..5b3f455
--- /dev/null
+++ b/java_interop/protobuf-triple/java/java-client/build/main/java/org/apache/dubbo/sample/HelloReply.java
@@ -0,0 +1,567 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: greet.proto
+
+package org.apache.dubbo.sample;
+
+import org.apache.dubbo.sample.HelloReplyOrBuilder;
+
+/**
+ * <pre>
+ * The response message containing the greetings
+ * </pre>
+ *
+ * Protobuf type {@code org.apache.dubbo.samples.HelloReply}
+ */
+public final class HelloReply extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:org.apache.dubbo.samples.HelloReply)
+        HelloReplyOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use HelloReply.newBuilder() to construct.
+  private HelloReply(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private HelloReply() {
+    message_ = "";
+  }
+
+  @Override
+  @SuppressWarnings({"unused"})
+  protected Object newInstance(
+      UnusedPrivateParameter unused) {
+    return new HelloReply();
+  }
+
+  @Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private HelloReply(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new NullPointerException();
+    }
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            String s = input.readStringRequireUtf8();
+
+            message_ = s;
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return org.apache.dubbo.sample.HelloWorldProto.internal_static_org_apache_dubbo_samples_HelloReply_descriptor;
+  }
+
+  @Override
+  protected FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return org.apache.dubbo.sample.HelloWorldProto.internal_static_org_apache_dubbo_samples_HelloReply_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            org.apache.dubbo.sample.HelloReply.class, org.apache.dubbo.sample.HelloReply.Builder.class);
+  }
+
+  public static final int MESSAGE_FIELD_NUMBER = 1;
+  private volatile Object message_;
+  /**
+   * <code>string message = 1;</code>
+   * @return The message.
+   */
+  @Override
+  public String getMessage() {
+    Object ref = message_;
+    if (ref instanceof String) {
+      return (String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      String s = bs.toStringUtf8();
+      message_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string message = 1;</code>
+   * @return The bytes for message.
+   */
+  @Override
+  public com.google.protobuf.ByteString
+      getMessageBytes() {
+    Object ref = message_;
+    if (ref instanceof String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (String) ref);
+      message_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(message_)) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 1, message_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(message_)) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, message_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @Override
+  public boolean equals(final Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof org.apache.dubbo.sample.HelloReply)) {
+      return super.equals(obj);
+    }
+    org.apache.dubbo.sample.HelloReply other = (org.apache.dubbo.sample.HelloReply) obj;
+
+    if (!getMessage()
+        .equals(other.getMessage())) return false;
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    hash = (37 * hash) + MESSAGE_FIELD_NUMBER;
+    hash = (53 * hash) + getMessage().hashCode();
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static org.apache.dubbo.sample.HelloReply parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static org.apache.dubbo.sample.HelloReply parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static org.apache.dubbo.sample.HelloReply parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static org.apache.dubbo.sample.HelloReply parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static org.apache.dubbo.sample.HelloReply parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static org.apache.dubbo.sample.HelloReply parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static org.apache.dubbo.sample.HelloReply parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static org.apache.dubbo.sample.HelloReply parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static org.apache.dubbo.sample.HelloReply parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static org.apache.dubbo.sample.HelloReply parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static org.apache.dubbo.sample.HelloReply parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static org.apache.dubbo.sample.HelloReply parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(org.apache.dubbo.sample.HelloReply prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @Override
+  protected Builder newBuilderForType(
+      BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * <pre>
+   * The response message containing the greetings
+   * </pre>
+   *
+   * Protobuf type {@code org.apache.dubbo.samples.HelloReply}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:org.apache.dubbo.samples.HelloReply)
+      HelloReplyOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.apache.dubbo.sample.HelloWorldProto.internal_static_org_apache_dubbo_samples_HelloReply_descriptor;
+    }
+
+    @Override
+    protected FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.apache.dubbo.sample.HelloWorldProto.internal_static_org_apache_dubbo_samples_HelloReply_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.apache.dubbo.sample.HelloReply.class, org.apache.dubbo.sample.HelloReply.Builder.class);
+    }
+
+    // Construct using org.apache.dubbo.sample.HelloReply.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @Override
+    public Builder clear() {
+      super.clear();
+      message_ = "";
+
+      return this;
+    }
+
+    @Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return org.apache.dubbo.sample.HelloWorldProto.internal_static_org_apache_dubbo_samples_HelloReply_descriptor;
+    }
+
+    @Override
+    public org.apache.dubbo.sample.HelloReply getDefaultInstanceForType() {
+      return org.apache.dubbo.sample.HelloReply.getDefaultInstance();
+    }
+
+    @Override
+    public org.apache.dubbo.sample.HelloReply build() {
+      org.apache.dubbo.sample.HelloReply result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @Override
+    public org.apache.dubbo.sample.HelloReply buildPartial() {
+      org.apache.dubbo.sample.HelloReply result = new org.apache.dubbo.sample.HelloReply(this);
+      result.message_ = message_;
+      onBuilt();
+      return result;
+    }
+
+    @Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        Object value) {
+      return super.setField(field, value);
+    }
+    @Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof org.apache.dubbo.sample.HelloReply) {
+        return mergeFrom((org.apache.dubbo.sample.HelloReply)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(org.apache.dubbo.sample.HelloReply other) {
+      if (other == org.apache.dubbo.sample.HelloReply.getDefaultInstance()) return this;
+      if (!other.getMessage().isEmpty()) {
+        message_ = other.message_;
+        onChanged();
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      org.apache.dubbo.sample.HelloReply parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (org.apache.dubbo.sample.HelloReply) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private Object message_ = "";
+    /**
+     * <code>string message = 1;</code>
+     * @return The message.
+     */
+    public String getMessage() {
+      Object ref = message_;
+      if (!(ref instanceof String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        String s = bs.toStringUtf8();
+        message_ = s;
+        return s;
+      } else {
+        return (String) ref;
+      }
+    }
+    /**
+     * <code>string message = 1;</code>
+     * @return The bytes for message.
+     */
+    public com.google.protobuf.ByteString
+        getMessageBytes() {
+      Object ref = message_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (String) ref);
+        message_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string message = 1;</code>
+     * @param value The message to set.
+     * @return This builder for chaining.
+     */
+    public Builder setMessage(
+        String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      message_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string message = 1;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearMessage() {
+      
+      message_ = getDefaultInstance().getMessage();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string message = 1;</code>
+     * @param value The bytes for message to set.
+     * @return This builder for chaining.
+     */
+    public Builder setMessageBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      message_ = value;
+      onChanged();
+      return this;
+    }
+    @Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:org.apache.dubbo.samples.HelloReply)
+  }
+
+  // @@protoc_insertion_point(class_scope:org.apache.dubbo.samples.HelloReply)
+  private static final org.apache.dubbo.sample.HelloReply DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new org.apache.dubbo.sample.HelloReply();
+  }
+
+  public static org.apache.dubbo.sample.HelloReply getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<HelloReply>
+      PARSER = new com.google.protobuf.AbstractParser<HelloReply>() {
+    @Override
+    public HelloReply parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new HelloReply(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<HelloReply> parser() {
+    return PARSER;
+  }
+
+  @Override
+  public com.google.protobuf.Parser<HelloReply> getParserForType() {
+    return PARSER;
+  }
+
+  @Override
+  public org.apache.dubbo.sample.HelloReply getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/java_interop/protobuf-triple/java/java-client/build/main/java/org/apache/dubbo/sample/HelloReplyOrBuilder.java b/java_interop/protobuf-triple/java/java-client/build/main/java/org/apache/dubbo/sample/HelloReplyOrBuilder.java
new file mode 100644
index 0000000..7acaaf8
--- /dev/null
+++ b/java_interop/protobuf-triple/java/java-client/build/main/java/org/apache/dubbo/sample/HelloReplyOrBuilder.java
@@ -0,0 +1,21 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: greet.proto
+
+package org.apache.dubbo.sample;
+
+public interface HelloReplyOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:org.apache.dubbo.samples.HelloReply)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>string message = 1;</code>
+   * @return The message.
+   */
+  String getMessage();
+  /**
+   * <code>string message = 1;</code>
+   * @return The bytes for message.
+   */
+  com.google.protobuf.ByteString
+      getMessageBytes();
+}
diff --git a/java_interop/protobuf-triple/java/java-client/build/main/java/org/apache/dubbo/sample/HelloRequest.java b/java_interop/protobuf-triple/java/java-client/build/main/java/org/apache/dubbo/sample/HelloRequest.java
new file mode 100644
index 0000000..d2e253f
--- /dev/null
+++ b/java_interop/protobuf-triple/java/java-client/build/main/java/org/apache/dubbo/sample/HelloRequest.java
@@ -0,0 +1,567 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: greet.proto
+
+package org.apache.dubbo.sample;
+
+import org.apache.dubbo.sample.HelloRequestOrBuilder;
+
+/**
+ * <pre>
+ * The request message containing the user's name.
+ * </pre>
+ *
+ * Protobuf type {@code org.apache.dubbo.samples.HelloRequest}
+ */
+public final class HelloRequest extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:org.apache.dubbo.samples.HelloRequest)
+        HelloRequestOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use HelloRequest.newBuilder() to construct.
+  private HelloRequest(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private HelloRequest() {
+    name_ = "";
+  }
+
+  @Override
+  @SuppressWarnings({"unused"})
+  protected Object newInstance(
+      UnusedPrivateParameter unused) {
+    return new HelloRequest();
+  }
+
+  @Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private HelloRequest(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new NullPointerException();
+    }
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            String s = input.readStringRequireUtf8();
+
+            name_ = s;
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return org.apache.dubbo.sample.HelloWorldProto.internal_static_org_apache_dubbo_samples_HelloRequest_descriptor;
+  }
+
+  @Override
+  protected FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return org.apache.dubbo.sample.HelloWorldProto.internal_static_org_apache_dubbo_samples_HelloRequest_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            org.apache.dubbo.sample.HelloRequest.class, org.apache.dubbo.sample.HelloRequest.Builder.class);
+  }
+
+  public static final int NAME_FIELD_NUMBER = 1;
+  private volatile Object name_;
+  /**
+   * <code>string name = 1;</code>
+   * @return The name.
+   */
+  @Override
+  public String getName() {
+    Object ref = name_;
+    if (ref instanceof String) {
+      return (String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      String s = bs.toStringUtf8();
+      name_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string name = 1;</code>
+   * @return The bytes for name.
+   */
+  @Override
+  public com.google.protobuf.ByteString
+      getNameBytes() {
+    Object ref = name_;
+    if (ref instanceof String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (String) ref);
+      name_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(name_)) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 1, name_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(name_)) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, name_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @Override
+  public boolean equals(final Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof org.apache.dubbo.sample.HelloRequest)) {
+      return super.equals(obj);
+    }
+    org.apache.dubbo.sample.HelloRequest other = (org.apache.dubbo.sample.HelloRequest) obj;
+
+    if (!getName()
+        .equals(other.getName())) return false;
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    hash = (37 * hash) + NAME_FIELD_NUMBER;
+    hash = (53 * hash) + getName().hashCode();
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static org.apache.dubbo.sample.HelloRequest parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static org.apache.dubbo.sample.HelloRequest parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static org.apache.dubbo.sample.HelloRequest parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static org.apache.dubbo.sample.HelloRequest parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static org.apache.dubbo.sample.HelloRequest parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static org.apache.dubbo.sample.HelloRequest parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static org.apache.dubbo.sample.HelloRequest parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static org.apache.dubbo.sample.HelloRequest parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static org.apache.dubbo.sample.HelloRequest parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static org.apache.dubbo.sample.HelloRequest parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static org.apache.dubbo.sample.HelloRequest parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static org.apache.dubbo.sample.HelloRequest parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(org.apache.dubbo.sample.HelloRequest prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @Override
+  protected Builder newBuilderForType(
+      BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * <pre>
+   * The request message containing the user's name.
+   * </pre>
+   *
+   * Protobuf type {@code org.apache.dubbo.samples.HelloRequest}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:org.apache.dubbo.samples.HelloRequest)
+      HelloRequestOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.apache.dubbo.sample.HelloWorldProto.internal_static_org_apache_dubbo_samples_HelloRequest_descriptor;
+    }
+
+    @Override
+    protected FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.apache.dubbo.sample.HelloWorldProto.internal_static_org_apache_dubbo_samples_HelloRequest_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.apache.dubbo.sample.HelloRequest.class, org.apache.dubbo.sample.HelloRequest.Builder.class);
+    }
+
+    // Construct using org.apache.dubbo.sample.HelloRequest.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @Override
+    public Builder clear() {
+      super.clear();
+      name_ = "";
+
+      return this;
+    }
+
+    @Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return org.apache.dubbo.sample.HelloWorldProto.internal_static_org_apache_dubbo_samples_HelloRequest_descriptor;
+    }
+
+    @Override
+    public org.apache.dubbo.sample.HelloRequest getDefaultInstanceForType() {
+      return org.apache.dubbo.sample.HelloRequest.getDefaultInstance();
+    }
+
+    @Override
+    public org.apache.dubbo.sample.HelloRequest build() {
+      org.apache.dubbo.sample.HelloRequest result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @Override
+    public org.apache.dubbo.sample.HelloRequest buildPartial() {
+      org.apache.dubbo.sample.HelloRequest result = new org.apache.dubbo.sample.HelloRequest(this);
+      result.name_ = name_;
+      onBuilt();
+      return result;
+    }
+
+    @Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        Object value) {
+      return super.setField(field, value);
+    }
+    @Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof org.apache.dubbo.sample.HelloRequest) {
+        return mergeFrom((org.apache.dubbo.sample.HelloRequest)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(org.apache.dubbo.sample.HelloRequest other) {
+      if (other == org.apache.dubbo.sample.HelloRequest.getDefaultInstance()) return this;
+      if (!other.getName().isEmpty()) {
+        name_ = other.name_;
+        onChanged();
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      org.apache.dubbo.sample.HelloRequest parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (org.apache.dubbo.sample.HelloRequest) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private Object name_ = "";
+    /**
+     * <code>string name = 1;</code>
+     * @return The name.
+     */
+    public String getName() {
+      Object ref = name_;
+      if (!(ref instanceof String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        String s = bs.toStringUtf8();
+        name_ = s;
+        return s;
+      } else {
+        return (String) ref;
+      }
+    }
+    /**
+     * <code>string name = 1;</code>
+     * @return The bytes for name.
+     */
+    public com.google.protobuf.ByteString
+        getNameBytes() {
+      Object ref = name_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (String) ref);
+        name_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string name = 1;</code>
+     * @param value The name to set.
+     * @return This builder for chaining.
+     */
+    public Builder setName(
+        String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      name_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string name = 1;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearName() {
+      
+      name_ = getDefaultInstance().getName();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string name = 1;</code>
+     * @param value The bytes for name to set.
+     * @return This builder for chaining.
+     */
+    public Builder setNameBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      name_ = value;
+      onChanged();
+      return this;
+    }
+    @Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:org.apache.dubbo.samples.HelloRequest)
+  }
+
+  // @@protoc_insertion_point(class_scope:org.apache.dubbo.samples.HelloRequest)
+  private static final org.apache.dubbo.sample.HelloRequest DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new org.apache.dubbo.sample.HelloRequest();
+  }
+
+  public static org.apache.dubbo.sample.HelloRequest getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<HelloRequest>
+      PARSER = new com.google.protobuf.AbstractParser<HelloRequest>() {
+    @Override
+    public HelloRequest parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new HelloRequest(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<HelloRequest> parser() {
+    return PARSER;
+  }
+
+  @Override
+  public com.google.protobuf.Parser<HelloRequest> getParserForType() {
+    return PARSER;
+  }
+
+  @Override
+  public org.apache.dubbo.sample.HelloRequest getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/java_interop/protobuf-triple/java/java-client/build/main/java/org/apache/dubbo/sample/HelloRequestOrBuilder.java b/java_interop/protobuf-triple/java/java-client/build/main/java/org/apache/dubbo/sample/HelloRequestOrBuilder.java
new file mode 100644
index 0000000..15b31f2
--- /dev/null
+++ b/java_interop/protobuf-triple/java/java-client/build/main/java/org/apache/dubbo/sample/HelloRequestOrBuilder.java
@@ -0,0 +1,21 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: greet.proto
+
+package org.apache.dubbo.sample;
+
+public interface HelloRequestOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:org.apache.dubbo.samples.HelloRequest)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>string name = 1;</code>
+   * @return The name.
+   */
+  String getName();
+  /**
+   * <code>string name = 1;</code>
+   * @return The bytes for name.
+   */
+  com.google.protobuf.ByteString
+      getNameBytes();
+}
diff --git a/java_interop/protobuf-triple/java/java-client/build/main/java/org/apache/dubbo/sample/HelloWorldProto.java b/java_interop/protobuf-triple/java/java-client/build/main/java/org/apache/dubbo/sample/HelloWorldProto.java
new file mode 100644
index 0000000..fbefd79
--- /dev/null
+++ b/java_interop/protobuf-triple/java/java-client/build/main/java/org/apache/dubbo/sample/HelloWorldProto.java
@@ -0,0 +1,63 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: greet.proto
+
+package org.apache.dubbo.sample;
+
+public final class HelloWorldProto {
+  private HelloWorldProto() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_apache_dubbo_samples_HelloRequest_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_org_apache_dubbo_samples_HelloRequest_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_apache_dubbo_samples_HelloReply_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_org_apache_dubbo_samples_HelloReply_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    String[] descriptorData = {
+      "\n\013greet.proto\022\030org.apache.dubbo.samples\"" +
+      "\034\n\014HelloRequest\022\014\n\004name\030\001 \001(\t\"\035\n\nHelloRe" +
+      "ply\022\017\n\007message\030\001 \001(\t2c\n\007Greeter\022X\n\010SayHe" +
+      "llo\022&.org.apache.dubbo.samples.HelloRequ" +
+      "est\032$.org.apache.dubbo.samples.HelloRepl" +
+      "yB?\n\027org.apache.dubbo.sampleB\017HelloWorld" +
+      "ProtoP\001Z\014/proto;proto\242\002\002WHb\006proto3"
+    };
+    descriptor = com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+        });
+    internal_static_org_apache_dubbo_samples_HelloRequest_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_org_apache_dubbo_samples_HelloRequest_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_org_apache_dubbo_samples_HelloRequest_descriptor,
+        new String[] { "Name", });
+    internal_static_org_apache_dubbo_samples_HelloReply_descriptor =
+      getDescriptor().getMessageTypes().get(1);
+    internal_static_org_apache_dubbo_samples_HelloReply_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_org_apache_dubbo_samples_HelloReply_descriptor,
+        new String[] { "Message", });
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/java_interop/protobuf-triple/java/java-client/pom.xml b/java_interop/protobuf-triple/java/java-client/pom.xml
new file mode 100644
index 0000000..ae5cb3d
--- /dev/null
+++ b/java_interop/protobuf-triple/java/java-client/pom.xml
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>org.example</groupId>
+    <artifactId>java</artifactId>
+    <version>1.0-SNAPSHOT</version>
+
+    <properties>
+        <maven.compiler.source>8</maven.compiler.source>
+        <maven.compiler.target>8</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <dubbo.version>3.1.7</dubbo.version>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.13</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo</artifactId>
+            <version>${dubbo.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-dependencies-zookeeper-curator5</artifactId>
+            <type>pom</type>
+            <version>${dubbo.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.protobuf</groupId>
+            <artifactId>protobuf-java</artifactId>
+            <version>3.19.4</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <extensions>
+            <extension>
+                <groupId>kr.motd.maven</groupId>
+                <artifactId>os-maven-plugin</artifactId>
+                <version>1.6.1</version>
+            </extension>
+        </extensions>
+        <plugins>
+            <plugin>
+                <groupId>org.xolstice.maven.plugins</groupId>
+                <artifactId>protobuf-maven-plugin</artifactId>
+                <version>0.6.1</version>
+                <configuration>
+                    <!--suppress UnresolvedMavenProperty -->
+                    <protocArtifact>com.google.protobuf:protoc:3.19.4:exe:${os.detected.classifier}</protocArtifact>
+                    <protocPlugins>
+                        <protocPlugin>
+                            <id>dubbo</id>
+                            <groupId>org.apache.dubbo</groupId>
+                            <artifactId>dubbo-compiler</artifactId>
+                            <version>${dubbo.version}</version>
+                            <mainClass>org.apache.dubbo.gen.tri.Dubbo3TripleGenerator</mainClass>
+                        </protocPlugin>
+                    </protocPlugins>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>compile</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/java_interop/protobuf-triple/java/java-client/run.sh b/java_interop/protobuf-triple/java/java-client/run.sh
new file mode 100644
index 0000000..dc04138
--- /dev/null
+++ b/java_interop/protobuf-triple/java/java-client/run.sh
@@ -0,0 +1 @@
+mvn -e clean compile exec:java -Dexec.mainClass="org.apache.dubbo.sample.Consumer"
\ No newline at end of file
diff --git a/java_interop/protobuf-triple/java/java-client/src/main/java/org/apache/dubbo/sample/Consumer.java b/java_interop/protobuf-triple/java/java-client/src/main/java/org/apache/dubbo/sample/Consumer.java
new file mode 100644
index 0000000..fe54c14
--- /dev/null
+++ b/java_interop/protobuf-triple/java/java-client/src/main/java/org/apache/dubbo/sample/Consumer.java
@@ -0,0 +1,29 @@
+package org.apache.dubbo.sample;
+
+import org.apache.dubbo.common.constants.CommonConstants;
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.config.ProtocolConfig;
+import org.apache.dubbo.config.ReferenceConfig;
+import org.apache.dubbo.config.RegistryConfig;
+import org.apache.dubbo.config.bootstrap.DubboBootstrap;
+
+public class ApiConsumer {
+    public static void main(String[] args) {
+        DubboBootstrap bootstrap = DubboBootstrap.getInstance();
+        ReferenceConfig<Greeter> ref = new ReferenceConfig<>();
+        ref.setInterface(Greeter.class);
+        ref.setProtocol(CommonConstants.TRIPLE);
+        ref.setProxy(CommonConstants.NATIVE_STUB);
+        ref.setTimeout(3000);
+        bootstrap.application(new ApplicationConfig("duboo-test"))
+                .registry(new RegistryConfig("zookeeper://127.0.0.1:2181"))
+                .protocol(new ProtocolConfig(CommonConstants.TRIPLE,50052))
+                .reference(ref)
+                .start();
+
+        Greeter greeter = ref.get();
+        HelloRequest request = HelloRequest.newBuilder().setName("Demo").build();
+        HelloReply reply = greeter.sayHello(request);
+        System.out.println("Received reply:" + reply);
+    }
+}
diff --git a/java_interop/protobuf-triple/java/java-client/src/main/proto/greet.proto b/java_interop/protobuf-triple/java/java-client/src/main/proto/greet.proto
new file mode 100644
index 0000000..59ec39e
--- /dev/null
+++ b/java_interop/protobuf-triple/java/java-client/src/main/proto/greet.proto
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//protoc --go_out=. --go_opt=paths=source_relative --go-triple_out=. greet.proto
+syntax = "proto3";
+package org.apache.dubbo.samples;
+
+option go_package = "/proto;proto";
+//package of go
+option java_package = 'org.apache.dubbo.sample';
+option java_multiple_files = true;
+option java_outer_classname = "HelloWorldProto";
+option objc_class_prefix = "WH";
+
+// The greeting service definition.
+service Greeter {
+  // Sends a greeting
+  rpc SayHello(HelloRequest) returns (HelloReply);
+  // Sends a greeting via stream
+  //  rpc SayHelloStream (stream HelloRequest) returns (stream HelloReply) {}
+}
+
+// The request message containing the user's name.
+message HelloRequest {
+  string name = 1;
+}
+
+// The response message containing the greetings
+message HelloReply {
+  string message = 1;
+}
\ No newline at end of file
diff --git a/java_interop/protobuf-triple/java/java-server/build/protobuf/java/org/apache/dubbo/sample/DubboGreeterTriple.java b/java_interop/protobuf-triple/java/java-server/build/protobuf/java/org/apache/dubbo/sample/DubboGreeterTriple.java
new file mode 100644
index 0000000..5fba724
--- /dev/null
+++ b/java_interop/protobuf-triple/java/java-server/build/protobuf/java/org/apache/dubbo/sample/DubboGreeterTriple.java
@@ -0,0 +1,182 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License.  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+    package org.apache.dubbo.sample;
+
+import org.apache.dubbo.common.stream.StreamObserver;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.PathResolver;
+import org.apache.dubbo.rpc.RpcException;
+import org.apache.dubbo.rpc.ServerService;
+import org.apache.dubbo.rpc.TriRpcStatus;
+import org.apache.dubbo.rpc.model.MethodDescriptor;
+import org.apache.dubbo.rpc.model.ServiceDescriptor;
+import org.apache.dubbo.rpc.model.StubMethodDescriptor;
+import org.apache.dubbo.rpc.model.StubServiceDescriptor;
+import org.apache.dubbo.rpc.stub.BiStreamMethodHandler;
+import org.apache.dubbo.rpc.stub.ServerStreamMethodHandler;
+import org.apache.dubbo.rpc.stub.StubInvocationUtil;
+import org.apache.dubbo.rpc.stub.StubInvoker;
+import org.apache.dubbo.rpc.stub.StubMethodHandler;
+import org.apache.dubbo.rpc.stub.StubSuppliers;
+import org.apache.dubbo.rpc.stub.UnaryStubMethodHandler;
+
+import com.google.protobuf.Message;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.BiConsumer;
+import java.util.concurrent.CompletableFuture;
+
+public final class DubboGreeterTriple {
+
+    public static final String SERVICE_NAME = Greeter.SERVICE_NAME;
+
+    private static final StubServiceDescriptor serviceDescriptor = new StubServiceDescriptor(SERVICE_NAME,Greeter.class);
+
+    static {
+        org.apache.dubbo.rpc.protocol.tri.service.SchemaDescriptorRegistry.addSchemaDescriptor(SERVICE_NAME,HelloWorldProto.getDescriptor());
+        StubSuppliers.addSupplier(SERVICE_NAME, DubboGreeterTriple::newStub);
+        StubSuppliers.addSupplier(Greeter.JAVA_SERVICE_NAME,  DubboGreeterTriple::newStub);
+        StubSuppliers.addDescriptor(SERVICE_NAME, serviceDescriptor);
+        StubSuppliers.addDescriptor(Greeter.JAVA_SERVICE_NAME, serviceDescriptor);
+    }
+
+    @SuppressWarnings("all")
+    public static Greeter newStub(Invoker<?> invoker) {
+        return new GreeterStub((Invoker<Greeter>)invoker);
+    }
+
+    /**
+         * <pre>
+         *  Sends a greeting
+         * </pre>
+         */
+    private static final StubMethodDescriptor sayHelloMethod = new StubMethodDescriptor("SayHello",
+    org.apache.dubbo.sample.HelloRequest.class, org.apache.dubbo.sample.HelloReply.class, serviceDescriptor, MethodDescriptor.RpcType.UNARY,
+    obj -> ((Message) obj).toByteArray(), obj -> ((Message) obj).toByteArray(), org.apache.dubbo.sample.HelloRequest::parseFrom,
+    org.apache.dubbo.sample.HelloReply::parseFrom);
+
+    private static final StubMethodDescriptor sayHelloAsyncMethod = new StubMethodDescriptor("SayHello",
+    org.apache.dubbo.sample.HelloRequest.class, java.util.concurrent.CompletableFuture.class, serviceDescriptor, MethodDescriptor.RpcType.UNARY,
+    obj -> ((Message) obj).toByteArray(), obj -> ((Message) obj).toByteArray(), org.apache.dubbo.sample.HelloRequest::parseFrom,
+    org.apache.dubbo.sample.HelloReply::parseFrom);
+
+    private static final StubMethodDescriptor sayHelloProxyAsyncMethod = new StubMethodDescriptor("SayHelloAsync",
+    org.apache.dubbo.sample.HelloRequest.class, org.apache.dubbo.sample.HelloReply.class, serviceDescriptor, MethodDescriptor.RpcType.UNARY,
+    obj -> ((Message) obj).toByteArray(), obj -> ((Message) obj).toByteArray(), org.apache.dubbo.sample.HelloRequest::parseFrom,
+    org.apache.dubbo.sample.HelloReply::parseFrom);
+
+
+
+
+
+    public static class GreeterStub implements Greeter{
+        private final Invoker<Greeter> invoker;
+
+        public GreeterStub(Invoker<Greeter> invoker) {
+            this.invoker = invoker;
+        }
+
+            /**
+         * <pre>
+         *  Sends a greeting
+         * </pre>
+         */
+        @Override
+        public org.apache.dubbo.sample.HelloReply sayHello(org.apache.dubbo.sample.HelloRequest request){
+            return StubInvocationUtil.unaryCall(invoker, sayHelloMethod, request);
+        }
+
+        public CompletableFuture<org.apache.dubbo.sample.HelloReply> sayHelloAsync(org.apache.dubbo.sample.HelloRequest request){
+            return StubInvocationUtil.unaryCall(invoker, sayHelloAsyncMethod, request);
+        }
+
+            /**
+         * <pre>
+         *  Sends a greeting
+         * </pre>
+         */
+        @Override
+        public void sayHello(org.apache.dubbo.sample.HelloRequest request, StreamObserver<org.apache.dubbo.sample.HelloReply> responseObserver){
+            StubInvocationUtil.unaryCall(invoker, sayHelloMethod , request, responseObserver);
+        }
+
+
+
+    }
+
+    public static abstract class GreeterImplBase implements Greeter, ServerService<Greeter> {
+
+        private <T, R> BiConsumer<T, StreamObserver<R>> syncToAsync(java.util.function.Function<T, R> syncFun) {
+            return new BiConsumer<T, StreamObserver<R>>() {
+                @Override
+                public void accept(T t, StreamObserver<R> observer) {
+                    try {
+                        R ret = syncFun.apply(t);
+                        observer.onNext(ret);
+                        observer.onCompleted();
+                    } catch (Throwable e) {
+                        observer.onError(e);
+                    }
+                }
+            };
+        }
+
+        @Override
+        public final Invoker<Greeter> getInvoker(URL url) {
+            PathResolver pathResolver = url.getOrDefaultFrameworkModel()
+            .getExtensionLoader(PathResolver.class)
+            .getDefaultExtension();
+            Map<String,StubMethodHandler<?, ?>> handlers = new HashMap<>();
+
+            pathResolver.addNativeStub( "/" + SERVICE_NAME + "/SayHello" );
+            pathResolver.addNativeStub( "/" + SERVICE_NAME + "/SayHelloAsync" );
+
+            BiConsumer<org.apache.dubbo.sample.HelloRequest, StreamObserver<org.apache.dubbo.sample.HelloReply>> sayHelloFunc = this::sayHello;
+            handlers.put(sayHelloMethod.getMethodName(), new UnaryStubMethodHandler<>(sayHelloFunc));
+            BiConsumer<org.apache.dubbo.sample.HelloRequest, StreamObserver<org.apache.dubbo.sample.HelloReply>> sayHelloAsyncFunc = syncToAsync(this::sayHello);
+            handlers.put(sayHelloProxyAsyncMethod.getMethodName(), new UnaryStubMethodHandler<>(sayHelloAsyncFunc));
+
+
+
+
+            return new StubInvoker<>(this, url, Greeter.class, handlers);
+        }
+
+
+        @Override
+        public org.apache.dubbo.sample.HelloReply sayHello(org.apache.dubbo.sample.HelloRequest request){
+            throw unimplementedMethodException(sayHelloMethod);
+        }
+
+
+
+
+
+        @Override
+        public final ServiceDescriptor getServiceDescriptor() {
+            return serviceDescriptor;
+        }
+        private RpcException unimplementedMethodException(StubMethodDescriptor methodDescriptor) {
+            return TriRpcStatus.UNIMPLEMENTED.withDescription(String.format("Method %s is unimplemented",
+                "/" + serviceDescriptor.getInterfaceName() + "/" + methodDescriptor.getMethodName())).asException();
+        }
+    }
+
+}
diff --git a/java_interop/protobuf-triple/java/java-server/build/protobuf/java/org/apache/dubbo/sample/Greeter.java b/java_interop/protobuf-triple/java/java-server/build/protobuf/java/org/apache/dubbo/sample/Greeter.java
new file mode 100644
index 0000000..e783758
--- /dev/null
+++ b/java_interop/protobuf-triple/java/java-server/build/protobuf/java/org/apache/dubbo/sample/Greeter.java
@@ -0,0 +1,64 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License.  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+    package org.apache.dubbo.sample;
+
+import org.apache.dubbo.common.stream.StreamObserver;
+import com.google.protobuf.Message;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.BiConsumer;
+import java.util.concurrent.CompletableFuture;
+
+public interface Greeter {
+
+    String JAVA_SERVICE_NAME = "org.apache.dubbo.sample.Greeter";
+    String SERVICE_NAME = "org.apache.dubbo.samples.Greeter";
+
+        /**
+         * <pre>
+         *  Sends a greeting
+         * </pre>
+         */
+    org.apache.dubbo.sample.HelloReply sayHello(org.apache.dubbo.sample.HelloRequest request);
+
+    default CompletableFuture<org.apache.dubbo.sample.HelloReply> sayHelloAsync(org.apache.dubbo.sample.HelloRequest request){
+        return CompletableFuture.completedFuture(sayHello(request));
+    }
+
+    /**
+    * This server stream type unary method is <b>only</b> used for generated stub to support async unary method.
+    * It will not be called if you are NOT using Dubbo3 generated triple stub and <b>DO NOT</b> implement this method.
+    */
+    default void sayHello(org.apache.dubbo.sample.HelloRequest request, StreamObserver<org.apache.dubbo.sample.HelloReply> responseObserver){
+        sayHelloAsync(request).whenComplete((r, t) -> {
+            if (t != null) {
+                responseObserver.onError(t);
+            } else {
+                responseObserver.onNext(r);
+                responseObserver.onCompleted();
+            }
+        });
+    }
+
+
+
+
+
+
+}
diff --git a/java_interop/protobuf-triple/java/java-server/build/protobuf/java/org/apache/dubbo/sample/HelloReply.java b/java_interop/protobuf-triple/java/java-server/build/protobuf/java/org/apache/dubbo/sample/HelloReply.java
new file mode 100644
index 0000000..8712757
--- /dev/null
+++ b/java_interop/protobuf-triple/java/java-server/build/protobuf/java/org/apache/dubbo/sample/HelloReply.java
@@ -0,0 +1,565 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: greet.proto
+
+package org.apache.dubbo.sample;
+
+/**
+ * <pre>
+ * The response message containing the greetings
+ * </pre>
+ *
+ * Protobuf type {@code org.apache.dubbo.samples.HelloReply}
+ */
+public final class HelloReply extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:org.apache.dubbo.samples.HelloReply)
+    HelloReplyOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use HelloReply.newBuilder() to construct.
+  private HelloReply(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private HelloReply() {
+    message_ = "";
+  }
+
+  @java.lang.Override
+  @SuppressWarnings({"unused"})
+  protected java.lang.Object newInstance(
+      UnusedPrivateParameter unused) {
+    return new HelloReply();
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private HelloReply(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            message_ = s;
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return org.apache.dubbo.sample.HelloWorldProto.internal_static_org_apache_dubbo_samples_HelloReply_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return org.apache.dubbo.sample.HelloWorldProto.internal_static_org_apache_dubbo_samples_HelloReply_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            org.apache.dubbo.sample.HelloReply.class, org.apache.dubbo.sample.HelloReply.Builder.class);
+  }
+
+  public static final int MESSAGE_FIELD_NUMBER = 1;
+  private volatile java.lang.Object message_;
+  /**
+   * <code>string message = 1;</code>
+   * @return The message.
+   */
+  @java.lang.Override
+  public java.lang.String getMessage() {
+    java.lang.Object ref = message_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      message_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string message = 1;</code>
+   * @return The bytes for message.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getMessageBytes() {
+    java.lang.Object ref = message_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      message_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(message_)) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 1, message_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(message_)) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, message_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof org.apache.dubbo.sample.HelloReply)) {
+      return super.equals(obj);
+    }
+    org.apache.dubbo.sample.HelloReply other = (org.apache.dubbo.sample.HelloReply) obj;
+
+    if (!getMessage()
+        .equals(other.getMessage())) return false;
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    hash = (37 * hash) + MESSAGE_FIELD_NUMBER;
+    hash = (53 * hash) + getMessage().hashCode();
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static org.apache.dubbo.sample.HelloReply parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static org.apache.dubbo.sample.HelloReply parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static org.apache.dubbo.sample.HelloReply parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static org.apache.dubbo.sample.HelloReply parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static org.apache.dubbo.sample.HelloReply parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static org.apache.dubbo.sample.HelloReply parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static org.apache.dubbo.sample.HelloReply parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static org.apache.dubbo.sample.HelloReply parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static org.apache.dubbo.sample.HelloReply parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static org.apache.dubbo.sample.HelloReply parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static org.apache.dubbo.sample.HelloReply parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static org.apache.dubbo.sample.HelloReply parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(org.apache.dubbo.sample.HelloReply prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * <pre>
+   * The response message containing the greetings
+   * </pre>
+   *
+   * Protobuf type {@code org.apache.dubbo.samples.HelloReply}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:org.apache.dubbo.samples.HelloReply)
+      org.apache.dubbo.sample.HelloReplyOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.apache.dubbo.sample.HelloWorldProto.internal_static_org_apache_dubbo_samples_HelloReply_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.apache.dubbo.sample.HelloWorldProto.internal_static_org_apache_dubbo_samples_HelloReply_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.apache.dubbo.sample.HelloReply.class, org.apache.dubbo.sample.HelloReply.Builder.class);
+    }
+
+    // Construct using org.apache.dubbo.sample.HelloReply.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      message_ = "";
+
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return org.apache.dubbo.sample.HelloWorldProto.internal_static_org_apache_dubbo_samples_HelloReply_descriptor;
+    }
+
+    @java.lang.Override
+    public org.apache.dubbo.sample.HelloReply getDefaultInstanceForType() {
+      return org.apache.dubbo.sample.HelloReply.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public org.apache.dubbo.sample.HelloReply build() {
+      org.apache.dubbo.sample.HelloReply result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public org.apache.dubbo.sample.HelloReply buildPartial() {
+      org.apache.dubbo.sample.HelloReply result = new org.apache.dubbo.sample.HelloReply(this);
+      result.message_ = message_;
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof org.apache.dubbo.sample.HelloReply) {
+        return mergeFrom((org.apache.dubbo.sample.HelloReply)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(org.apache.dubbo.sample.HelloReply other) {
+      if (other == org.apache.dubbo.sample.HelloReply.getDefaultInstance()) return this;
+      if (!other.getMessage().isEmpty()) {
+        message_ = other.message_;
+        onChanged();
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      org.apache.dubbo.sample.HelloReply parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (org.apache.dubbo.sample.HelloReply) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private java.lang.Object message_ = "";
+    /**
+     * <code>string message = 1;</code>
+     * @return The message.
+     */
+    public java.lang.String getMessage() {
+      java.lang.Object ref = message_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        message_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string message = 1;</code>
+     * @return The bytes for message.
+     */
+    public com.google.protobuf.ByteString
+        getMessageBytes() {
+      java.lang.Object ref = message_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        message_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string message = 1;</code>
+     * @param value The message to set.
+     * @return This builder for chaining.
+     */
+    public Builder setMessage(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      message_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string message = 1;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearMessage() {
+      
+      message_ = getDefaultInstance().getMessage();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string message = 1;</code>
+     * @param value The bytes for message to set.
+     * @return This builder for chaining.
+     */
+    public Builder setMessageBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      message_ = value;
+      onChanged();
+      return this;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:org.apache.dubbo.samples.HelloReply)
+  }
+
+  // @@protoc_insertion_point(class_scope:org.apache.dubbo.samples.HelloReply)
+  private static final org.apache.dubbo.sample.HelloReply DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new org.apache.dubbo.sample.HelloReply();
+  }
+
+  public static org.apache.dubbo.sample.HelloReply getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<HelloReply>
+      PARSER = new com.google.protobuf.AbstractParser<HelloReply>() {
+    @java.lang.Override
+    public HelloReply parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new HelloReply(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<HelloReply> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<HelloReply> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public org.apache.dubbo.sample.HelloReply getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/java_interop/protobuf-triple/java/java-server/build/protobuf/java/org/apache/dubbo/sample/HelloReplyOrBuilder.java b/java_interop/protobuf-triple/java/java-server/build/protobuf/java/org/apache/dubbo/sample/HelloReplyOrBuilder.java
new file mode 100644
index 0000000..71da562
--- /dev/null
+++ b/java_interop/protobuf-triple/java/java-server/build/protobuf/java/org/apache/dubbo/sample/HelloReplyOrBuilder.java
@@ -0,0 +1,21 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: greet.proto
+
+package org.apache.dubbo.sample;
+
+public interface HelloReplyOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:org.apache.dubbo.samples.HelloReply)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>string message = 1;</code>
+   * @return The message.
+   */
+  java.lang.String getMessage();
+  /**
+   * <code>string message = 1;</code>
+   * @return The bytes for message.
+   */
+  com.google.protobuf.ByteString
+      getMessageBytes();
+}
diff --git a/java_interop/protobuf-triple/java/java-server/build/protobuf/java/org/apache/dubbo/sample/HelloRequest.java b/java_interop/protobuf-triple/java/java-server/build/protobuf/java/org/apache/dubbo/sample/HelloRequest.java
new file mode 100644
index 0000000..b8a490a
--- /dev/null
+++ b/java_interop/protobuf-triple/java/java-server/build/protobuf/java/org/apache/dubbo/sample/HelloRequest.java
@@ -0,0 +1,565 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: greet.proto
+
+package org.apache.dubbo.sample;
+
+/**
+ * <pre>
+ * The request message containing the user's name.
+ * </pre>
+ *
+ * Protobuf type {@code org.apache.dubbo.samples.HelloRequest}
+ */
+public final class HelloRequest extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:org.apache.dubbo.samples.HelloRequest)
+    HelloRequestOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use HelloRequest.newBuilder() to construct.
+  private HelloRequest(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private HelloRequest() {
+    name_ = "";
+  }
+
+  @java.lang.Override
+  @SuppressWarnings({"unused"})
+  protected java.lang.Object newInstance(
+      UnusedPrivateParameter unused) {
+    return new HelloRequest();
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private HelloRequest(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            name_ = s;
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return org.apache.dubbo.sample.HelloWorldProto.internal_static_org_apache_dubbo_samples_HelloRequest_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return org.apache.dubbo.sample.HelloWorldProto.internal_static_org_apache_dubbo_samples_HelloRequest_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            org.apache.dubbo.sample.HelloRequest.class, org.apache.dubbo.sample.HelloRequest.Builder.class);
+  }
+
+  public static final int NAME_FIELD_NUMBER = 1;
+  private volatile java.lang.Object name_;
+  /**
+   * <code>string name = 1;</code>
+   * @return The name.
+   */
+  @java.lang.Override
+  public java.lang.String getName() {
+    java.lang.Object ref = name_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      name_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string name = 1;</code>
+   * @return The bytes for name.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getNameBytes() {
+    java.lang.Object ref = name_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      name_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(name_)) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 1, name_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(name_)) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, name_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof org.apache.dubbo.sample.HelloRequest)) {
+      return super.equals(obj);
+    }
+    org.apache.dubbo.sample.HelloRequest other = (org.apache.dubbo.sample.HelloRequest) obj;
+
+    if (!getName()
+        .equals(other.getName())) return false;
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    hash = (37 * hash) + NAME_FIELD_NUMBER;
+    hash = (53 * hash) + getName().hashCode();
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static org.apache.dubbo.sample.HelloRequest parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static org.apache.dubbo.sample.HelloRequest parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static org.apache.dubbo.sample.HelloRequest parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static org.apache.dubbo.sample.HelloRequest parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static org.apache.dubbo.sample.HelloRequest parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static org.apache.dubbo.sample.HelloRequest parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static org.apache.dubbo.sample.HelloRequest parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static org.apache.dubbo.sample.HelloRequest parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static org.apache.dubbo.sample.HelloRequest parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static org.apache.dubbo.sample.HelloRequest parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static org.apache.dubbo.sample.HelloRequest parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static org.apache.dubbo.sample.HelloRequest parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(org.apache.dubbo.sample.HelloRequest prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * <pre>
+   * The request message containing the user's name.
+   * </pre>
+   *
+   * Protobuf type {@code org.apache.dubbo.samples.HelloRequest}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:org.apache.dubbo.samples.HelloRequest)
+      org.apache.dubbo.sample.HelloRequestOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.apache.dubbo.sample.HelloWorldProto.internal_static_org_apache_dubbo_samples_HelloRequest_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.apache.dubbo.sample.HelloWorldProto.internal_static_org_apache_dubbo_samples_HelloRequest_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.apache.dubbo.sample.HelloRequest.class, org.apache.dubbo.sample.HelloRequest.Builder.class);
+    }
+
+    // Construct using org.apache.dubbo.sample.HelloRequest.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      name_ = "";
+
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return org.apache.dubbo.sample.HelloWorldProto.internal_static_org_apache_dubbo_samples_HelloRequest_descriptor;
+    }
+
+    @java.lang.Override
+    public org.apache.dubbo.sample.HelloRequest getDefaultInstanceForType() {
+      return org.apache.dubbo.sample.HelloRequest.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public org.apache.dubbo.sample.HelloRequest build() {
+      org.apache.dubbo.sample.HelloRequest result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public org.apache.dubbo.sample.HelloRequest buildPartial() {
+      org.apache.dubbo.sample.HelloRequest result = new org.apache.dubbo.sample.HelloRequest(this);
+      result.name_ = name_;
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof org.apache.dubbo.sample.HelloRequest) {
+        return mergeFrom((org.apache.dubbo.sample.HelloRequest)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(org.apache.dubbo.sample.HelloRequest other) {
+      if (other == org.apache.dubbo.sample.HelloRequest.getDefaultInstance()) return this;
+      if (!other.getName().isEmpty()) {
+        name_ = other.name_;
+        onChanged();
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      org.apache.dubbo.sample.HelloRequest parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (org.apache.dubbo.sample.HelloRequest) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private java.lang.Object name_ = "";
+    /**
+     * <code>string name = 1;</code>
+     * @return The name.
+     */
+    public java.lang.String getName() {
+      java.lang.Object ref = name_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        name_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string name = 1;</code>
+     * @return The bytes for name.
+     */
+    public com.google.protobuf.ByteString
+        getNameBytes() {
+      java.lang.Object ref = name_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        name_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string name = 1;</code>
+     * @param value The name to set.
+     * @return This builder for chaining.
+     */
+    public Builder setName(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      name_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string name = 1;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearName() {
+      
+      name_ = getDefaultInstance().getName();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string name = 1;</code>
+     * @param value The bytes for name to set.
+     * @return This builder for chaining.
+     */
+    public Builder setNameBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      name_ = value;
+      onChanged();
+      return this;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:org.apache.dubbo.samples.HelloRequest)
+  }
+
+  // @@protoc_insertion_point(class_scope:org.apache.dubbo.samples.HelloRequest)
+  private static final org.apache.dubbo.sample.HelloRequest DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new org.apache.dubbo.sample.HelloRequest();
+  }
+
+  public static org.apache.dubbo.sample.HelloRequest getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<HelloRequest>
+      PARSER = new com.google.protobuf.AbstractParser<HelloRequest>() {
+    @java.lang.Override
+    public HelloRequest parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new HelloRequest(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<HelloRequest> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<HelloRequest> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public org.apache.dubbo.sample.HelloRequest getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/java_interop/protobuf-triple/java/java-server/build/protobuf/java/org/apache/dubbo/sample/HelloRequestOrBuilder.java b/java_interop/protobuf-triple/java/java-server/build/protobuf/java/org/apache/dubbo/sample/HelloRequestOrBuilder.java
new file mode 100644
index 0000000..0573b3d
--- /dev/null
+++ b/java_interop/protobuf-triple/java/java-server/build/protobuf/java/org/apache/dubbo/sample/HelloRequestOrBuilder.java
@@ -0,0 +1,21 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: greet.proto
+
+package org.apache.dubbo.sample;
+
+public interface HelloRequestOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:org.apache.dubbo.samples.HelloRequest)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>string name = 1;</code>
+   * @return The name.
+   */
+  java.lang.String getName();
+  /**
+   * <code>string name = 1;</code>
+   * @return The bytes for name.
+   */
+  com.google.protobuf.ByteString
+      getNameBytes();
+}
diff --git a/java_interop/protobuf-triple/java/java-server/build/protobuf/java/org/apache/dubbo/sample/HelloWorldProto.java b/java_interop/protobuf-triple/java/java-server/build/protobuf/java/org/apache/dubbo/sample/HelloWorldProto.java
new file mode 100644
index 0000000..aed85f5
--- /dev/null
+++ b/java_interop/protobuf-triple/java/java-server/build/protobuf/java/org/apache/dubbo/sample/HelloWorldProto.java
@@ -0,0 +1,63 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: greet.proto
+
+package org.apache.dubbo.sample;
+
+public final class HelloWorldProto {
+  private HelloWorldProto() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_apache_dubbo_samples_HelloRequest_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_org_apache_dubbo_samples_HelloRequest_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_org_apache_dubbo_samples_HelloReply_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_org_apache_dubbo_samples_HelloReply_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\013greet.proto\022\030org.apache.dubbo.samples\"" +
+      "\034\n\014HelloRequest\022\014\n\004name\030\001 \001(\t\"\035\n\nHelloRe" +
+      "ply\022\017\n\007message\030\001 \001(\t2c\n\007Greeter\022X\n\010SayHe" +
+      "llo\022&.org.apache.dubbo.samples.HelloRequ" +
+      "est\032$.org.apache.dubbo.samples.HelloRepl" +
+      "yB?\n\027org.apache.dubbo.sampleB\017HelloWorld" +
+      "ProtoP\001Z\014/proto;proto\242\002\002WHb\006proto3"
+    };
+    descriptor = com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+        });
+    internal_static_org_apache_dubbo_samples_HelloRequest_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_org_apache_dubbo_samples_HelloRequest_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_org_apache_dubbo_samples_HelloRequest_descriptor,
+        new java.lang.String[] { "Name", });
+    internal_static_org_apache_dubbo_samples_HelloReply_descriptor =
+      getDescriptor().getMessageTypes().get(1);
+    internal_static_org_apache_dubbo_samples_HelloReply_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_org_apache_dubbo_samples_HelloReply_descriptor,
+        new java.lang.String[] { "Message", });
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/java_interop/protobuf-triple/java/java-server/pom.xml b/java_interop/protobuf-triple/java/java-server/pom.xml
new file mode 100644
index 0000000..3f7a7a6
--- /dev/null
+++ b/java_interop/protobuf-triple/java/java-server/pom.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>org.example</groupId>
+    <artifactId>java</artifactId>
+    <version>1.0-SNAPSHOT</version>
+
+    <properties>
+        <maven.compiler.source>8</maven.compiler.source>
+        <maven.compiler.target>8</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <dubbo.version>3.1.7</dubbo.version>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.13</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo</artifactId>
+            <version>${dubbo.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-dependencies-zookeeper-curator5</artifactId>
+            <type>pom</type>
+            <version>${dubbo.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.protobuf</groupId>
+            <artifactId>protobuf-java</artifactId>
+            <version>3.19.4</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <extensions>
+            <extension>
+                <groupId>kr.motd.maven</groupId>
+                <artifactId>os-maven-plugin</artifactId>
+                <version>1.6.1</version>
+            </extension>
+        </extensions>
+        <plugins>
+            <plugin>
+                <groupId>org.xolstice.maven.plugins</groupId>
+                <artifactId>protobuf-maven-plugin</artifactId>
+                <version>0.6.1</version>
+                <configuration>
+                    <protocArtifact>com.google.protobuf:protoc:3.19.4:exe:${os.detected.classifier}</protocArtifact>
+                    <protocPlugins>
+                        <protocPlugin>
+                            <id>dubbo</id>
+                            <groupId>org.apache.dubbo</groupId>
+                            <artifactId>dubbo-compiler</artifactId>
+                            <version>${dubbo.version}</version>
+                            <mainClass>org.apache.dubbo.gen.tri.Dubbo3TripleGenerator</mainClass>
+                        </protocPlugin>
+                    </protocPlugins>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>compile</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/java_interop/protobuf-triple/java/java-server/run.sh b/java_interop/protobuf-triple/java/java-server/run.sh
new file mode 100644
index 0000000..de9ebfb
--- /dev/null
+++ b/java_interop/protobuf-triple/java/java-server/run.sh
@@ -0,0 +1 @@
+mvn -e clean compile exec:java -Dexec.mainClass="org.apache.dubbo.sample.Provider"
\ No newline at end of file
diff --git a/java_interop/protobuf-triple/java/java-server/src/main/java/org/apache/dubbo/sample/GreeterImpl.java b/java_interop/protobuf-triple/java/java-server/src/main/java/org/apache/dubbo/sample/GreeterImpl.java
new file mode 100644
index 0000000..233e3d6
--- /dev/null
+++ b/java_interop/protobuf-triple/java/java-server/src/main/java/org/apache/dubbo/sample/GreeterImpl.java
@@ -0,0 +1,10 @@
+package org.apache.dubbo.sample;
+
+public class GreeterImpl extends DubboGreeterTriple.GreeterImplBase {
+    @Override
+    public HelloReply sayHello(HelloRequest request) {
+        return HelloReply.newBuilder()
+                .setMessage("Hello," + request.getName() + "!")
+                .build();
+    }
+}
\ No newline at end of file
diff --git a/java_interop/protobuf-triple/java/java-server/src/main/java/org/apache/dubbo/sample/Provider.java b/java_interop/protobuf-triple/java/java-server/src/main/java/org/apache/dubbo/sample/Provider.java
new file mode 100644
index 0000000..081697b
--- /dev/null
+++ b/java_interop/protobuf-triple/java/java-server/src/main/java/org/apache/dubbo/sample/Provider.java
@@ -0,0 +1,27 @@
+package org.apache.dubbo.sample;
+
+import org.apache.dubbo.common.constants.CommonConstants;
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.config.ProtocolConfig;
+import org.apache.dubbo.config.RegistryConfig;
+import org.apache.dubbo.config.ServiceConfig;
+import org.apache.dubbo.config.bootstrap.DubboBootstrap;
+
+import java.io.IOException;
+
+public class Producer {
+    public static void main(String[] args) throws IOException {
+        ServiceConfig<Greeter> service =  new ServiceConfig<>();
+        service.setInterface(Greeter.class);
+        service.setRef(new GreeterImpl());
+
+        DubboBootstrap bootstrap = DubboBootstrap.getInstance();
+        bootstrap.application(new ApplicationConfig("java-go-sample-server"))
+                .registry(new RegistryConfig("zookeeper://127.0.0.1:2181"))
+                .protocol(new ProtocolConfig(CommonConstants.TRIPLE,36969))
+                .service(service)
+                .start();
+        System.out.println("Dubbo triple java server started");
+        System.in.read();
+    }
+}
diff --git a/java_interop/protobuf-triple/java/java-server/src/main/proto/greet.proto b/java_interop/protobuf-triple/java/java-server/src/main/proto/greet.proto
new file mode 100644
index 0000000..ff5a800
--- /dev/null
+++ b/java_interop/protobuf-triple/java/java-server/src/main/proto/greet.proto
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//protoc --go_out=. --go_opt=paths=source_relative --go-triple_out=. greet.proto
+syntax = "proto3";
+package org.apache.dubbo.sample;
+
+option go_package = "/proto;proto";
+//package of go
+option java_package = 'org.apache.dubbo.sample';
+option java_multiple_files = true;
+option java_outer_classname = "HelloWorldProto";
+option objc_class_prefix = "WH";
+
+// The greeting service definition.
+service Greeter {
+  // Sends a greeting
+  rpc SayHello(HelloRequest) returns (HelloReply);
+  // Sends a greeting via stream
+  //  rpc SayHelloStream (stream HelloRequest) returns (stream HelloReply) {}
+}
+
+// The request message containing the user's name.
+message HelloRequest {
+  string name = 1;
+}
+
+// The response message containing the greetings
+message HelloReply {
+  string message = 1;
+}
\ No newline at end of file
diff --git a/java_interop/protobuf-triple/java/pom.xml b/java_interop/protobuf-triple/java/pom.xml
new file mode 100644
index 0000000..3f7a7a6
--- /dev/null
+++ b/java_interop/protobuf-triple/java/pom.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>org.example</groupId>
+    <artifactId>java</artifactId>
+    <version>1.0-SNAPSHOT</version>
+
+    <properties>
+        <maven.compiler.source>8</maven.compiler.source>
+        <maven.compiler.target>8</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <dubbo.version>3.1.7</dubbo.version>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.13</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo</artifactId>
+            <version>${dubbo.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-dependencies-zookeeper-curator5</artifactId>
+            <type>pom</type>
+            <version>${dubbo.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.protobuf</groupId>
+            <artifactId>protobuf-java</artifactId>
+            <version>3.19.4</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <extensions>
+            <extension>
+                <groupId>kr.motd.maven</groupId>
+                <artifactId>os-maven-plugin</artifactId>
+                <version>1.6.1</version>
+            </extension>
+        </extensions>
+        <plugins>
+            <plugin>
+                <groupId>org.xolstice.maven.plugins</groupId>
+                <artifactId>protobuf-maven-plugin</artifactId>
+                <version>0.6.1</version>
+                <configuration>
+                    <protocArtifact>com.google.protobuf:protoc:3.19.4:exe:${os.detected.classifier}</protocArtifact>
+                    <protocPlugins>
+                        <protocPlugin>
+                            <id>dubbo</id>
+                            <groupId>org.apache.dubbo</groupId>
+                            <artifactId>dubbo-compiler</artifactId>
+                            <version>${dubbo.version}</version>
+                            <mainClass>org.apache.dubbo.gen.tri.Dubbo3TripleGenerator</mainClass>
+                        </protocPlugin>
+                    </protocPlugins>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>compile</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file