воскресенье, 11 декабря 2011 г.

Неудачная попытка вызова метода @Stateless сервиса

Сегодня предлагаю рассмотреть RuntimeException при вызове метода сервиса:
javax.ejb.EJBException: Illegal non-business method access on no-interface view
Как ошибка получается?
Пусть есть крайне полезный сервис:
@Stateless
public class MyService {

    public String getAnswer() {
        return "42";
    }

    protected String getQuestion() {
        return "20 + 22 = ?";
    }
}
И также есть сервис (расположенный в том же пакете), обращающийся к первому в процессе выполнения какой-то своей логики:
@Stateless
public class MyClientService {

    @Inject
    private MyService myService;

    public String getPageHeader() {
        return myService.getQuestion() + myService.getAnswer();
    }
}
Чем нам так нравятся последние версии EJB?
Например, не нужно делать лишнюю и утомительную работу по написанию никому не нужных home-интерфейсов для сервисов. Объявляем сервис @Stateless, контейнер вставляет его куда надо с помощью @Inject/@EJB и вперёд. Смотрите сами: приведённый код достаточно ясен и краток. И даже компилируется... Вот только не выполняется, выбрасывая обозначенную выше ошибку.

Почему?
А вот не надо забывать, что механизмы работы EJB особенно не поменялись. Все эти позволения не писать лишнего - некоторый синтаксический сахар (хотя и очень классный). И на самом деле интерфейс для сервиса всё равно будет создан. И всё равно прокси-объект "над нашим сервисом" будет реализовывать этот автоматически созданный интерфейс. И войдут в него только public-методы. Другими словами, если грубо, то получится следующее:
public interface MyServiceIntf extends EJBHome {

  public String getAnswer();
}
Как видно, метода getQuestion() здесь нет. И именно этот интерфейс будет иметь переменная myService в MyClientService. А потому и происходит RuntimeException, когда мы пытаемся сделать вызов
myService.getAnswer()
При этом компилятор не показывает ошибок: с его точки зрения всё верно: вызов protected-методов внутри одного пакета разрешён.

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

Отправить комментарий