JEE7: Do EJB and CDI beans support container-managed transactions? - java

Java EE7 consists of a bunch of "bean" definitions:
Managed Beans 1.0 (JSR-316 / JSR-250)
Dependency Injection for Java 1.0 (JSR-330)
CDI 1.1 (JSR-346)
JSF Managed Beans 2.2 (JSR-344)
EJB 3.2 (JSR-345)
In order to get rid of the chaos in my mind, I studies several articles of "when to use which bean type". One of the pros for EJB seems to be that they alone support declarative container-managed transactions (the famous transaction annotations). I'm not sure, though, if this is correct. Can anyone approve this?
Meanwhile, I came up with a simple demo application to check if this was actually true. I just defined a CDI bean (not an EJB - it has no class level annotations) as follows, based on this snippet:
public class CdiBean {
#Resource
TransactionSynchronizationRegistry tsr;
#Transactional(Transactional.TxType.REQUIRED)
public boolean isTransactional() {
return tsr.getTransactionStatus() == Status.STATUS_ACTIVE;
}
}
Now, the outcome on GlassFish 4.0 is that this method actually returns true, which, according to my inquiries, is not working as expected. I did expect the container to ignore the #Transactional annotation on a CDI bean method, or to even throw an exception. I use a freshly-installed GlassFish 4 server, so there are no interferences.
So my question is really:
Which bean types do actually support container-managed transactions?
Just for the sake of curiosity, how could I test it with a simple demo application if the code above is wrong?
(BTW: Someone described a similar problem here, but its solution does not apply to my case.

Until Java EE 7 only EJB was transactional and the #Transactional annotation didn't exist.
Since Java EE 7 and JTA 1.2 you can use transactional interceptor in CDI with #Transactional annotation.
To answer your question about the best type of bean to use, the answer is CDI by default.
CDI beans are lighter than EJB and support a lot of feature (including being an EJB) and is activated by default (when you add beans.xml file to your app).
Since Java EE 6 #Inject supersede #EJB. Even if you use remote EJBs (feature not existing in CDI) the best practice suggest that you #EJB once to inject remote EJB and a CDI producer to expose it as a CDI bean
public class Resources {
#EJB
#Produces
MyRemoteEJB ejb;
}
The same is suggested for Java EE resources
public class Resources2 {
#PersistenceContext
#Produces
EntityManager em;
}
These producers will be used later
public class MyBean {
#Inject
MyRemoteEJB bean;
#Inject
EntityManager em;
}
EJB continue to make sense for certain services they include like JMS or Asynchronous treatment, but you'll use them as CDI bean.

The javadoc of Transactional says:
The javax.transaction.Transactional annotation provides the application the ability to declaratively control transaction boundaries on CDI managed beans, as well as classes defined as managed beans by the Java EE specification, at both the class and method level where method level annotations override those at the class level.
So, your assumptions are wrong. EJBs, until Java EE 6, were the only kinds of components to support declarative transactions. The Transactional annotation has precisely been introduced in Java EE 7 to make non-EJB, managed CDI beans transactional.

Related

Why is my list empty in my jsf managed bean [duplicate]

I feel there is a little mess in the Java EE 6 spec. There are several sets of annotations.
We have javax.ejb annotations like #Stateful and #Stateless for creating EJBs.
There is also a #javax.annotation.ManagedBean to create a managed bean.
There are annotations in javax.enterprise.context like #SessionScoped and #RequestScoped.
What is more there are also #ManagedBean and #SessionScoped/#RequestScoped annotations in javax.faces.bean package.
And to make things event more complicated there is a package javax.inject with #Named annotation.
Can someone please describe how they are related one to another?
Where can I use #EJB, #Inject or #ManagedPropery to inject other beans?
First of all let me do some clarifications:
Managed bean definition : generally a managed bean is an object that its life cycle (construction, destruction, etc) is managed by a container.
In Java ee we have many containers that manage life cycle of their objects, like JSF container, EJB container, CDI container, Servlet container, etc.
All of these containers work kind of independent, they boot in application server initialization and scan classes of all artifacts including jar, ejb-jar, war and ear files in deployment time and gather and store some metadata about them, then when you need an object of a class at runtime they will give you instances of those classes and after finishing the job, they will destroy them.
So we can say that we have:
JSF managed beans
CDI managed beans
EJB managed beans
And even Servlets are managed beans because they are instantiated and destroyed by a container, which is a servlet container.
So when you see the Managed Bean word, you should ask about the context or type of it.(JSF, CDI, EJB, etc.)
Then you might ask why we have many of these containers: AFAIK, Java EE guys wanted to have a dependency injection framework, but they could not gather all requirements in one specification because they could not predict the future requirements and they made EJB 1.0 and then 2.0 and then 3.0 and now 3.1 but EJB's target was for just some requirements (transaction, distributed component model, etc).
At the same time (in parallel) they realized that they need to support JSF too, then they made JSF managed beans and another container for JSF beans and they considered it a mature DI container, but still it was not complete and mature container.
After that Gavin King and some other nice guys ;) made CDI which is the most mature DI container I've seen. CDI (inspired by Seam2, Guice and Spring) was made to fill the gap between JSF and EJB and lots of other useful stuff like pojo injection, producer methods, interceptors, decorators, integration SPI, very flexible, etc. and it can even do what EJB and JSF managed beans are doing then we can have just one mature and powerful DI container. But for some backward compatibility and political reasons Java EE guys want to keep them!!!
Here you can find the difference and use cases for each of these types:
JSF Managed Beans, CDI Beans and EJBs
JSF was initially developed with its own managed bean and dependency injection mechanism which was enhanced for JSF 2.0 to include annotation based beans. When CDI was released with Java EE 6, it was regarded as the managed bean framework for that platform and of course, EJBs outdated them all having been around for well over a decade.
The problem of course is knowing which one to use and when use them.
Let’s start with the simplest, JSF Managed beans.
JSF Managed Beans
In short, don’t use them if you are developing for Java EE 6 and using CDI. They provide a simple mechanism for dependency injection and defining backing beans for web pages, but they are far less powerful than CDI beans.
They can be defined using the #javax.faces.bean.ManagedBean annotation which takes an optional name parameter. This name can be used to reference the bean from JSF pages.
Scope can be applied to the bean using one of the different scopes defined in the javax.faces.bean package which include the request, session, application, view and custom scopes.
#ManagedBean(name="someBean")
#RequestScoped
public class SomeBean {
....
....
}
JSF beans cannot be mixed with other kinds of beans without some kind of manual coding.
CDI Beans
CDI is the bean management and dependency injection framework that was released as part of Java EE 6 and it includes a complete, comprehensive managed bean facility. CDI beans are far more advanced and flexible than simple JSF managed beans. They can make use of interceptors, conversation scope, Events, type safe injection, decorators, stereotypes and producer methods.
To deploy CDI beans, you must place a file called beans.xml in a META-INF folder on the classpath. Once you do this, then every bean in the package becomes a CDI bean. There are a lot of features in CDI, too many to cover here, but as a quick reference for JSF-like features, you can define the scope of the CDI bean using one of the scopes defined in the javax.enterprise.context package (namely, request, conversation, session and application scopes). If you want to use the CDI bean from a JSF page, you can give it a name using the javax.inject.Named annotation. To inject a bean into another bean, you annotate the field with javax.inject.Inject annotation.
#Named("someBean")
#RequestScoped
public class SomeBean {
#Inject
private SomeService someService;
}
Automatic injection like that defined above can be controlled through the use of Qualifiers that can help match the specific class that you want injected. If you have multiple payment types, you might add a qualifier for whether it is asynchronous or not. While you can use the #Named annotation as a qualifier, you shouldn’t as it is provided for exposing the beans in EL.
CDI handles the injection of beans with mismatched scopes through the use of proxies. Because of this you can inject a request scoped bean into a session scoped bean and the reference will still be valid on each request because for each request, the proxy re-connects to a live instance of the request scoped bean.
CDI also has support for interceptors, events, the new conversation scope and many other features which makes it a much better choice over JSF managed beans.
EJB
EJBs predate CDI beans and are in someways similar to CDI beans and in other ways very different. Primarily, the differences between CDI beans and EJBs is that EJBs are :
Transactional
Remote or local
Able to passivate stateful beans freeing up resources
Able to make use of timers
Can be asynchronous
The two types of EJBs are called stateless and stateful. Stateless EJBs can be thought of as thread safe single-use beans that don’t maintain any state between two web requests. Stateful EJBs do hold state and can be created and sit around for as long as they are needed until they are disposed of.
Defining an EJB is simple, you just add either a javax.ejb.Stateless or javax.ejb.Stateful annotation to the class.
#Stateless
public class BookingService {
public String makeReservation(Item Item, Customer customer) {
...
...
}
}
Stateless beans must have a dependent scope while a stateful session bean can have any scope. By default they are transactional, but you can use the transaction attribute annotation.
While EJBs and CDI beans are very different in terms of features, writing the code to integrate them is very similar since CDI beans can be injected into EJBs and EJBs can be injected into CDI beans. There is no need to make any distinction when injecting one into the other. Again, the different scopes are handled by CDI through the use of proxying. One exception to this is that CDI does not support the injection of remote EJBs but that can be implemented by writing a simple producer method for it.
The javax.inject.Named annotation as well as any Qualifiers can be used on an EJB to match it to an injection point.
When to use which bean
How do you know when to use which bean? Simple.
Never use JSF managed beans unless you are working in a servlet container and don’t want to try and get CDI working in Tomcat (although there are some Maven archetypes for that so there’s no excuse).
In general, you should use CDI beans unless you need the advanced functionality available in the EJBs such as transactional functions. You can write your own interceptor to make CDI beans transactional, but for now, it's simpler to use an EJB until CDI gets transactional CDI beans which is just around the corner. If you are stuck in a servlet container and are using CDI, then either hand written transactions or your own transaction interceptor is the only option without EJBs.
If you need to use #ViewScoped in CDI you should
use seam-faces or MyFaces CODI module. just add one of them to your classpath and #ViewScoped will work in CDI. MyFaces CODI has an even more solid support of #ViewScoped
use MyFaces CODI's #ViewAccessScoped, it is an extension written on top of CDI by Apache, just download it and use #ViewAccessScoped annotation instead of #ViewScoped.
Use CDI #ConversationScoped and make it long running. See here for more info.
Use Omnifaces #ViewScoped annotation
Some parts pilfered from here.
Yep, this can be confusing.
For some ehm historical reasons JSF and CDI are using the same annotations for scopes, but from different packages.
As you are probably guessing those from javax.faces.bean are from the JSF spec, and are not related to CDI. Do not use them unless you have a very good reason to do so. And do never ever mix them with CDI annotations from javax.ejb. This will produce a sheer endless lists of bugs and subtle anomalies.
I generally recommend that you skim the first few (or even more) pages of the excellent Weld documentation. This should put you on track for Java EE 6.
And feel free to post further questions here.
Since there are no replies specifically about #javax.annotation.ManagedBean, here's a link to the answer of a similar question: Backing beans (#ManagedBean) or CDI Beans (#Named)?. The spec can be found at http://download.oracle.com/otndocs/jcp/managed_beans-1.0-fr-eval-oth-JSpec/. So it looks to me that #javax.annotation.ManagedBean was meant to be a generalization of #javax.faces.bean.ManagedBean.
From what I gathered, JSF Managed Beans are being phased out in favour of CDI Beans (maybe getting deprecated from JSF 2.3?), so I guess #javax.annotation.ManagedBean is all the more becoming obsolete now.

CDI injection of beans with no scope

We have a CDI project using:
Tomee Container
Apache OpenWebBeans for CDI
Deltaspike CDI extensions
In the beans.xml file of the webapp the discovery mode is configured to the recommended setting: bean-discovery-mode="annotated". Despite this I am able to inject this class, which isn't annotated with a scope:
public class TestClass implements Serializable {
public String getDescription() {
return "This is a test class";
}
}
Into this ViewScoped class without any issues:
#ViewScoped
#Named
public class AuthenticationWebBean implements Serializable {
#Inject
private TestClass testClass;
I would have expected this to either throw an exception, or to leave the field as null. What is happening here, and will the injected Object take the same scope as the object it's injected into?
Thanks in advance.
The behavior you're describing is in CDI 1.1/1.2, Java EE 7 compliant containers would follow it.
You're using TomEE 1.7.2, which is Java EE 6/CDI 1.0 compliant. It's going to operate under the rules of CDI 1.0 which makes everything a CDI component.
TomEE 7 would begin to demonstrate the behavior you're describing.
TomEE normally supports only Java EE 6, only night builds support Java EE 7. bean-discovery-mode="annotated" is only supported in Java EE 7. It means that in TomEE it is most probably ignored and then all beans are considered for injection. If you want to exclude a bean from injection, annotate it with #Alternative. Otherwise the bean would be injected with the same scope as the bean it is injected into. This is equivalent to #Dependent scope, which is default.

spring vs ejb3 - what is different in beans injection?

is it correct that in spring I can inject my own beans , and in ejb3 I can inject only ejb3 beans ? if so how can ejb3 be a replacement to Spring?
Besides the fact that you can use CDI for injecting different types of beans, what do you mean by "ejb3" beans and how those beans are not yours as in case of spring? Spring injects any kind of bean and you do that either by declaring it in XML (old approach) or by specifying an annotation (#Component, #Service, etc.). Which is the case also for EJB3 (you can use #Stateless instead of #Service, just to make an analogy).
So, in JEE environment one can be replaced with the other (from this point of view, Spring has some advantages as it sets the grounds for fast development, providing additional helpers, libraries, frameworks on top of JEE specification - see Spring Data JPA for one).
So, I think is a matter of how you design your application to use one or the other.
In a Java EE environment, you can not only use EJB, but also CDI.
see How do CDI and EJB compare? interact?

Java EE 6 #javax.annotation.ManagedBean vs. #javax.inject.Named vs. #javax.faces.ManagedBean

I feel there is a little mess in the Java EE 6 spec. There are several sets of annotations.
We have javax.ejb annotations like #Stateful and #Stateless for creating EJBs.
There is also a #javax.annotation.ManagedBean to create a managed bean.
There are annotations in javax.enterprise.context like #SessionScoped and #RequestScoped.
What is more there are also #ManagedBean and #SessionScoped/#RequestScoped annotations in javax.faces.bean package.
And to make things event more complicated there is a package javax.inject with #Named annotation.
Can someone please describe how they are related one to another?
Where can I use #EJB, #Inject or #ManagedPropery to inject other beans?
First of all let me do some clarifications:
Managed bean definition : generally a managed bean is an object that its life cycle (construction, destruction, etc) is managed by a container.
In Java ee we have many containers that manage life cycle of their objects, like JSF container, EJB container, CDI container, Servlet container, etc.
All of these containers work kind of independent, they boot in application server initialization and scan classes of all artifacts including jar, ejb-jar, war and ear files in deployment time and gather and store some metadata about them, then when you need an object of a class at runtime they will give you instances of those classes and after finishing the job, they will destroy them.
So we can say that we have:
JSF managed beans
CDI managed beans
EJB managed beans
And even Servlets are managed beans because they are instantiated and destroyed by a container, which is a servlet container.
So when you see the Managed Bean word, you should ask about the context or type of it.(JSF, CDI, EJB, etc.)
Then you might ask why we have many of these containers: AFAIK, Java EE guys wanted to have a dependency injection framework, but they could not gather all requirements in one specification because they could not predict the future requirements and they made EJB 1.0 and then 2.0 and then 3.0 and now 3.1 but EJB's target was for just some requirements (transaction, distributed component model, etc).
At the same time (in parallel) they realized that they need to support JSF too, then they made JSF managed beans and another container for JSF beans and they considered it a mature DI container, but still it was not complete and mature container.
After that Gavin King and some other nice guys ;) made CDI which is the most mature DI container I've seen. CDI (inspired by Seam2, Guice and Spring) was made to fill the gap between JSF and EJB and lots of other useful stuff like pojo injection, producer methods, interceptors, decorators, integration SPI, very flexible, etc. and it can even do what EJB and JSF managed beans are doing then we can have just one mature and powerful DI container. But for some backward compatibility and political reasons Java EE guys want to keep them!!!
Here you can find the difference and use cases for each of these types:
JSF Managed Beans, CDI Beans and EJBs
JSF was initially developed with its own managed bean and dependency injection mechanism which was enhanced for JSF 2.0 to include annotation based beans. When CDI was released with Java EE 6, it was regarded as the managed bean framework for that platform and of course, EJBs outdated them all having been around for well over a decade.
The problem of course is knowing which one to use and when use them.
Let’s start with the simplest, JSF Managed beans.
JSF Managed Beans
In short, don’t use them if you are developing for Java EE 6 and using CDI. They provide a simple mechanism for dependency injection and defining backing beans for web pages, but they are far less powerful than CDI beans.
They can be defined using the #javax.faces.bean.ManagedBean annotation which takes an optional name parameter. This name can be used to reference the bean from JSF pages.
Scope can be applied to the bean using one of the different scopes defined in the javax.faces.bean package which include the request, session, application, view and custom scopes.
#ManagedBean(name="someBean")
#RequestScoped
public class SomeBean {
....
....
}
JSF beans cannot be mixed with other kinds of beans without some kind of manual coding.
CDI Beans
CDI is the bean management and dependency injection framework that was released as part of Java EE 6 and it includes a complete, comprehensive managed bean facility. CDI beans are far more advanced and flexible than simple JSF managed beans. They can make use of interceptors, conversation scope, Events, type safe injection, decorators, stereotypes and producer methods.
To deploy CDI beans, you must place a file called beans.xml in a META-INF folder on the classpath. Once you do this, then every bean in the package becomes a CDI bean. There are a lot of features in CDI, too many to cover here, but as a quick reference for JSF-like features, you can define the scope of the CDI bean using one of the scopes defined in the javax.enterprise.context package (namely, request, conversation, session and application scopes). If you want to use the CDI bean from a JSF page, you can give it a name using the javax.inject.Named annotation. To inject a bean into another bean, you annotate the field with javax.inject.Inject annotation.
#Named("someBean")
#RequestScoped
public class SomeBean {
#Inject
private SomeService someService;
}
Automatic injection like that defined above can be controlled through the use of Qualifiers that can help match the specific class that you want injected. If you have multiple payment types, you might add a qualifier for whether it is asynchronous or not. While you can use the #Named annotation as a qualifier, you shouldn’t as it is provided for exposing the beans in EL.
CDI handles the injection of beans with mismatched scopes through the use of proxies. Because of this you can inject a request scoped bean into a session scoped bean and the reference will still be valid on each request because for each request, the proxy re-connects to a live instance of the request scoped bean.
CDI also has support for interceptors, events, the new conversation scope and many other features which makes it a much better choice over JSF managed beans.
EJB
EJBs predate CDI beans and are in someways similar to CDI beans and in other ways very different. Primarily, the differences between CDI beans and EJBs is that EJBs are :
Transactional
Remote or local
Able to passivate stateful beans freeing up resources
Able to make use of timers
Can be asynchronous
The two types of EJBs are called stateless and stateful. Stateless EJBs can be thought of as thread safe single-use beans that don’t maintain any state between two web requests. Stateful EJBs do hold state and can be created and sit around for as long as they are needed until they are disposed of.
Defining an EJB is simple, you just add either a javax.ejb.Stateless or javax.ejb.Stateful annotation to the class.
#Stateless
public class BookingService {
public String makeReservation(Item Item, Customer customer) {
...
...
}
}
Stateless beans must have a dependent scope while a stateful session bean can have any scope. By default they are transactional, but you can use the transaction attribute annotation.
While EJBs and CDI beans are very different in terms of features, writing the code to integrate them is very similar since CDI beans can be injected into EJBs and EJBs can be injected into CDI beans. There is no need to make any distinction when injecting one into the other. Again, the different scopes are handled by CDI through the use of proxying. One exception to this is that CDI does not support the injection of remote EJBs but that can be implemented by writing a simple producer method for it.
The javax.inject.Named annotation as well as any Qualifiers can be used on an EJB to match it to an injection point.
When to use which bean
How do you know when to use which bean? Simple.
Never use JSF managed beans unless you are working in a servlet container and don’t want to try and get CDI working in Tomcat (although there are some Maven archetypes for that so there’s no excuse).
In general, you should use CDI beans unless you need the advanced functionality available in the EJBs such as transactional functions. You can write your own interceptor to make CDI beans transactional, but for now, it's simpler to use an EJB until CDI gets transactional CDI beans which is just around the corner. If you are stuck in a servlet container and are using CDI, then either hand written transactions or your own transaction interceptor is the only option without EJBs.
If you need to use #ViewScoped in CDI you should
use seam-faces or MyFaces CODI module. just add one of them to your classpath and #ViewScoped will work in CDI. MyFaces CODI has an even more solid support of #ViewScoped
use MyFaces CODI's #ViewAccessScoped, it is an extension written on top of CDI by Apache, just download it and use #ViewAccessScoped annotation instead of #ViewScoped.
Use CDI #ConversationScoped and make it long running. See here for more info.
Use Omnifaces #ViewScoped annotation
Some parts pilfered from here.
Yep, this can be confusing.
For some ehm historical reasons JSF and CDI are using the same annotations for scopes, but from different packages.
As you are probably guessing those from javax.faces.bean are from the JSF spec, and are not related to CDI. Do not use them unless you have a very good reason to do so. And do never ever mix them with CDI annotations from javax.ejb. This will produce a sheer endless lists of bugs and subtle anomalies.
I generally recommend that you skim the first few (or even more) pages of the excellent Weld documentation. This should put you on track for Java EE 6.
And feel free to post further questions here.
Since there are no replies specifically about #javax.annotation.ManagedBean, here's a link to the answer of a similar question: Backing beans (#ManagedBean) or CDI Beans (#Named)?. The spec can be found at http://download.oracle.com/otndocs/jcp/managed_beans-1.0-fr-eval-oth-JSpec/. So it looks to me that #javax.annotation.ManagedBean was meant to be a generalization of #javax.faces.bean.ManagedBean.
From what I gathered, JSF Managed Beans are being phased out in favour of CDI Beans (maybe getting deprecated from JSF 2.3?), so I guess #javax.annotation.ManagedBean is all the more becoming obsolete now.

How do CDI and EJB compare? interact?

I'm having a tough time understanding how the two interact and where the boundary between them lies. Do they overlap? Are there redundancies between them?
I know there are annotations associated with both, but I haven't been able to find a complete list for both with brief descriptions. Not sure if this would help clear up how they differ or where they overlap.
Really just confused. I (think I) understand EJB reasonably well, I guess I'm having a hard time understanding exactly what CDI brings to the table and how it supplants or enhances what EJB already offers.
It is currently indeed a bit confusing as there are now multiple component models in Java EE. They are CDI, EJB3 and JSF Managed Beans.
CDI is the new kid on the block. CDI beans feature dependency injection, scoping and an event bus. CDI beans are the most flexible with respect to injection and scoping. The event bus is very lightweight and very well suited for even the simplest of web applications. In addition to this, CDI also exposes a very advanced feature called portable extensions, which is a kind of plug-in mechanism for vendors to provide extra functionality to Java EE that can be made available on all implementations (Glassfish, JBoss AS, Websphere, etc).
EJB3 beans were retrofitted from the old legacy EJB2 component model* and were the first beans in Java EE to be managed beans via an annotation. EJB3 beans feature dependency injection, declarative transactions, declarative security, pooling, concurrency control, asynchronous execution and remoting.
Dependency injection in EJB3 beans is not as flexible as in CDI beans and EJB3 beans have no concept of scoping. However, EJB3 beans are transactional and pooled by default**, two very useable things that CDI has chosen to leave in the domain of EJB3. The other mentioned items are also not available in CDI. EJB3 has no event bus of its own though, but it does have a special type of bean for listening to messages; the message driven bean. This can be used to receive messages from the Java Messaging System or from any other system that has a JCA resource adaptor. Using full blown messaging for simple events is far more heavyweight than the CDI event bus and EJB3 only defines a listener, not a producer API.
JSF Managed Beans have existed in Java EE ever since JSF was included. They too feature dependency injection and scoping. JSF Managed Beans introduced the concept of declarative scoping. Originally the scopes were rather limited and in the same version of Java EE where EJB3 beans could already be declared via annotations, JSF Managed Beans still had to be declared in XML. The current version of JSF Managed Beans are also finally declared via an annotation and the scopes are expanded with a view scope and the ability to create custom scopes. The view scope, which remembers data between requests to the same page is a unique feature of JSF Managed Beans.
Apart from the view scope, there is very little still going for JSF Managed Beans in Java EE 6. The missing view scope in CDI there is unfortunate, since otherwise CDI would have been a perfect super set of what JSF Managed Beans offer. Update: In Java EE 7/JSF 2.2 a CDI compatible #ViewScoped has been added, making CDI indeed that perfect super set. Update 2: In JSF2.3 the JSF managed beans have been deprecated in favour of CDI managed beans.
With EJB3 and CDI the situation is not that clear cut. The EJB3 component model and API offers a lot of services that CDI does not offer, so typically EJB3 cannot be replaced by CDI. On the other hand, CDI can be used in combination with EJB3 - e.g. adding scope support to EJBs.
Reza Rahman, expert group member and implementor of a CDI implementation called CanDI, has frequently hinted that the services associated with the EJB3 component model can be retrofitted as a set of CDI annotations. If that were to happen, all managed beans in Java EE could become CDI beans. This does not mean that EJB3 disappears or becomes obsolete, but just that its functionality will be exposed via CDI instead of via EJB's own annotations like #Stateless and #EJB.
Update
David Blevins of TomEE and OpenEJB fame explains the differences and similarities between CDI and EJB very well on his blog: CDI, when to break out the EJBs
*
Although it's just an increment in version number, EJB3 beans were for the most part a completely different kind of bean: a simple pojo that becomes a "managed bean" by applying a simple single annotation, vs the model in EJB2 where a heavyweight and overly verbose XML deployment descriptor was required for each and every bean, in addition to the bean being required to implement various extremely heavyweight and for the most part meaningless component interfaces.
** Stateless session beans are typically pooled, stateful session beans typically not (but they can be). For both types pooling is thus optional and the EJB spec does not mandate it either way.
CDI: it is about dependency injection. It means that you can inject interface implementation anywhere. This object can be anything, it can be not related to EJB. Here is an example of how to inject random generator using CDI. There is nothing about EJB. You are going to use CDI when you want to inject non-EJB services, different implementations or algorithms (so you don't need EJB there at all).
EJB: you do understand, and probably you are confused by #EJB annotation - it allows you to inject implementation into your service or whatever. The main idea is that class, where you inject, should be managed by EJB container.
Seems that CDI does understand what EJB is, so in Java EE 6 compliant server, in your servlet you can write both
#EJB EJBService ejbService;
and
#Inject EJBService ejbService;
that's what can make you confusing, but that's probably the only thing which is the bridge between EJB and CDI.
When we are talking about CDI, you can inject other objects into CDI managed classes (they just should be created by CDI aware frameworks).
What else CDI offers... For instance, you use Struts 2 as MVC framework (just example), and you are limited here, even using EJB 3.1 - you can't use #EJB annotation in Struts action, it is not managed by container. But when you add Struts2-CDI plugin, you can write there #Inject annotation for the same thing (so no more JNDI lookup needed). This way it enhances EJB power, but as I mentioned before, what you inject with CDI - it does not matter if it is related to EJB or not, and that's its power.
PS. updated link to the example
Albert Einstein: If you can't explain it simply, you don't understand it well enough
Ejbs and CDI are pretty simple to understand.
Ejbs:
Will always be annotated by scope qualifiers, for instance, #Stateless, #Stateful, #Request etc
The instances of Ejbs is controlled by the Java EE framework and pooled. It is the duty of EE framework to provide the instances for the consumer.
#Stateless
public class CarMaker(){
public void createCar(Specification specs){
Car car = new Car(specs);
}
}
The CarMaker is Annotated with specific Ejbs scope, therefore, it's Ejb
CDI:
Not managed entirely by EE framework, instances has to be created by yourself.
It is always dependent. let me explain "Dependent" with example:
class Specification {
private String color;
private String model;
//- Getter and Setter
}
The Specification class is CDI, since it is not annotated with Ejb scopes and also this has to initialized by your code not EE framework.
One point to be noted here is that since we didn't Annotated the Specification class, it is by default Annotated by #Dependent annotation.
#Dependent <- By default added
class Specification { ... }
Further reading: You need to study more between Ejbs scope annotation and CDI scope annotation, that will further clear the conceptl

Categories