Skip to content

Conversation

@Tsukikage7
Copy link

@Tsukikage7 Tsukikage7 commented Jan 6, 2026

What this PR does

This PR refactors and enhances the generic call sample to demonstrate both Dubbo protocol and Triple protocol generic calls between Go and Java.

Dependencies

This PR depends on apache/dubbo-go#3154 which adds NewGenericService API.
CI will pass after that PR is merged to main branch.

Background

The existing generic sample only demonstrated Dubbo protocol generic call. With the new Triple protocol generic call support in dubbo-go (see apache/dubbo-go#3154), this sample needs to be updated to showcase both protocols.

Changes Overview

1. Dual Protocol Support

The sample now demonstrates generic call on both protocols:

Protocol Port Group Description
Dubbo 20000 dubbo Traditional Dubbo binary protocol
Triple 50052 triple HTTP/2 based Triple protocol

2. Java Server Enhancement

Before: Single protocol, ZooKeeper dependency
After: Dual protocol, direct connection mode

// ApiProvider.java - Now exposes both protocols
public class ApiProvider {
    private static final int DUBBO_PORT = 20000;
    private static final int TRIPLE_PORT = 50052;

    public static void main(String[] args) {
        // Dubbo protocol service (group=dubbo)
        ServiceConfig<UserProvider> dubboService = new ServiceConfig<>();
        dubboService.setGroup("dubbo");
        dubboService.setProtocol(new ProtocolConfig("dubbo", DUBBO_PORT));

        // Triple protocol service (group=triple)
        ServiceConfig<UserProvider> tripleService = new ServiceConfig<>();
        tripleService.setGroup("triple");
        tripleService.setProtocol(new ProtocolConfig("tri", TRIPLE_PORT));

        // Bootstrap both services...
    }
}

3. Go Client Enhancement

Before: Only Dubbo protocol test
After: Tests both Dubbo and Triple protocols using new GenericService API

func main() {
    // Test Dubbo protocol generic call
    logger.Info("=== Testing Dubbo Protocol Generic Call ===")
    testDubboProtocol(ins)

    // Test Triple protocol generic call
    logger.Info("=== Testing Triple Protocol Generic Call ===")
    testTripleProtocol(ins)
}

func testDubboProtocol(ins *dubbo.Instance) {
    cli, _ := ins.NewClient(
        client.WithClientProtocolDubbo(),
        client.WithClientSerialization(constant.Hessian2Serialization),
    )
    // Use NewGenericService for traditional Dubbo-style generic call API
    genericService, _ := cli.NewGenericService(UserProvider,
        client.WithURL("dubbo://127.0.0.1:20000"),
        client.WithVersion("1.0.0"),
        client.WithGroup("dubbo"),
    )
    runGenericTests(genericService, "Dubbo")
}

func testTripleProtocol(ins *dubbo.Instance) {
    cli, _ := ins.NewClient(
        client.WithClientProtocolTriple(),
        client.WithClientSerialization(constant.Hessian2Serialization),
    )
    // Use NewGenericService for traditional Dubbo-style generic call API
    genericService, _ := cli.NewGenericService(UserProvider,
        client.WithURL("tri://127.0.0.1:50052"),
        client.WithVersion("1.0.0"),
        client.WithGroup("triple"),
    )
    runGenericTests(genericService, "Triple")
}

// GenericService.Invoke provides traditional $invoke style API
func runGenericTests(svc *generic.GenericService, protocol string) {
    // GetUser1(String)
    result, _ := svc.Invoke(ctx, "GetUser1",
        []string{"java.lang.String"},
        []hessian.Object{"A003"})
    logger.Infof("[%s] GetUser1 res: %+v", protocol, result)

    // QueryUser(User) - POJO parameter
    result, _ = svc.Invoke(ctx, "QueryUser",
        []string{"org.apache.dubbo.samples.User"},
        []hessian.Object{&pkg.User{ID: "001", Name: "test", Age: 25}})
    logger.Infof("[%s] QueryUser res: %+v", protocol, result)
}

4. Comprehensive Test Suite

Added client_test.go with 19 test cases:

Dubbo Protocol Tests (6 cases):

  • TestDubboGenericCall_StringArg
  • TestDubboGenericCall_MultipleArgs
  • TestDubboGenericCall_IntArg
  • TestDubboGenericCall_NoArgs
  • TestDubboGenericCall_ArrayArg
  • TestDubboGenericCall_POJOArg

Triple Protocol Tests (13 cases):

  • TestTripleGenericCall_StringArg
  • TestTripleGenericCall_MultipleArgs
  • TestTripleGenericCall_IntArg
  • TestTripleGenericCall_NoArgs
  • TestTripleGenericCall_ArrayArg
  • TestTripleGenericCall_POJOArg
  • TestTripleGenericCall_POJOArrayArg
  • TestTripleGenericCall_MapResult
  • TestTripleGenericCall_ListResult
  • TestTripleGenericCall_EmptyArrayArg
  • TestTripleGenericCall_NonExistentMethod
  • TestTripleGenericCall_WithTimeout
  • TestTripleGenericCall_WithCancelledContext

Benchmarks:

  • BenchmarkDubboGenericCall
  • BenchmarkTripleGenericCall

5. Project Structure Simplification

Before (nested directories):

generic/
├── java-server/
│   └── java-server/     # Redundant nesting
│       ├── pom.xml
│       └── src/
├── java-client/
│   └── java-client/     # Redundant nesting
│       ├── pom.xml
│       └── src/

After (flat structure):

generic/
├── java-server/
│   ├── pom.xml
│   ├── run.sh
│   └── src/
├── java-client/
│   ├── pom.xml
│   ├── run.sh
│   └── src/
├── go-server/
│   └── cmd/
├── go-client/
│   └── cmd/
│       ├── client.go
│       └── client_test.go

6. Removed ZooKeeper Dependency

  • Changed from registry-based service discovery to direct URL connection
  • Simplifies local testing and CI/CD pipelines
  • No external dependencies required to run the sample

Files Changed

File Change Type Description
generic/java-server/src/.../ApiProvider.java Modified Dual protocol support
generic/java-client/src/.../ApiTripleConsumer.java Added Triple protocol consumer
generic/go-client/cmd/client.go Modified Both protocol tests
generic/go-client/cmd/client_test.go Added 19 test cases + benchmarks
generic/go-server/cmd/server.go Modified Enhanced server
generic/go-server/pkg/user_provider.go Modified Cleaner implementation
generic/java-server/run.sh Added Easy run script
generic/java-client/run.sh Added Easy run script
generic/README.md Modified Updated documentation
generic/README_zh.md Modified Updated Chinese documentation
generic/java-*/java-*/ Deleted Removed redundant nesting
generic/build/test.sh Deleted Obsolete test script

How to Test

1. Start Java Server

cd generic/java-server
./run.sh

2. Run Go Client Tests

cd generic/go-client/cmd
go test -v

3. Or Run Go Client Manually

cd generic/go-client/cmd
go run client.go

Test Results

=== Testing Dubbo Protocol Generic Call ===
[Dubbo] GetUser1(userId string) res: map[age:48 class:org.apache.dubbo.samples.User ...]
[Dubbo] GetUser2(userId string, name string) res: map[age:48 ...]
[Dubbo] GetUser3(userCode int) res: map[age:48 ...]
[Dubbo] GetUser4(userCode int, name string) res: map[age:48 ...]
[Dubbo] GetOneUser() res: map[age:48 ...]
[Dubbo] GetUsers(userIdList []string) res: [map[age:48 ...] map[age:48 ...] ...]
[Dubbo] GetUsersMap(userIdList []string) res: map[001:map[age:48 ...] ...]
[Dubbo] QueryAll() res: [map[age:48 ...] map[age:48 ...]]
[Dubbo] QueryUser(user *User) res: map[age:25 ...]
[Dubbo] QueryUsers(users []*User) res: [map[age:24 ...] map[age:21 ...]]

=== Testing Triple Protocol Generic Call ===
[Triple] GetUser1(userId string) res: map[age:48 ...]
[Triple] GetUser2(userId string, name string) res: map[age:48 ...]
[Triple] GetUser3(userCode int) res: map[age:48 ...]
[Triple] GetUser4(userCode int, name string) res: map[age:48 ...]
[Triple] GetOneUser() res: map[age:48 ...]
[Triple] GetUsers(userIdList []string) res: [map[age:48 ...] ...]
[Triple] GetUsersMap(userIdList []string) res: map[001:map[age:48 ...] ...]
[Triple] QueryAll() res: [map[age:48 ...] map[age:48 ...]]
[Triple] QueryUser(user *User) res: map[age:25 ...]
[Triple] QueryUsers(users []*User) res: [map[age:24 ...] map[age:21 ...]]

All generic call tests completed

Related PRs


Signed-off-by: TsukiKage [email protected]

@Tsukikage7 Tsukikage7 force-pushed the test/generic-interop-enhanced branch 4 times, most recently from 9babfa4 to da7f82d Compare January 6, 2026 04:03
@Tsukikage7
Copy link
Author

⚠️ CI Failure Note

The golangci-lint check fails because this PR uses NewGenericService API which is added in apache/dubbo-go#3154.

CI will pass after apache/dubbo-go#3154 is merged to main branch.

Dependency chain:

  1. feat(triple): support generic call for Triple protocol dubbo-go#3154 (adds NewGenericService API) - merge first
  2. This PR (uses the new API) - merge after

…ocols

Add comprehensive generic call examples demonstrating Go-Java interoperability
using both Dubbo and Triple protocols with hessian2 serialization.

Features:
- Go client generic call examples for various parameter types
- Java server supporting both Dubbo (port 20000) and Triple (port 50052)
- Test cases covering basic types, collections, and POJO types
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors the generic call sample to demonstrate both Dubbo and Triple protocol generic calls between Go and Java. The refactoring includes dual protocol support, project structure simplification, and a comprehensive test suite with 19 test cases.

Changes:

  • Added dual protocol support (Dubbo on port 20000 and Triple on port 50052) with separate service groups
  • Refactored project structure by removing redundant nested directories (java-server/java-server → java-server)
  • Added comprehensive test coverage with 19 test cases and 2 benchmarks for generic calls
  • Changed QueryUsers signature from List to User[] for consistency

Reviewed changes

Copilot reviewed 30 out of 38 changed files in this pull request and generated 16 comments.

Show a summary per file
File Description
go.mod Added local replace directive for dubbo-go dependency (temporary)
generic/java-server/src/main/java/org/apache/dubbo/samples/ApiProvider.java New dual protocol server implementation
generic/java-server/src/main/java/org/apache/dubbo/samples/User.java Added User POJO class
generic/java-server/src/main/java/org/apache/dubbo/samples/Gender.java Added Gender enum
generic/java-server/src/main/java/org/apache/dubbo/samples/UserProvider.java Changed QueryUsers from List to array
generic/java-server/src/main/java/org/apache/dubbo/samples/UserProviderImpl.java Updated QueryUsers implementation
generic/java-client/src/main/java/org/apache/dubbo/samples/ApiTripleConsumer.java New Triple protocol consumer
generic/java-client/pom.xml New client pom configuration
generic/go-server/cmd/server.go Simplified server implementation
generic/go-server/pkg/user_provider.go Added Invoke method for generic calls
generic/go-client/cmd/client.go Refactored to test both protocols
generic/go-client/cmd/client_test.go Added comprehensive test suite
generic/README.md Updated documentation
generic/README_zh.md Updated Chinese documentation

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +19 to +23
Start ZooKeeper:

## Registry
```bash
docker run -d --name zookeeper -p 2181:2181 zookeeper:3.8
```
Copy link

Copilot AI Jan 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both README files include instructions to start ZooKeeper in the "Prerequisites" section using docker, but the PR description states that ZooKeeper dependency was removed. The Prerequisites sections in both README.md and README_zh.md should be updated to reflect the direct connection mode that doesn't require ZooKeeper.

Copilot uses AI. Check for mistakes.
```

## 运行示例
客户端通过 ZooKeeper 发现服务,使用 `client.WithGenericType("true")` 进行泛化调用。
Copy link

Copilot AI Jan 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Chinese README states "客户端通过 ZooKeeper 发现服务" (client discovers service through ZooKeeper), but the client.go implementation uses direct URLs via client.WithURL() rather than ZooKeeper-based service discovery. The documentation should be updated to reflect the actual implementation.

Suggested change
客户端通过 ZooKeeper 发现服务,使用 `client.WithGenericType("true")` 进行泛化调用。
客户端通过直连服务地址(例如使用 `client.WithURL("tri://127.0.0.1:50052")`)调用服务,并使用 `client.WithGenericType("true")` 进行泛化调用。

Copilot uses AI. Check for mistakes.
)

replace (
dubbo.apache.org/dubbo-go/v3 => ../dubbo-go
Copy link

Copilot AI Jan 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The local replace directive points to a relative path '../dubbo-go' which is a temporary development dependency. This should be removed before merging to production. The PR description mentions this depends on apache/dubbo-go#3154, so this replace directive should only be present during development/testing and removed once that PR is merged.

Copilot uses AI. Check for mistakes.
- QueryUser(User user)
- QueryUsers(List<User> userObjectList)
- QueryAll()
- Do NOT start Go Server and Java Server at the same time. Both listen on port 50052.
Copy link

Copilot AI Jan 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The README states "Do NOT start Go Server and Java Server at the same time. Both listen on port 50052." However, according to the ApiProvider.java code, the Java server uses Dubbo protocol on port 20000 and Triple protocol on port 50052, while the Go server only uses port 50052. The documentation should clarify that the conflict is specifically for the Triple protocol port.

Suggested change
- Do NOT start Go Server and Java Server at the same time. Both listen on port 50052.
- Do NOT start the Go Server and the Java Server's Triple protocol endpoint on the same host at the same time, because both use port 50052 for Triple.

Copilot uses AI. Check for mistakes.
Comment on lines +19 to +23
启动 ZooKeeper:

- Docker 和 Docker Compose 用于运行 ZooKeeper 注册中心
- Go 1.23+ 用于 Dubbo-Go 示例
- Java 8+ 和 Maven 用于 Dubbo Java 示例
```bash
docker run -d --name zookeeper -p 2181:2181 zookeeper:3.8
```
Copy link

Copilot AI Jan 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Chinese README also includes ZooKeeper setup instructions in the Prerequisites section, which is inconsistent with the direct connection approach described in the PR. This section should be updated to match the removal of ZooKeeper dependency.

Copilot uses AI. Check for mistakes.
Comment on lines 40 to 43
dubbo.WithRegistry(
registry.WithZookeeper(),
registry.WithAddress(RegistryAddress),
registry.WithAddress("127.0.0.1:2181"),
),
Copy link

Copilot AI Jan 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Go server uses ZooKeeper registry (registry.WithZookeeper() and address "127.0.0.1:2181"), but the PR description states that ZooKeeper dependency was removed in favor of direct connection mode. The Java server in ApiProvider.java correctly uses direct export with registry address "N/A". The Go server should be updated to match this approach for consistency.

Copilot uses AI. Check for mistakes.
- QueryUsers(List<User> userObjectList)
- QueryAll()
- Do NOT start Go Server and Java Server at the same time. Both listen on port 50052.
- Make sure ZooKeeper is running before starting the server or client.
Copy link

Copilot AI Jan 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The README.md states "Make sure ZooKeeper is running before starting the server or client," but the PR description indicates ZooKeeper dependency was removed in favor of direct connection mode. The updated Java server uses direct export (registry address "N/A"). This documentation is inconsistent with the implementation changes and should be updated.

Copilot uses AI. Check for mistakes.
```shell
# 启动 ZooKeeper 注册中心
docker run -d --name zookeeper -p 2181:2181 zookeeper:3.4.14
服务端监听 `50052` 端口,并注册到 ZooKeeper。
Copy link

Copilot AI Jan 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Chinese README states the Go server "并注册到 ZooKeeper" (registers to ZooKeeper), but the PR description indicates ZooKeeper dependency was removed. While the current Go server implementation does still use ZooKeeper, according to the PR goals this should be changed to direct connection mode for consistency.

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,7 @@
dubbo.application.name=generic-java-server
dubbo.registry.address=zookeeper://127.0.0.1:2181
Copy link

Copilot AI Jan 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dubbo.properties file references a ZooKeeper registry address, but according to the PR description, ZooKeeper dependency was removed in favor of direct connection mode. This configuration file appears to be inconsistent with the new direct connection approach used in ApiProvider.java which sets registry address to "N/A".

Copilot uses AI. Check for mistakes.
- QueryUsers(List<User> userObjectList)
- QueryAll()
- 不要同时启动 Go 服务端和 Java 服务端,它们都监听 50052 端口。
- 启动服务端或客户端之前,请确保 ZooKeeper 正在运行。
Copy link

Copilot AI Jan 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Chinese documentation has the same issue as the English version - it states "启动服务端或客户端之前,请确保 ZooKeeper 正在运行" (Make sure ZooKeeper is running before starting the server or client), but this is inconsistent with the removal of ZooKeeper dependency mentioned in the PR description. The documentation should be updated to reflect the direct connection approach.

Copilot uses AI. Check for mistakes.
@AlexStocks
Copy link
Contributor

Please fix the ci failure and review the copilot's comment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants