我想通过使用反射来调用外部.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......");
}
}
然后我将这个jar加载到一个单独的java程序中,并尝试调用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()方法从jar加载Class。并且getRequestClass()方法用于查找HelloFunction.handle()方法的输入参数的类类型。 一切都很好,直到调用handle()方法。
最后我得到一个错误,上面写着&#34; com.hello.Request无法转换为com.hello.Request&#34;。你能帮我解决这个问题。
答案 0 :(得分:1)
由不同类加载器加载的相同类定义被JVM视为两个不同的类。
您的代码“URLClassLoader.newInstance”,同时获取不同的类加载器
第一个(处理程序#参数)是:URLClassLoader#1&amp; com.hello.Request
第二个(inputObject)是:URLClassLoader#2&amp; com.hello.Request
“com.hello.Request无法转换为com.hello.Request”。
实际错误是
“URLClassLoader#2 com.hello.Request无法强制转换为URLClassLoader#1 com.hello.Request”
并建议:
private static final ClassLoader classLoader = URLClassLoader.newInstance(new URL[]{new URL("file:" + "/jar-location/hello.jar")}, App.class.getClassLoader());
private static Class<?> getClassFromFunctionJar(final String className) throws ClassNotFoundException, MalformedURLException{
return Class.forName(className, true, classLoader);
}