Клиент получает необъявленное проверенное исключение, но исключение объявляется перехваченным

#java #rmi

#java #rmi

Вопрос:

В моем интерфейсе сервера RMI объявляется метод foo(), который объявляется для вызова RemoteException и Exception следующим образом:

 public interface Node extends RemoteService {

   public void foo() throws RemoteException, Exception;
}
  

Реализация сервера:

 public class NodeImpl extends UnicastRemoteObject implements Node {

    public void foo() throws RemoteException, Exception {
      // Implementation - calls other stuff...
    }
}
  

Мой клиент вызывает foo на сервере:

 try {
  node.foo();
}
catch (Exception e) {
   System.err.print("Got exception from foo() of type "   e.getClass().getName());
   System.err.println("Exception: "   e.getMessage());
}
  

Теперь, когда я запускаю клиент, я получаю:

Получено исключение из foo() типа java.rmi.Исключение UnexpectedException: необъявленное проверенное исключение; вложенное исключение: java.io.InterruptedIOException: время ожидания операции истекло

Java doc говорит об этом о java.rmi.UnexpectedException:

Генерируется непредвиденное исключение, если клиент удаленного вызова метода получает в результате вызова проверяемое исключение, которое не входит в число проверяемых типов исключений, объявленных в предложении throws метода в удаленном интерфейсе.

Но мой удаленный интерфейс указывает, что foo() выдает исключение, а java.io.InterruptedIOException является своего рода исключением. Итак, почему мой клиент получает UnexpectedException?

Спасибо, Том

Комментарии:

1. Ваш клиент имеет caught исключение и выполняет объявленные вами инструкции печати, в чем проблема?

2. Старайтесь избегать генерирования общих исключений, таких как Exception . Было бы лучше перехватывать и повторно генерировать эти отдельные исключения как исключение, зависящее от домена, например ServerException .

3. Пожалуйста, опубликуйте полную трассировку стека. Вы уверены, что у вас есть текущая версия кода, развернутая как на сервере, так и на клиенте? и вы перезапустили реестр с момента последнего изменения кода?

4. Да, пожалуйста, опубликуйте полную трассировку стека. Принятый ответ, похоже, не ответил на вопрос.

5. К сожалению, полная трассировка стека — это то, что я включил в исходное сообщение. Цель использует старую версию IBM J9 JVM, совместимую с JDK1.3.

Ответ №1:

Но мой удаленный интерфейс указывает, что foo() выдает исключение, а java.io.InterruptedIOException является своего рода исключением. Итак, почему мой клиент получает UnexpectedException

Потому что

 throws Exception 
  

означает, что метод может генерировать исключение типа класса Exception или любого типа его подкласса. InterruptedIOException является подклассом Exception , поэтому вполне допустимо, чтобы метод выдавал InterruptedIOException , когда в подписи упоминается его супертип Exception .

Комментарии:

1. Спасибо Juned — Так означает ли UnexpectedException, что необъявленное проверенное исключение попадает дальше в стек сервера?

2. @user604713 Из вашей трассировки стека кажется, что java.io.InterruptedIOException действительно происходит.

3. Вы не объяснили, почему расширяющееся исключение Exception является «неожиданным».

4. @EJP еще не упоминается в вопросе и не очень понятен: Java doc говорит об этом о java.rmi.UnexpectedException: Вызывается UnexpectedException, если клиент удаленного вызова метода получает в результате вызова проверенное исключение, которого нет среди проверенных типов исключений, объявленных впредложение throws метода в удаленном интерфейсе.

5.Я знаю, что это говорит. Вопрос в том, почему эта ошибка? Exception объявляется в throws предложении метода в удаленном интерфейсе: public void foo() throws RemoteException, Exception;

Ответ №2:

Я сильно подозреваю, что вы не используете одну и ту же версию кода на клиенте и сервере. Выполните чистую сборку и повторно разверните все. Похоже, существует несогласие между удаленными интерфейсами на сервере и клиенте.

Комментарии:

1. Это может быть так — я все перекомпилировал. Наблюдаемое исключение в любом случае встречается редко, поэтому его нелегко воспроизвести. Я буду следить за этим.