리플렉션을 사용하여 외부 .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() 메서드를 호출 할 때까지는 아무 문제가 없습니다.
마지막으로 "com.hello.Request를 com.hello.Request로 캐스트 할 수 없습니다."라는 오류가 나타납니다. 이 문제를 해결할 수 있도록 도와주세요.
왜 :
실제 오류가
"URLClassLoader의 # 2 com.hello.Request가 URLClassLoader의 # 1 com.hello.Request 캐스트 할 수없는"이 제안입니다 반사가 필요 하신가요? – Stultuske
'com.hello.Request는 com.hello.Request'로 캐스팅 될 수 없습니다. 항상 두 개의 다른 클래스 로더를 통해 클래스를 두 번로드했음을 의미합니다. 이미 하드 코딩 된 참조로 인해 클래스가 정적으로로드되어 있고 구현을로드 할 때 두 번째 복사본을로드했습니다. 이 질문에 대한 답변은 게시되지 않았습니다. 오류가 발생한 이유를 설명 할 수는 있지만 해결 방법을 알려주는 정보가 충분하지 않으므로 (그리고 클래스 로더 전문 지식이 다소 오래되었습니다). –
예. 문제는 클래스 로더 twise를로드하여 이제 수정했습니다. 고맙습니다. – Tharanga