저는 Spring-boot에서 jsonrpc4j Client을 사용할 때 서버쪽에서 Exception을 throw하면 Client쪽에서는 제대로 된 Exception을 받지 못하고 UndeclaredThrowableException이 발생되며 해당 UndeclaredThrowableException의 getCause()을 통해 진짜 Exception을 받아와도 진짜 Exception Class으로 Casting하려고 하면 ClassCastException이 발생했습니다.
이에 대한 원인은 RPC을 호출하는 쪽(Spring-boot)의 ClassLoader는 RestartClassLoader인데 반에
jsonrpc4j에서 Exception을 resovle하는 쪽은 LauncherClassLoader이었기 때문이었습니다.
이를 해결하기 위해 Custom ExceptionResolver을 생성해서 사용하고 있습니다.
public <T> T getInterface(Class<T> interfaceClass, URL url) {
final ExceptionResolver exceptionResolver = new MyExceptionResolver(getClass().getClassLoader());
JsonRpcHttpClient jsonRpcHttpClient = new JsonRpcHttpClient(url);
jsonRpcHttpClient.setExceptionResolver(exceptionResolver);
return ProxyUtil.createClientProxy(getClass().getClassLoader(), interfaceClass, jsonRpcHttpClient);
}
public class MyExceptionResolver extends DefaultExceptionResolver {
private final ClassLoader classLoader;
public MyExceptionResolver(ClassLoader classLoader) {
super();
this.classLoader = classLoader;
}
@Override
protected Class<? extends Throwable> resolveThrowableClass(String typeName) throws ClassNotFoundException {
Class<?> clazz;
try {
clazz = Class.forName(typeName, true, this.classLoader);
if (!Throwable.class.isAssignableFrom(clazz)) {
//logger.warn("Type does not inherit from Throwable {}", clazz.getName());
} else {
return clazz.asSubclass(Throwable.class);
}
} catch(ClassNotFoundException e) {
//logger.warn("Unable to load Throwable class {}", typeName);
throw e;
} catch(Exception e) {
//logger.warn("Unable to load Throwable class {}", typeName);
}
return null;
}
}
'개발 및 운영 > Spring' 카테고리의 다른 글
sqlite-jdbc inmemory could not prepare statement 오류 (0) | 2021.10.19 |
---|---|
Spring-boot: Error during WebSocket handshake: Unexpected response code: 404 (0) | 2020.01.16 |
spring-cloud Zuul 사용시 매번 Set-Cookie하는 경우 (0) | 2018.12.26 |
springBootAdminVersion='2.0.4' 에서 reactor 오류날때 (0) | 2018.11.27 |
[Spring-boot] OAuth2 인증 과정 정리 (0) | 2018.10.22 |
댓글