我有一个应用程序,它通过Spring的RMI代理机制公开一个服务。存在这样一个问题:有时文件服务器上的“点”(它的JAR存储在上面)会导致调用将一个NoClassDefFoundError传播回调用方。
到目前为止还算公平。问题是,如果发生这种情况,我希望我的应用程序崩溃--也就是说,如果一个Error将被传播回调用方。
请注意,我在应用程序中已经有了一个UncaughtExceptionHandler,并且没有调用它(因为异常并不是真正的秘密)。
发布于 2010-08-27 12:41:39
如果通过RmiServiceExporter (或RemoteExporter的任何其他子类)公开RMI服务,则可以将注入任意拦截器放入调用堆栈中,每当调用RMI服务时,调用堆栈将被调用。
这些拦截器可以捕获任何抛出的NoClassDefFoundError,并调用System.exit()。
例如:
public class ExitInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
try {
return methodInvocation.proceed();
} catch (NoClassDefFoundError noClassDefFoundError) {
noClassDefFoundError.printStackTrace();
System.exit(1);
return null;
}
}
}和
<bean id="exporter" class="org.springframework.remoting.rmi.RmiServiceExporter">
<!-- existing properties -->
<property name="interceptors">
<bean class="com.x.ExitInterceptor"/>
<property>
</bean>发布于 2010-08-27 12:51:42
您可以做的是扩展[RmiServiceExporter][1]并处理invoke方法中的异常。这是可以做到的。
public class AutoFailRmiServiceExporter extends RmiProxyFactoryBean implements ApplicationContextAware {
private ApplicationContext ac;
@override
public Object invoke(RemoteInvocation invocation,
Object targetObject)
throws NoSuchMethodException,
IllegalAccessException,
InvocationTargetException {
try {
super.invoke(methodInvocation, target);
} catch (NoClassDefFoundError e) {
if {ac instanceof ConfigurableApplicationContext) {
(ConfigurableApplicationContext)ac).close();
else {
//log error
}
}
}
//application context setter
}然后,您将使用AutoFail版本的RmiServiceExporterwhen定义春季上下文中的rmi服务。
编辑:原始答案显示了一种在抛出异常时杀死客户端的方法。这是通过子类RmiProxyFactorty和重写doInvoke而不是RmiServiceExporter来实现的。
https://stackoverflow.com/questions/3584060
复制相似问题