Какие исключения RMI указывают на потерянные соединения - PullRequest
1 голос
/ 27 июля 2011

Я использую следующий бит кода для уведомления удаленных (RMI) слушателей событий об изменении.

        // notify remote listeners of this change
        ThreadPool.execute(new Runnable() { @Override public void run() {

            List<Integer> removal = new ArrayList<Integer>();

            listeners.getReadLock().lock();
            try {

                for (Entry<Integer, RemoteDataServerListener> e : listeners.entrySet()) {

                    try {
                        e.getValue().creditsChanged(player.getId(), player.getCredits());
                    } catch (RemoteException er) {

                        log.warn("Error in remote listener", er);

                        // this listener is gone
                        if (er instanceof NoSuchObjectException) {
                            log.info("Removing the listener");
                            removal.add(e.getKey());
                        }

                    }

                }

            } finally {
                listeners.getReadLock().unlock();
            }

            // listeners that are gone don't need future events
            listeners.removeAll(removal);


        }});

Как видите, я удаляю слушателя, когда он выдает NoSuchObjectException, но это, вероятно, не единственное исключение, которое может быть выдано. Существует ли полный список исключений RMI, которые указывают, что удаленный объект (или весь сервер) потерян / отключен?

Ответы [ 3 ]

1 голос
/ 27 июля 2011

AFAIK, если вы можете гарантировать, что ваше приложение RMI всегда отбрасывает пользовательские или пользовательские исключения независимо от того, что идет не так на сервере, перехват RemoteException и удаление прослушивателя должны быть хорошими.Например,

public Object doSomething() throws RemoteException {
    Object o;
    try {
        // application processing
    } catch(final Throwable t) {
        throw new CustomException(t);
    }
    return o;
}
0 голосов
/ 28 июля 2011

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

В некотором смысле ConnectIOException такжеуказывает на это, но это происходит только при попытке восстановить соединение с пулом клиента в начале вызова.

Более интересным и еще более сложным вопросом является то, какие исключения сохраняют идемпотентность, если вы повторите попытку после них, и этоочень сложный вопрос для ответа.Я посвятил этому около 20 страниц своей книги по RMI и сомневаюсь, что рассмотрел все возможные варианты.

NoSuchObjectException указывает на то, что удаленного объекта, который экспортировал заглушку, к которой вы обращаетесь, больше нет, т.е. он не был экспортирован изего JVM.

Само по себе RemoteException может означать практически что угодно, особенно если вы допустили ошибку, из-за которой ваши собственные исключения из приложения расширяли его.Не делай этого.И на практике вам не нужно просто перехватывать RemoteException, вы должны перехватывать все возможные исключения RMI по отдельности с помощью перехватчика RemoteException для всех ловушек внизу, поскольку существуют разные стратегии восстановления для разных исключений.Если вы просто не хотите отказываться от какой-либо удаленной ошибки вообще.

0 голосов
/ 28 июля 2011

С http://download.oracle.com/javase/6/docs/api/java/rmi/RemoteException.html похоже, что я могу обработать все исключения RemoteException таким образом, кроме:

  • UnmarshalException
  • UnexpectedException
  • ServerError
...