後方互換性テストのために、以前のバージョンからコードの一部をロードするための独自のクラスローダーを作成しています。(古いカスタムクラスからの)カスタムオブジェクトを取得した後、リフレクションを使用してそのAPIを呼び出しています。ただし、そのようなAPIメソッドにカスタム引数がある場合(Javaライブラリの一部ではない場合)、たとえば次のようになります。
public void MyMethod(MyObj a) {}
リフレクションを使用してこのメソッドを呼び出すと、次のようになります。
java.lang.IllegalArgumentException:引数タイプの不一致
メソッドがカスタムクラスローダーからMyObjを取得することを期待しているのに、デフォルトのクラスローダーからMyObjを渡しているためです。
メソッドを呼び出すために使用しているコード(エージェントがカスタムクラスローダーによってロードされ、エージェントのapiメソッドへの引数がデフォルトのクラスローダーによってロードされたテストクラスから到着した場合)
private Object invoke(Object... args) {
try {
final String methodName = getMethodName();
final Class<?>[] methodArgs = getMethodArgs(methodName);
return agent.getClass().getMethod(methodName, methodArgs).invoke(agent, args);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
return null;
}
private Class<?>[] getMethodArgs(String methodName) {
final Method[] declaredMethods = agent.getClass().getDeclaredMethods();
for (Method method : declaredMethods) {
if (method.getName().equals(methodName)) {
return method.getParameterTypes();
}
}
return new Class<?>[0];
}
private String getMethodName() {
StackTraceElement[] stacktrace = Thread.currentThread().getStackTrace();
StackTraceElement e = stacktrace[3];
return e.getMethodName();
}
この問題を回避するにはどうすればよいですか?(myCustomObjectは共有モジュールに存在するインターフェースを実装していないため、メソッドに共通インターフェースを渡すことができません。また、古いjarがそれを認識しないため、今は追加できません)