Работа декоратора не разрешена
У меня есть EJB-декоратор (так что этот декоратор CDI, если я правильно понимаю). Мне нужно сделать бизнес-логику в зависимости от роли вошедшего в систему пользователя. Итак, в EJB у меня есть SessionContext, но, поскольку это объект EJB, мне нужно искать его через JNDI.
InitialContext ic = new InitialContext();
SessionContext ctx = (SessionContext) ic.lookup("java:comp/EJBContext");
Это работает, но создает другую ошибку. Когда я пытаюсь позвонить ctx.isCallerInRole("MyRole");
Я получаю эту ошибку:
Caused by: java.lang.IllegalStateException: Operation not allowed
at com.sun.ejb.containers.SessionContextImpl.checkAccessToCallerSecurity(SessionContextImpl.java:205)
at com.sun.ejb.containers.EJBContextImpl.isCallerInRole(EJBContextImpl.java:447)
at com.example.decorators.MyDecorator.findAll(MyDecorator.java:46)
Что я ожидаю, так это то, что CDI не разрешено запрашивать SessionContext, находится ли зарегистрированный пользователь в указанной роли. Есть ли способ, как я могу решить это? Я бродил по Google уже несколько дней, но безуспешно.
Erates
Редактировать:
Вот что у меня на данный момент:
Интерфейс:
@Local
public interface StatelessSessionBeanLocal extends Serializable {
<T> Collection<T> findAll(Class<T> clazz);
boolean isCallerInRole(String role);
}
EJB:
@Stateless
public class StatelessSessionBean implements StatelessSessionBeanLocal {
@Resource
private SessionContext ctx;
@Override
public <T> Collection<T> findAll(Class<T> clazz){
...
}
@Override
public boolean isCallerInRole(String role){
return ctx.isCallerInRole(role);
}
}
Decorator:
@Decorator
public abstract class StatelessSessionBeanDecorator implements StatelessSessionBeanLocal {
@Inject
@Delegate
StatelessSessionBeanLocal sb;
@Override
public <T> Collection<T> findAll(Class<T> clazz){
if (sb.isCallerInRole("TestRole")){
return new ArrayList();
} else {
return sb.findAll(clazz);
}
}
}
Это дает мне NullPointerException в StatelessSessionBean.isCallerInRole, указывая на тот факт, что SessionContext не внедряется. (Я думаю, что из-за разницы между SessionContext (EJB) и Inject (CDI)) Обратите внимание, что EJB и Decorator находятся в разных пакетах в разных JAR-файлах в EAR.
2 ответа
Проблема была проблема Classloader.
ear
| - lib
| | - custom decorators.jar
| - custom ejb
| - ejb
| - war
Я использовал класс производителя, который создает EntityManager и SessionContext, используя @Produces
аннотации на них. Этот класс продюсера находился в банке "ejb". На декораторах я использовал provided
зависимость от "EJB", поэтому в тот момент он знал, где @Inject
придет из.
Но однажды во время выполнения пользовательский EJB найдет декоратор, потому что он находится в папке libs, но декоратор не может найти Produced
SessionContext
или же EntityManager
,
Теперь я переместил декораторы в "custom ejb", и все работает просто отлично.
SessionContext создается для каждого экземпляра компонента, при подходе поиска вы не получили привязку ctx к вашему экземпляру компонента, поэтому метод запрещен. Попробуйте использовать внедрение @Resource для получения контекста компонента.