不允许装饰器操作

时间:2015-03-05 14:13:20

标签: java java-ee glassfish ejb cdi

我在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。我有办法解决这个问题吗?我已经在谷歌漫游了几天,但没有成功。

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
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);
        }
    }
}

这在StatelessSessionBean.isCallerInRole中给出了一个NullPointerException,指向未注入SessionContext的事实。 (我认为由于SessionContext(EJB)和Inject(CDI)之间的区别)注意,EJB和Decorator在EAR中的不同JAR中的不同包中。

2 个答案:

答案 0 :(得分:0)

为每个bean实例创建SessionContext,使用查找方法没有获得对bean实例的ctx绑定,因此不允许使用该方法。 尝试使用@Resource注入来获取bean上下文。

答案 1 :(得分:0)

问题是类加载器问题。

ear
| - lib
|    | - custom decorators.jar
| - custom ejb
| - ejb
| - war

我使用了一个生成器类,它使用@Produces注释创建EntityManager和SessionContext。这个制片人课程在&#34; ejb&#34;罐。在装饰器上,我使用provided依赖于&#34; ejb&#34;所以在这一点上,它知道了@Inject的来源。

但是一旦在运行时,自定义EJB会找到装饰器,因为它位于libs文件夹中,但装饰者找不到Produced SessionContextEntityManager

现在我已经将装饰器移到了#34; custom ejb&#34;所有的作品都很好,花花公子。