у меня есть EJB проект со следующими модулями:Передача @ApplicationException через несколько модулей EJB
- модуль отдыха, который обрабатывает вызовы API
- модуль API, который предоставляет интерфейс для ядра
- основной модуль, который содержит фактическую бизнес-логику
В случае, если что-то пойдет не так, и клиент должен получить сообщение об ошибке, я использую пользовательские исключения, которые являются подклассами Web ApplicationException и уже содержат соответствующий ответ.
@ApplicationException(rollback = true)
public class InvalidParameterException extends WebApplicationException { }
Эти исключения никогда не должны быть уловлены. При аннотации к нему как ApplicationException он не попадает в журнал журнала Glassfish. Пока все работает нормально.
Теперь у меня есть ситуация, когда основной модуль включает в себя другой модуль EJB, который включает в себя его собственные подклассы WebApplicationExceptions, которые выглядят похожими на вышеупомянутые. Это исключение передается в ядро, как должно. Однако, когда это исключение передается остальному модулю, оно обернуто в javax.ejb.EJBTransactionRolledbackException
, что заставляет журнал сервера Glassfish регистрировать все эти исключения, чего я бы хотел избежать.
Итак, аннотация @ApplicationException работает только тогда, когда исключение передается от модуля ejb к основному модулю, однако, как только он передается дополнительному модулю, аннотация перестает действовать.
Есть ли хороший способ передать исключение как исключение приложения через несколько модулей? Я знаю, что я мог поймать Exception и снова восстановить его как ApplicationException, однако это сильно раздует код и не будет очень хорошим решением. Есть ли способ лучше?
Edit: Некоторые примеры кода модуля
отдых:
@Path("/someservice")
@Stateless
public class SomeResource {
@EJB private SomeService someService;
@GET
@Produces("application/json")
public Response someGetMethod() {
this.someService.someMethod();
return Response.ok().build();
}
}
апи модуль:
public Interface SomeService {
public void someMethod();
}
модуль ядра:
@Stateless
public Class SomeServiceImpl implements SomeService {
@EJB private ExternalEJB externalEJB;
public void someMethod() {
externalEJB.externalMethod();
}
}
Внешний модуль EJB. В pom.xml (модуль ядра) с помощью <type>ejb</type>
@Stateless
public class ExternalEJB {
public void externalMethod() {
throw new ExternalApplicationException();
}
}
Исключения из внешнего модуля:
@ApplicationException
public class ExternalApplicationException extends WebApplicationException {
private static final long serialVersionUID = 1L;
public ExternalApplicationException() {
super(Response.serverError().build());
}
}
Мы часто используем '@ ApplicationException', и они корректно всплывают через множественные вызовы EJB как исключенные. Тем не менее, я вижу, что ваше аннотирование имеет «rollback = true» - не значит ли это 'EJBTransactionRolledBackException' именно то, что вы хотели? –
Это потому, что модуль отдыха находится вне контейнера EJB.Вообще говоря, и, к сожалению, вы не можете беспрепятственно подключать вызовы EJB и REST без обработки подклассов EJBException, которые REST-модуль (как клиент EJB) обречен обрабатывать, когда дело касается транзакций и безопасности. – Osw
@AlexanderLanger Я только что проверил это. Если я удалю «rollback = true» (по умолчанию - false), поведение немного не изменится. –