Как использовать пользовательские исключения в сессионных компонентах? - PullRequest
2 голосов
/ 07 марта 2011

EJB 3.1 Session Bean:

import javax.ejb.*;
public class FooException extends EJBException {
}
@Stateless @Local
public class Foo {
  public void bar() throws FooException {
    if (/* something wrong */) {
      throw new FooException();
    }
  }
}

Теперь тест:

import org.junit.*;
public class FooTest {
  @Test(expected = FooException.class)
  public void testException() {
    new InitialContext().lookup("Foo").bar();
  }
}

Проблема в том, что EJBException перехватывается в тесте, а не FooException. Похоже, контейнер EJB теряет информацию о моем типе исключений и выдает базовый тип (EJBException). Что здесь не так? (это OpenEJB 3.1)

1 Ответ

6 голосов
/ 07 марта 2011

Прежде всего, вам не нужно использовать аннотацию @Local здесь.Это обозначает интерфейс как локальный интерфейс или при использовании в bean-компоненте (в вашем случае) может использоваться для указания на локальный интерфейс (через атрибут value).Ни один из случаев не применим здесь.Ваш код, как указано, также не будет компилироваться.lookup ("Foo") вернет объект, который должен быть приведен.

В любом случае, проблема EJB-контейнера не теряет никакой информации, но оборачивает ваше исключение в EJBException.Это потому, что FooException в конечном счете наследуется от RuntimeException.Любое такое исключение рассматривается контейнером как nonapplication exception, и для тех, которые спецификация EJB определяет, что они должны быть заключены в оболочку.

В вашей ситуации вы уже вышли из EJBException, поэтому кажется, что это угловой случай,JBoss AS 6, например, в этой ситуации не выполняет дополнительного переноса, но, очевидно, OpenEJB делает.

Вы можете решить эту проблему, либо не допустив FooException наследовать от EJBException, либо перехватив исключение в своем тесте,распаковывая его и перебрасывая распакованное исключение.

Поскольку ваш метод bar объявляет, что он выдает FooException, я предполагаю, что вы не понимали, что EJBException является RuntimeException и, следовательно, исключением из приложения.Почему вы позволили FooException наследоваться от EJBException?Считаете ли вы, что это каким-то образом требуется, или для этого требуется сервер специального назначения?

(в качестве дополнительной подсказки убедитесь, что вы понимаете разницу между исключениями приложений и неаппликаций в отношении отката любой транзакции и уничтоженияобъединенный боб)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...