xuxueli / xxl-job

A distributed task scheduling framework.(分布式任务调度平台XXL-JOB)
http://www.xuxueli.com/xxl-job/
GNU General Public License v3.0
27.46k stars 10.86k forks source link

xxl-rpc xxlRpcResponse.getErrorMsg() != null 判断导致ErrorMsg为空字符串时抛异常 #2598

Open youbeiwuhuan opened 3 years ago

youbeiwuhuan commented 3 years ago

Which version of XXL-JOB do you using?

2.1.2

问题背景:适配go语言执行器,已完成2.3.0的适配,现在适配2.1.2。(代码链接:https://gitee.com/youbeiwuhuan/go-xxljob-executor/tree/dev2.1.2/

问题描述: 点击后台执行一次任务,执行器端用gin+dubbo-go-hessian2 能正常接收并解析出xxl-rpc发送的得XxlRpcRequest对象,但向调度器返回XxlRpcResponse时,调度器抛以下异常 com.xxl.rpc.util.XxlRpcException: at com.xxl.rpc.remoting.invoker.reference.XxlRpcReferenceBean$1.invoke(XxlRpcReferenceBean.java:244) at com.sun.proxy.$Proxy103.run(Unknown Source) at com.xxl.job.admin.core.trigger.XxlJobTrigger.runExecutor(XxlJobTrigger.java:196) at com.xxl.job.admin.core.trigger.XxlJobTrigger.processTrigger(XxlJobTrigger.java:149) at com.xxl.job.admin.core.trigger.XxlJobTrigger.trigger(XxlJobTrigger.java:74) at com.xxl.job.admin.core.thread.JobTriggerPoolHelper$3.run(JobTriggerPoolHelper.java:90) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748)

经debug,发现 XxlRpcReferrenceBean.java 243行

XxlRpcResponse xxlRpcResponse = futureResponse.get(timeout, TimeUnit.MILLISECONDS); if (xxlRpcResponse.getErrorMsg() != null) { throw new XxlRpcException(xxlRpcResponse.getErrorMsg()); } return xxlRpcResponse.getResult();

这里判断xxlRpcResponse.getErrorMsg() != null,而go语言的ErrorMsg 为string类型,string类型的零值为“”(空字符串),不是nil,转化为java对象则是空字符串导致这里异常,所以读不到返回数据,并非协议报文出问题。

这里要是判断xxlRpcResponse.getErrorMsg() != null && !"".equals( xxlRpcResponse.getErrorMsg().trim()) 就好了

youbeiwuhuan commented 3 years ago

个人已解决,方案:多定义一个类,把ErrorMsg
// 解决xxl-rpc 中返回 errorMsg 为空字符仍报错问题(xxl-rpc的坑) type XxlRpcResponse2 struct { RequestId string hessian:"requestId" json:"requestId" ErrorMsg interface{} hessian:"errorMsg" json:"errorMsg" Result interface{} hessian:"result" json:"result" }

func NewXxlRpcResponse2(r *XxlRpcResponse) XxlRpcResponse2 { return XxlRpcResponse2{ RequestId: r.RequestId, ErrorMsg: nil, // 这里设为nil,dubbo-go-hessian2转化为Java对象就是null Result: r.Result, } }

func (XxlRpcResponse2) JavaClassName() string { return "com.xxl.rpc.remoting.net.params.XxlRpcResponse" }

虽然已解决,但还是希望xxl-job代码多注意规范性,把项目影响力扩大