Dubboで発生した異常-frozen class(cannot edit)

2236 ワード

dubboバージョン2.5.4
dubbo消費側パラメータチェックをオンにするとvalidation=「true」
次の異常が報告されます.
[CurrentUser(userId=200887212, username=15210165164)] [http-nio-8837-exec-9] [WARN ] [com.alibaba.dubbo.validation.support.jvalidation.JValidator] warn 62 -  [DUBBO] net.wecash.postloan.core.service.PLRepaymentPlanService_GetRepaymentPlanByOrderIdParameter: frozen class (cannot edit), dubbo version: 2.5.4, current host: 10.41.42.56 java.lang.RuntimeException: net.wecash.postloan.core.service.PLRepaymentPlanService_GetRepaymentPlanByOrderIdParameter: frozen class (cannot edit)
 
この問題は、アップグレードされたdubboバージョンで解決されました.現在使用可能なdubboバージョン2.7.2
 
同問題リンク:https://github.com/apache/dubbo/issues/796

問題の説明


Spring Bootを使用してWeb appを構築し、Controllerでdubboコンシューマからサービス・エンドをリモートで呼び出し、getName(@NotNull String id)などのパラメータ検証を注釈で行います.呼び出し中に常にエラーが発生します.
java.lang.RuntimeException: XXXService_GetNameParameter: frozen class (cannot edit) at javassist.ClassPool.checkNotFrozen(ClassPool.java:617) ~[javassist-3.21.0-GA.jar:?] at javassist.ClassPool.makeClass(ClassPool.java:859) ~[javassist-3.21.0-GA.jar:?] at javassist.ClassPool.makeClass(ClassPool.java:836) ~[javassist-3.21.0-GA.jar:?] at com.alibaba.dubbo.validation.support.jvalidation.JValidator.getMethodParameterBean(JValidator.java:166)

もんだいぶんせき

  • 初歩的な判断はdubboバージョンとは関係なく、バグであるべきだ.エラーの原因は、動的に生成されたクラスを再検索しようとすると、実際にclassloaderの原因で見つからないはずです.即com.alibaba.dubbo.validation.support.jvalidation.JValidator 163行目:parameterClass = (Class>) Class.forName(parameterClassName, true, clazz.getClassLoader());ここでは、ClassNotFoundExceptionを再び投げ出すのではなくparameterClassを見つけることができるはずです.
  • ClassNotFoundExceptionが発生したのは、パラメータクラスXXXServices_が生成されたためです.GetNameParameterの場合、このパラメータのインタフェースに入力されたclassLoader(clazz.getClassLoader)ではなく、デフォルトのContext ClassLoaderが使用されます.
  • JValidator 202の動作を修正することを提案します:parameterClass = ctClass.toClass(clazz.getClassLoader(), null);インタフェースのclassLoaderに転送して、その一致性を保証します.

  • 古いバージョンdubboここのコード:
    parameterClass = ctClass.toClass();
    

    新しいバージョンdubboのコード:
    parameterClass = ctClass.toClass(clazz.getClassLoader(), (ProtectionDomain)null);