From dubbo-go
Guides interoperability between dubbo-go v3 and dubbo-java — cross-language RPC calls using Triple+Protobuf or Dubbo+Hessian2. Use when user asks how to call a Java Dubbo service from Go, expose a Go service to Java clients, share a proto/interface across languages, or pick between Triple and Dubbo protocols for interop.
How this skill is triggered — by the user, by Claude, or both
Slash command
/dubbo-go:java-interopThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Interop is one of dubbo-go's distinctive strengths: a single service definition can be served by Go and consumed by Java (or vice versa) without a gateway. Two viable paths:
Interop is one of dubbo-go's distinctive strengths: a single service definition can be served by Go and consumed by Java (or vice versa) without a gateway. Two viable paths:
| Path | Wire format | Serialization | When to use |
|---|---|---|---|
| Triple + Protobuf (recommended) | HTTP/2 | Protobuf | New services, polyglot teams, gRPC-compatible clients |
| Dubbo + Hessian2 | TCP (dubbo) | Hessian2 | Calling existing Java services that were originally defined with Java interfaces (no .proto) |
Pick Triple unless you're integrating with an existing Hessian2-based Java codebase.
Shared .proto file drives both sides. Set both go_package and java_package:
syntax = "proto3";
package org.apache.dubbo.sample;
option go_package = "github.com/yourorg/yourapp/proto;greet";
option java_package = "org.apache.dubbo.sample";
option java_multiple_files = true;
service Greeter {
rpc SayHello(HelloRequest) returns (HelloReply);
}
message HelloRequest { string name = 1; }
message HelloReply { string message = 1; }
Go server — nothing interop-specific, just plain Triple:
srv, _ := server.NewServer(
server.WithServerProtocol(
protocol.WithPort(20000),
protocol.WithTriple(),
),
)
greet.RegisterGreeterHandler(srv, &impl{})
srv.Serve()
Testing interop without a client — Triple supports JSON over HTTP/1.1, so you can verify a Go Triple server from any HTTP tool:
curl -H "Content-Type: application/json" \
-d '{"name":"Dubbo"}' \
http://localhost:20000/org.apache.dubbo.sample.Greeter/sayHello
The path is /<java_package>.<service>/<method> — note the lowercase-first-letter method name (Java camelCase convention).
Java client calling the Go server uses standard dubbo-java APIs; no Go-specific code. See java_interop/protobuf-triple for the full working pair.
SayHello in Go and sayHello on the Java wire. The HTTP route uses the lowercase-first form.java_package in the proto is what Java's dubbo picks up as the interface FQN. Pick it deliberately — renaming later is a breaking change.grpcurl can list services without extra config.Use this when the service was defined by a Java interface (no .proto) and you need to add a Go side.
The Go side must mirror the Java POJO exactly, via Hessian2 registration. Each field name, type, and JavaClassName() must match the Java class.
package greet
import (
dubbo_go_hessian2 "github.com/apache/dubbo-go-hessian2"
)
type GreetRequest struct {
Name string
}
// Must match the Java class's fully-qualified name
func (x *GreetRequest) JavaClassName() string {
return "org.apache.dubbo.hessian2.api.GreetRequest"
}
type GreetResponse struct {
Greeting string
}
func (x *GreetResponse) JavaClassName() string {
return "org.apache.dubbo.hessian2.api.GreetResponse"
}
func init() {
dubbo_go_hessian2.RegisterPOJO(new(GreetRequest))
dubbo_go_hessian2.RegisterPOJO(new(GreetResponse))
}
Go server:
srv, _ := server.NewServer(
server.WithServerProtocol(
protocol.WithPort(20000),
protocol.WithDubbo(), // NOT Triple
),
)
greet.RegisterGreetingsServiceHandler(srv, &impl{})
srv.Serve()
Generate the Go stub from the same proto that describes the Java interface with protoc-gen-go-dubbo (different plugin from protoc-gen-go-triple). That's what produces greet.dubbo.go and greet.hessian2.go.
See java_interop/non-protobuf-dubbo.
hessian: failed to decode at runtime. Always RegisterPOJO in the package's init().enum maps to Go int (ordinal), not string — unless the Java side customized serialization.Date ↔ Go time.Time generally works; java.time.* types need extra care.If both sides use the same registry (Nacos / ZooKeeper), they discover each other automatically — the registry entry is language-agnostic, just a URL with protocol + address.
dubbo.NewInstance(
dubbo.WithName("polyglot-service"), // same application name as Java side
dubbo.WithRegistry(registry.WithNacos(), registry.WithAddress("127.0.0.1:8848")),
dubbo.WithProtocol(protocol.WithTriple(), protocol.WithPort(20000)),
)
See java_interop/service_discovery.
| Scenario | Path |
|---|---|
| New service, Go + Java teams both need clients | Triple + Protobuf |
| Calling an existing Java Dubbo service defined by Java interface | Dubbo + Hessian2 |
| Legacy Java service exports both Triple and Dubbo endpoints | Triple + Protobuf on Go side |
| Need gRPC-compatible wire | Triple + Protobuf |
| Can't touch Java side, and it's not Protobuf | Dubbo + Hessian2 |
Official guide: Interoperability with Dubbo Java
Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub tsukikage7/dubbo-go-skills --plugin dubbo-go