Skip to content

fix(generic): support variadic method invocation via generic call#3284

Open
mochengqian wants to merge 2 commits intoapache:developfrom
mochengqian:fix/generic-variadic-support
Open

fix(generic): support variadic method invocation via generic call#3284
mochengqian wants to merge 2 commits intoapache:developfrom
mochengqian:fix/generic-variadic-support

Conversation

@mochengqian
Copy link
Copy Markdown
Contributor

@mochengqian mochengqian commented Apr 6, 2026

Description

Fixes issue #3259
注意:本次PR为短期方案,但是已经可以关闭issue #3259

背景
Java 客户端通过泛化调用($invoke)访问 Go 服务端定义了变长参数(...T)的方法时,
框架会触发 reflect.Value.Call panic,导致调用 100% 失败(测试见issue的comment)。

根因

两层问题叠加:

  1. service_filter.go 参数数量校验过严argsType 中变长参数被记录为单个切片类型
    (如 []string),但 Java 端可能以离散形式发送多个 args,
    len(args) != len(argsType) 直接拒绝
  2. callLocalMethod 使用 reflect.Value.Call() — 即使参数数量对齐,
    已打包为切片的变长参数传入 Call() 时会因类型不匹配触发
    panic: cannot use []string as type string in Call

修复方案

采用统一数组传参 + CallSlice 动态类型重塑策略,改动封锁在框架内部,
对外部业务代码零侵入:

文件 改动
common/rpc_service.go MethodType 新增 IsVariadic() 方法,暴露变长方法元信息
filter/generic/service_filter.go 识别变长方法后,将 Java 传来的离散 args 或数组 args 通过 reflect.MakeSlice 重塑为精确类型切片
proxy/proxy_factory/utils.go 变长方法且尾参数为切片时使用 CallSlice 替代 Call
proxy/proxy_factory/default.go variadic 分支优先于 []interface{} passthrough 检测,避免 ...interface{} 被错误多包一层

支持 Java 端两种传参形式:

  • Form A(离散传参)args: ["a", "b"] — 框架自动收拢为切片
  • Form B(数组传参)args: [["a", "b"]] — 框架自动解包内层数组

用户现在怎么调用:

Java 泛化调用 Go variadic 方法,两种传参方式都支持了:

方式 A:离散传参
genericService.$invoke(
"MultiArgs",
new String[]{"java.lang.String", "java.lang.String"},
new Object[]{"a", "b"}
);

方式 B:数组传参(推荐)
genericService.$invoke(
"MultiArgs",
new String[]{"[Ljava.lang.String;"},
new Object[]{new String[]{"a", "b"}}
);

非泛化调用也正常工作,Java 端按普通方法调用即可。

边界条件处理

场景 行为
零变长参数(空数组/未传参数) 构造长度为 0 的空切片,不 panic
单变长参数 正常投递,不误解析为多重嵌套
...interface{} 混合类型 直接接受任何值,不做强转
固定参数 + 变长参数混合 固定部分走常规 Realize,尾部进入变长重塑
显式 nil 注入 等同于零参数调用,不解引用 panic

Checklist

  • I confirm the target branch is develop
  • Code has passed local testing
  • I have added tests that prove my fix is effective or that my feature works

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Apr 6, 2026

Codecov Report

❌ Patch coverage is 61.73285% with 106 lines in your changes missing coverage. Please review.
✅ Project coverage is 49.68%. Comparing base (60d1c2a) to head (06bbd4e).
⚠️ Report is 767 commits behind head on develop.

Files with missing lines Patch % Lines
filter/generic/service_filter.go 57.73% 68 Missing and 14 partials ⚠️
protocol/triple/server.go 64.86% 9 Missing and 4 partials ⚠️
proxy/proxy_factory/default.go 76.19% 2 Missing and 3 partials ⚠️
server/server.go 76.47% 2 Missing and 2 partials ⚠️
common/rpc_service.go 0.00% 2 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #3284      +/-   ##
===========================================
+ Coverage    46.76%   49.68%   +2.91%     
===========================================
  Files          295      469     +174     
  Lines        17172    34841   +17669     
===========================================
+ Hits          8031    17310    +9279     
- Misses        8287    16124    +7837     
- Partials       854     1407     +553     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown
Contributor

@AlexStocks AlexStocks left a comment

Choose a reason for hiding this comment

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

Code review

Copy link
Copy Markdown
Contributor

@AlexStocks AlexStocks left a comment

Choose a reason for hiding this comment

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

Additional code review

Copy link
Copy Markdown
Contributor

@AlexStocks AlexStocks left a comment

Choose a reason for hiding this comment

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

Additional suggestions

@AlexStocks AlexStocks requested a review from Copilot April 7, 2026 09:29
@AlexStocks AlexStocks added the 3.3.2 version 3.3.2 label Apr 7, 2026
@AlexStocks
Copy link
Copy Markdown
Contributor

Please attention that your PR target branch should be develop.

@AlexStocks AlexStocks changed the base branch from main to develop April 7, 2026 09:30
Copy link
Copy Markdown
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

Note

Copilot was unable to run its full agentic suite in this review.

This PR fixes generic ($invoke) calls from Java into Go methods with variadic parameters (...T) by reshaping generic args into a typed slice and invoking the target method using reflect.CallSlice when appropriate, preventing reflect.Value.Call panics (issue #3259).

Changes:

  • Expose variadic metadata via MethodType.IsVariadic().
  • Update generic service filter to validate variadic arg counts and reshape trailing args into the correct typed slice.
  • Update proxy invocation to prefer variadic handling and use CallSlice when the final argument is already a slice.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
common/rpc_service.go Adds IsVariadic() to expose variadic method info.
filter/generic/service_filter.go Validates variadic arg counts and reshapes variadic args into typed slices for invocation.
proxy/proxy_factory/utils.go Uses CallSlice for pre-packed variadic slices to avoid reflection panics.
proxy/proxy_factory/default.go Ensures variadic branch runs before []interface{} passthrough logic.

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

@mochengqian mochengqian force-pushed the fix/generic-variadic-support branch from dd65da7 to 06bbd4e Compare April 7, 2026 15:28
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud bot commented Apr 7, 2026

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Java 泛化调用 dubbo-go,dubbo go 为可变形参,该怎么传参?

5 participants