Как я могу получить Spring для фатального выхода если ошибка распространяется из удаленного вызова

У меня есть приложение, которое предоставляет сервис через механизм Spring RMI proxy , Существует проблема, из-за которой иногда «сообщение» на файловом сервере, на котором хранятся его JAR-файлы, заставляет вызов передавать NoClassDefFoundError обратно вызывающей стороне.

Пока что это достаточно справедливо. Дело в том, что я хотел бы, чтобы мое приложение просто аварийно завершало работу, если это происходит, то есть если ошибка будет передана обратно вызывающей стороне.

Обратите внимание, что у меня уже есть UncaughtExceptionHandler в приложении, и это не вызывается (потому что исключение не является на самом деле необработанным )

1
задан oxbow_lakes 27 August 2010 в 12:25
поделиться

2 ответа

Если вы предоставляете службу RMI через RmiServiceExporter (или любой другой подкласс RemoteExporter), то вы можете вводить произвольные перехватчики в стек вызовов, которые будут вызываться всякий раз, когда вызывается служба 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>
1
ответ дан 2 September 2019 в 21:46
поделиться

Что вы можете сделать, так это расширить [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 RmiServiceExporter при определении службы rmi в контексте весны.

РЕДАКТИРОВАТЬ: Исходный ответ показал способ убить клиента при возникновении исключения. Это делается путем создания подкласса RmiProxyFactorty и переопределения doInvoke вместо RmiServiceExporter.

1
ответ дан 2 September 2019 в 21:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: