Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Valid CDI scopes for Session (EJB) Beans

DZone's Guide to

Valid CDI scopes for Session (EJB) Beans

· Java Zone ·
Free Resource

Get the Edge with a Professional Java IDE. 30-day free trial.

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 !

  • Stateful EJBs 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)

Get the Java IDE that understands code & makes developing enjoyable. Level up your code with IntelliJ IDEA. Download the free trial.

Topics:

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}