Reputation: 666
I have a decorator on an EJB (so this decorator is CDI if I understand it correct). I need do some business logic depending on the role the logged in user is. So in the EJB I have the SessionContext, but since this is an EJB object, I need to look it up via JNDI.
InitialContext ic = new InitialContext();
SessionContext ctx = (SessionContext) ic.lookup("java:comp/EJBContext");
This works, but creates another error. When I try to call ctx.isCallerInRole("MyRole");
I get this error:
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)
What I expect is happening is that a CDI is not allowed to ask the SessionContext if the logged in user is in the specified role. Is there a way how I can solve this? I've been roaming Google for a few days now, without success.
Erates
Edit:
This is what I have at the moment:
Interface:
@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);
}
}
}
This gives me a NullPointerException at StatelessSessionBean.isCallerInRole pointing to the fact that the SessionContext is not injected. (I think because of the difference between SessionContext (EJB) and Inject (CDI)) Note, the EJB and Decorator are in different packages in different JARs in the EAR.
Upvotes: 0
Views: 218
Reputation: 666
Problem was a Classloader issue.
ear
| - lib
| | - custom decorators.jar
| - custom ejb
| - ejb
| - war
I used a producer class that creates the EntityManager and SessionContext using the @Produces
annotations on them. This producer class was in the "ejb" jar. On the decorators I used a provided
dependency to the "ejb" so at that point, it knew where the @Inject
would come from.
But once in runtime, the custom EJB would find the decorator because it is in the libs folder, but the decorator could not find the Produced
SessionContext
or EntityManager
.
Now I've moved the decorators inside the "custom ejb" and all works just fine and dandy.
Upvotes: 1
Reputation: 880
The SessionContext is created for each bean instance, with the lookup approach you didn't obtain the ctx bind to your bean instance so the method is not allowed. Try using @Resource injection to obtain the bean context.
Upvotes: 0