How to add a EJB Interceptor programmatically? - java

I'm trying to add a Interceptor in a EJB at runtime programmatically via CDI extensions.
This EJB exposes a Remote interface for remote calls. But I'm trying to add this Interceptor in the implementation class of this EJB adding the #Interceptors annontation like in this other SO question (CDI Extensions - Add Interceptors in ProcessAnnotatedType phase)
I think the CDI Extension only executes after the EJB are already registered because the Interceptor is never called.
But, for test purpose I have successfully register and execute an Interceptor programmatically in a simple CDI Bean.
The problem is when I'm try to register in a EJB.
Am I missing something?
Edit:
I'm using Wildfly 8

I think the key problem here is the difference between #Interceptors (EJB ones) and #Interceptor (CDI ones). CDI does not govern EJB container hence adding the EJB annotation (#Interceptors) in CDI extension won't necessarrily kick EJB logic into effect - EJB container might have started at that moment and it won't know of the annotation. Furthermore the CDI extension would add this annotation to the AnnotatedType which is a structure EJB probably won't make use of. On the other hand, all this really depends on the application server as it is responsible for CDI/EJB integration hence as a "bonus" the behavior might differ between AS.
CDI extension is something which allows you to hook into CDI bootstrap lifecycle, therefore you are able to use/enable/add CDI interceptors. I would try going that way instead. BTW even the SO question you referred to speaks of beans.xml/#Priority for enablement which means it uses CDI interceptors and not EJB ones.
Also, an EJB bean should automatically become CDI bean therefore you can attach CDI interceptor to it without changing the bean itself.

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.

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 to get a 'JBoss service' with CDI in JMX with AS6?

I'm currently migrating a JBoss service class from AS5.1 to AS6 (not going to AS7 for a variety of reasons).
For AS5.1, the service implements a {serviceName}MBean and has a jboss-service.xml with attribute values. It's packaged in a jboss-sar, which is packaged in an EAR to be deployed. When deployed, the service fields are populated with the values from jboss-service.xml, and the service is automatically registered into JMX.
I would like to achieve the same thing using AS6, but would like the service to support CDI - so I'd like its new #Inject injection points to be satisfied. I need these to be satisfied in the object registered with JMX, so that methods called via JMX can reference injected fields, but I'm struggling to achieve this.
I've had to package the service in a jar, instead of a jboss-sar, for classloader reasons, but let's say it's otherwise unchanged. When deployed to AS6, all works as before - service goes into JMX, values from XML propagate to the object. However, the instance created does not have its CDI injection points satisfied, and neither does the object registered in JMX.
If I annotate the service class with #Startup and #javax.ejb.Singleton, but keep its interface and the jboss-service.xml, the object registered into JMX still does not have its CDI injection points satisfied. However if I programmattically deregister that bean, and re-register the instance in a #PostConstruct method, then the bean in JMX DOES have its injection points satisfied. However that bean no longer has the values specified in the jboss-service.xml.
So how can I get the best of both worlds? CDI and the usual JBoss service behaviour? What is the correct way to implement a JBoss service with CDI? I've been unable to find documentation on this. Hope someone can help.
Thanks,
Ben
As a worst-case fallback, you should be able to use the CDI extension API to get your service to be injected. I don't think you would need to write a fully-fledged extension, but if you have an initialisation hook in the service object, you can do this (lifted with minor editing from the docs, not compiled or tested):
public static <T> void inject(T object) {
BeanManager beanManager = (BeanManager)new InitialContext().lookup("java:comp/BeanManager");
AnnotatedType<T> type = beanManager.createAnnotatedType(object.getClass());
InjectionTarget<T> it = beanManager.createInjectionTarget(type);
CreationalContext ctx = beanManager.createCreationalContext(null);
it.inject(object, ctx);
it.postConstruct(object);
}
Basically, any object to that method will get injected. All the usual CDI annotations should work. Hopefully.
As mentioned in the comments above, it seems Tom's right - there's no 'nice' way of created a CDIed, JMX bean in one go, you either have to put your JMX bean in CDI, as is suggested above, or put you CDIed bean into JMX. We tried the former, but it appears the BeanManager isn't bound to JNDI at the point the service starts up.
So instead we went with CDI bean -> JMX. We're creating the services as Singleton EJBs, so their injection points are satisfied, and they then get registered/unregistered to JMX in their PostConstruct/PreDestroy methods, using German Escobar's excellent CDI portable extension (germanescobar.net/2010/01/cdi-portable-extension-jmx.html, community.jboss.org/thread/148750 is also helpful).
May try to use ApplicationScoped beans and get them to start by observing a ContainerInitialized(?) event, however, as we don't need all the features of an EJB. Haven't tried that yet, mind...

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

Something like EJB wiring in Spring for non EJB's

I've noticed recently that spring can wire up my ejb's for me if I annotate the ejb with #Interceptors(SpringBeanAutowiringInterceptor.class). I've never actually done this so don't know the details.
I was wondering, is there a way to get this to work with other kinds of beans, for example, #WebService annotated ones as well.
At the moment in my web service classes (because the application server manages them) I have to load the dependencies from the BeanFactory and would thus prefer to have them autowired.
I know I could use the #Configurable annotation but am not particularly keen to have to specify and agent on the VM.
Is this possible?
Once again, spring has thought of this use case and catered for it!
The problem is that #WebService is not a spring annotation, it is a JAX-WS annotation and thus classes that are annotated with #WebService to be exposed as web services are not managed by spring, but their life cycle is managed by JAX-WS.
The way to handle this case is to have the JAX-WS managed bean extend org.springframework.web.context.support.SpringBeanAutowiringSupport - this will enable the #Autowire annotation, for example, to work in this bean. see here for more information
Yes, of course. There's #WebService, #Repository, #Controller, #Service, #Endpoint, and other annotations in Spring. Here's an example.

Categories