Valid CDI scopes for Session (EJB) Beans

Datetime:2016-08-23 01:59:29          Topic: EJB           Share

CDI  enriches the  EJB specification (Session beans to be specific) by providing contextual life cycle management. Session beans are not ‘contextual’ instances in general.

If you are comfortable with CDI in general, the idea of ‘being contextual’ should be pretty clear.

Here are the valid permutations and combinations of EJB session beans and corresponding CDI scopes (Application, Session or Request)

  • Stateless  beans can only belong to the @Dependent scope i.e. you can either choose to use the @Dependent pseudo-scope explicitly or just flow with the @Stateless annotation in which case the CDI container will pretty much use @Dependent by default (convention). 
    //This is valid
    @Stateless
    @Dependent
    public class EJB1 {
    	@PostConstruct
    	public void init(){
    		System.out.println(EJB1.class.getName() + " constructed successfully on "+ new Date().toString());
    	}
    }
    //This is NOT valid
    @Stateless
    @RequestScoped
    public class EJB1 {
    	@PostConstruct
    	public void init(){
    		System.out.println(EJB1.class.getName() + " constructed successfully on "+ new Date().toString());
    	}
    }
    //CDI container will complain
    Caused by: org.jboss.weld.exceptions.DefinitionException: WELD-000082: Scope interface javax.enterprise.context.RequestScoped is not allowed on stateless enterprise beans for class cdi.ejb.integration.EJB1.  Only @Dependent is allowed on stateless session beans.
    	at org.jboss.weld.bean.SessionBean.checkScopeAllowed(SessionBean.java:122)
    	at org.jboss.weld.bean.SessionBean.internalInitialize(SessionBean.java:101)
    	at org.jboss.weld.bean.RIBean.initialize(RIBean.java:66)
    	at org.jboss.weld.bootstrap.ConcurrentBeanDeployer$5.doWork(ConcurrentBeanDeployer.java:118)
    	at org.jboss.weld.bootstrap.ConcurrentBeanDeployer$5.doWork(ConcurrentBeanDeployer.java:115)
    	at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:59)
    	at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:52)
    	at java.util.concurrent.FutureTask.run(FutureTask.java:266) [rt.jar:1.8.0_25]
    	... 3 more
    

    The CDI container will not let you get away with any other annotation and the end result would be a deployment failure

  • With  Singleton  beans, @ApplicationScoped is the only valid CDI scope (@Dependent is the default in case you do not use any other explicit CDI scope)
    //This is legal
    @Singleton
    @Startup
    @ApplicationScoped
    public class Singleton1 {
    	@PostConstruct
    	public void init(){
    		System.out.println(Singleton1.class.getName() + " constructed successfully on "+ new Date().toString());
    	}
    }
    //CDI container will not be happy seeing this
    @Singleton
    @Startup
    @RequestScoped
    public class Singleton1 {
    	@PostConstruct
    	public void init(){
    		System.out.println(Singleton1.class.getName() + " constructed successfully on "+ new Date().toString());
    	}
    }
    Caused by: org.jboss.weld.exceptions.DefinitionException: WELD-000083: Scope interface javax.enterprise.context.RequestScoped is not allowed on singleton enterprise beans for class cdi.ejb.integration.Singleton1.  Only @Dependent and @ApplicationScoped is allowed on singleton session beans.
    	at org.jboss.weld.bean.SessionBean.checkScopeAllowed(SessionBean.java:125)
    	at org.jboss.weld.bean.SessionBean.internalInitialize(SessionBean.java:101)
    	at org.jboss.weld.bean.RIBean.initialize(RIBean.java:66)
    	at org.jboss.weld.bootstrap.ConcurrentBeanDeployer$5.doWork(ConcurrentBeanDeployer.java:118)
    	at org.jboss.weld.bootstrap.ConcurrentBeanDeployer$5.doWork(ConcurrentBeanDeployer.java:115)
    	at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:59)
    	at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:52)
    	at java.util.concurrent.FutureTask.run(FutureTask.java:266) [rt.jar:1.8.0_25]
    	... 3 more
    

    Again, any other scope annotation and the CDI god will crush your WAR/EAR !

  • StatefulEJBs can have any scope – no restrictions whatsoever! (although I do not see too much value in using @ApplicationScoped for Stateful beans – but that’s just me! feel free to chime in case you think otherwise)

Published at DZone with permission ofAbhishek Gupta, author and DZone MVB. ( source )

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)





About List