dubbo版本2.5.4
dubbo开启消费端参数校验时,validation = "true"
会报如下异常:
[CurrentUser(userId=200887212, username=15210165164)] [http-nio-8837-exec-9] [WARN ] [] warn 62 - [DUBBO] .PLRepaymentPlanService_GetRepaymentPlanByOrderIdParameter: frozen class (cannot edit), dubbo version: 2.5.4, current host: 10.41.42.56 : .PLRepaymentPlanService_GetRepaymentPlanByOrderIdParameter: frozen class (cannot edit)
该问题在升级的dubbo版本中得到了解决 目前可用dubbo版本 2.7.2
同问题链接:/apache/dubbo/issues/796
问题描述
使用Spring Boot构建web app,Controller中通过dubbo消费端远程调用服务端,使用注解进行参数校验,如getName(@NotNull String id)。
在调用过程中始终报错:
: XXXService_GetNameParameter: frozen class (cannot edit)
at (:617) ~[javassist-3.21.:?]
at (:859) ~[javassist-3.21.:?]
at (:836) ~[javassist-3.21.:?]
at (:166)
问题分析
- 初步判断和dubbo版本无关,应该是一个bug。报错的原因是再次尝试查找动态生成的类时,应该能找到,实际上因为classloader的原因无法找到。即第163行:
parameterClass = (Class<?>) (parameterClassName, true, ());
这里应该能够找到parameterClass,而不是再次抛出ClassNotFoundException。 - 出现ClassNotFoundException的原因,是由于在生成参数类XXXService_GetNameParameter的时候,没有传入该参数的接口的classLoader(即),而是使用了默认的Context ClassLoader。
- 建议修改JValidator第202行为:
parameterClass = ((), null);
传入接口的classLoader,保证其一致性。
老版本dubbo此处代码:
parameterClass = ();
新版本dubbo 此处的代码:
parameterClass = ((), (ProtectionDomain)null);