Resinによるjava.lang.IllegalArgumentException:object is not an instance of declaring class(反射で使用)思考


文書ディレクトリ
  • バックグラウンド
  • 原因
  • 解決策
  • 背景
    Java agentでResinをキャプチャするいくつかの方法は、invokeのときにエラーが発生します.
    java.lang.IllegalArgumentException: object is not an instance of declaring class
    

    この問題が発生したのはclazzで見つけたmethodが、本当のinvokeの時に伝わるclazzが違うからです.
    の原因となる
    コード再構築後にプラグインにMethodがキャッシュされたため
    provite Static Method mmm = null
    if(method == null){
    	  methodFromCache = clazz.getMethod("methodname", parameterTypes);
    }
    method.invoke(clazz,parameterTypes)
    //     methodname request
    

    ここのclazzはrequestです
    Debugによりresinが起動したばかりのときに何らかのメカニズム(位置)でrequest,com.xxxx.xxxxxx.httpreqestが送信され、クライアントで再アクセスし、request,com.xxxxx.xxx.dispetchrequestが再送信されることが分かった.
    初めてrequestをキャッシュし(com.xxxx.xxxxxx.htpreqest)、2回目に直接取りましたが、2回目のclazzがcom.xxxx.xxx.dispetchrequestになったので、上記のエラーが発生しました.
    解決策
    mapキャッシュメソッドにより、mapのkeyはclassname+method nameを唯一のメソッドを決定する識別子とし、valueはclassnameである
    	private static Map<String, Method> methodMap = new HashMap<String, Method>();
    	String methodId = className + methodName;
    	Method method = methodMap.get(methodId);
    if(method == null){
    	  methodFromCache = clazz.getMethod("methodname", parameterTypes);
    }
    method.invoke(clazz,parameterTypes)
    

    これによりメソッド名がclassname+methodnameであることが保証され、上記の問題は発生しません.