リフレクションを使用して外部の.jar内のメソッドを呼び出す必要があります。リフレクションを使用して外部jar内のメソッドを呼び出す方法
これは、jarファイル内のサンプルコードです。
public class HelloFunction implements Runnable, RequestHandler<Request> {
@Override
public void handle(final Request request) {
System.out.println("handle : " + request);
}
@Override
public void run() {
System.out.println("run......");
}
}
私は別のJavaプログラムにこのjarをロードし、HelloFunction.handle()メソッドを呼び出そうとしました。これはその部分のサンプルコードです。
public class App {
public static void main(String[] args) {
test();
}
public static void test(){
try{
final Class<?> functionClass = getClassFromFunctionJar("com.hello.HelloFunction");
final Object functionClassObject = functionClass.newInstance();
if(functionClassObject instanceof RequestHandler){
@SuppressWarnings("unchecked")
final RequestHandler<Object> handler = RequestHandler.class.cast(functionClassObject);
final Object inputObject = getRequestClass(functionClass).newInstance();
handler.handle(inputObject);
}
}catch(final Exception e){
System.err.println(e.getMessage());
}
}
public static Class<?> getRequestClass(final Class<?> cls) throws FunctionInvokerException{
try{
final Type[] types = cls.getGenericInterfaces();
for(Type type : types){
//check RequestHandler
if(type.getTypeName().contains(RequestHandler.class.getName())){
final ParameterizedType parameterizedType = (ParameterizedType) type;
// [0]=> Request Type
final String inputClassName = parameterizedType.getActualTypeArguments()[0].getTypeName();
return getClassFromFunctionJar(inputClassName);
}
}
throw new Exception("UNABLE_TO_FIND_REQUEST_TYPE");
}catch(final Exception e){
throw new FunctionInvokerException(e);
}
}
private static Class<?> getClassFromFunctionJar(final String className) throws ClassNotFoundException, MalformedURLException{
final ClassLoader classLoader = URLClassLoader.newInstance(new URL[]{new URL("file:" + "/jar-location/hello.jar")}, App.class.getClassLoader());
return Class.forName(className, true, classLoader);
}
}
ここでは、getClassFromFunctionJar()メソッドを使用して、クラスからクラスをロードしています。また、getRequestClass()メソッドは、HelloFunction.handle()メソッドの入力パラメータのクラス型を検索するために使用されます。 handle()メソッドを呼び出すまでは問題ありません。
最後に、「com.hello.Requestをcom.hello.Requestにキャストできません」というエラーが表示されました。この問題を解決するために私を助けてください。
理由を行います
実際のエラーが
"のURLClassLoader#2 com.hello.RequestがURLClassLoaderの#1 com.hello.Requestにキャストすることはできません" と、これはお勧めですあなたは反射が必要ですか? – Stultuske
'com.hello.Requestはcom.hello.Request'にキャストできません。常に、2つの異なるクラスローダーを通してクラスを2回ロードしたことを意味します。既にハードコードされた参照のためにクラスが静的にロードされていて、実装をロードしたときに2番目のコピーがロードされています。これは答えとして投稿されていないのですが、エラーが出ている理由を教えてもらえますが、修正方法を教える情報が不足しています(クラスローダーの専門知識が古くなっています)。 –
はい。問題は、クラスローダーtwiseをロードして、今修正しました。ありがとうございました。 – Tharanga