Friday, April 9, 2010

4 areas of possible confusion in JEE 6

The JEE specification is released and maintained through the Java Community Process, which defines the different API’s that will be included in each release, and how they relate to each other. Due to the technical and political factors involved in the process, besides the time constraint, is no surprise that some areas of the specification may be confusing to new developers, especially with the rising number of annotations introduced by each API.

In this post, I will try to explain four areas where developers might find themselves confused when working with JEE 6.

1. Managed Beans and EL access

The following two annotations from the JEE 6 API are both used to access a bean from the Expression Language (i.e. using the #{} notation):

  • @javax.faces.bean.ManagedBean – Defined in the JSF 2.0 Managed Bean Annotations specification (JSR-314), it provides an alternative to the declaration of managed beans in the faces-config.xml descriptor file.
  • @javax.inject.Named – Defined in the Dependency Injection (JSR-330) specification, is one of the built-in qualifier types of CDI (JSR-299) used to provide a name to a bean, making it accessible through EL.

So, which one to use? Always use the @Named annotation, unless you are working in a JSF 2.0 environment without CDI (a very unlikely scenario). There is just no reason to use JSF Managed Beans if CDI is present. You can check this article for more information.

Furthermore, there is another @ManagedBean annotation you might also get confused with:

  • @javax.annotation.ManagedBean – Defined by the Commons Annotations specification (JSR-250), it is used to declare a managed bean as specified in the Managed Beans specification (JSR-316).

Most likely, you will never need to use this annotation. Let’s look why.

First, don’t confuse Managed Beans with JSF Managed Beans, they are different things. The Managed Beans specification, a subset of the JSR-316, is an effort to provide services like dependency injection, lifecycle callbacks and interceptors to POJO’s (Plain Old Java Objects), which is really cool! So, why not to use it?

CDI treats all POJO’s as Managed Beans! There is no need to explicitly annotate the POJO with @javax.annotation.ManagedBean. Nothing stops you from doing it though.

2. Duplicated @…Scoped annotations

The following annotations are duplicated in the JEE 6 API:

  • @javax.faces.bean.RequestScoped and @javax.enterprise.context.RequestScoped.
  • @javax.faces.bean.SessionScoped and @javax.enterprise.context.SessionScoped.
  • @javax.faces.bean.ApplicationScoped and @javax.enterprise.context.ApplicationScoped.

The @javax.faces.bean… annotations are defined in the JSF Managed Beans specification (JSR-314) and the @javax.enterprise.context… annotations are defined in the CDI specification (JSR-299). 

So, which ones to use? Always use the CDI annotations, unless you are working in a JSF 2.0 environment without CDI (a very unlikely scenario). As discussed above, there is no reason to use JSF Managed Beans if CDI is present.

One scope that is missing in CDI is the @ViewScoped of JSF. However, the problem is solved by creating a portable extension which will be included in the Seam 3 Faces Module.

3. Defining a Singleton

There are four annotations that provide very similar functionality:

  • @javax.ejb.Singleton – A new type of EJB from the JSR-318 specification, it is used to maintain a single shared instance; it’s thread safe and transactional.
  • @javax.inject.Singleton – From the Dependency Injection specification (JSR-330), marks a type the injector will only instantiate once.
  • @javax.enterprise.inject.ApplicationScoped – One of the built-in scopes from the Contexts and Dependency Injection specification (JSR-299), specifies that a bean is application scoped.
  • @javax.faces.bean.ApplicationScoped – Defined in the JSF 2.0 (JSR-314) Managed Beans specification, specifies that a JSF managed bean is application scoped.

They all guarantee a single instance of the class. But, which one to use?

We have already discussed the duplicated @ApplicationScoped annotations above, so we will just dismiss @javax.faces.bean.ApplicationScoped to move on. That leaves us with just 3 options.

@javax.ejb.Singleton is the only one that will give you out-of-the-box “enterprise” services such as concurrency and transaction management. So, if you need these features, this is the annotation to use. You can optionally add the @javax.enterprise.inject.ApplicationScoped annotation but you will not feel the difference, although, CDI will treat it differently. You can check this forum thread for more information.

Note: even though it is possible to use @javax.enterprise.inject.ApplicationScoped with a Stateful Session Bean, I can’t find any good reason to use it given that EJB 3.1 has introduced the Singleton Beans.

If you want to use POJO’s (called Managed Beans in the JEE world), instead of EJB’s, you can also annotate them with @javax.enterprise.inject.ApplicationScoped to guarantee that the class is instantiated only once. Be aware that you will lose all of the services provided by EJB’s such as concurrency and transaction management.

I would not suggest using @javax.inject.Singleton unless you are working in a JS2E environment without CDI support. You can check the Weld documentation and this forum thread for more information about how this annotation is handled in CDI.

Note: none of the annotations discussed above will guarantee a shared single instance in a clustered environment. Usually, you will have one singleton instance per JVM.

4. @Inject or @EJB

They are both used for injection. @Inject is from the Dependency Injection specification (JSR-330) and @EJB from the EJB specification (JSR-318).

So, which one to use?

In most of the cases you will use @Inject over @EJB unless you are working on an environment with EJB’s but no CDI (very unlikely since JEE 6), or if you need to define an EJB resource. You can check the this forum thread for more information.

Conclusion

  1. If you need to access a bean through EL (i.e. from a JSF page), annotate the bean with @Named.
  2. Usually, you will never need none of the @ManagedBean annotations.
  3. Always use the @…Scoped annotations from the javax.enterprise.context package (CDI).
  4. To define a singleton, use the @ApplicationScoped annotation. If you need the EJB services such as concurrency and transaction, add the @javax.ejb.Singleton annotation.
  5. Always use @Inject instead of @EJB, unless you really have a motive to do so.

22 comments:

Anonymous said...

nice article - I hope a book or more articles on CDI come out soon.

Germán Escobar said...

Thanks! Yes, I hope that too ;)

Jan Halasa said...

Thank you Germán for clarification, I was also little confused about these annotations :)

Kai Wähner said...

Very good article! Actually, these problems confused me a lot looking at JEE 6.

But one extension should be made:
Always use @Inject instead of @EJB, if you need a local instance. You still need @EJB for Remote EJBs.

I think this is a little bit unclear... Or do you disagree?

Best regards, Kai.

Germán Escobar said...

Kai,

I agree. @EJB only if you need a remote EJB or need to define a resource. Is anybody still using remote EJB's? ;)

Anonymous said...

Thank you!

Anonymous said...

Nice article.
thanks.

Gregor said...

hmmm... using the POJO+@Inject-approach in JBoss 6.1.0.Final, I repeatedly get an Exception:

ERROR [org.jboss.kernel.plugins.dependency.AbstractKernelController] Error installing to Start: name=vfs:///C:/Programme/jboss-6.1.0.Final/server/default/deploy/myapp.war_WeldBootstrapBean state=Create: java.lang.RuntimeException: Service class org.jboss.kernel.weld.plugins.weld.McBeanRegistryObserver didn't implement the Extension interface

This does not happen in another, smaller JEE6 project, though. Any tips on this exception? I only found one entry on pastebin using Google...

Anonymous said...

ERROR [org.jboss.kernel.plugins.dependency.AbstractKernelController] Error installing to Start: name=vfs:///C:/Programme/jboss-6.1.0.Final/server/default/deploy/myapp.war_WeldBootstrapBean state=Create: java.lang.RuntimeException: Service class org.jboss.kernel.weld.plugins.weld.McBeanRegistryObserver didn't implement the Extension interface


Getting the same error, did you solve it?

Wei Wei said...

Very nice summary. Thanks.

Ant Kutschera said...

Nice article.

@Gérman: "Is anybody still using remote EJBs"? Sure, if you have an enterprisy landscape (i.e. large) and want to scale, while at the same time getting the container to handle distributed transactions and security. SOA with Web Services makes life harder (compensation & recovery rather than transactions) and so remote EJBs is a good alternative.

Anna said...

Great and Useful Article.

J2EE Training

Java EE course

Java EE training

J2EE training in chennai

Java J2EE Training Institutes in Chennai

Java J2EE Training in Chennai

Java EE training

Java Interview Questions

LightningStrikerOfDreamsStormKnight08 said...

Denizli
Konya
Denizli
ısparta
Bayburt
4LFL3

PlasmaPioneer666 said...

görüntülü.show
whatsapp ücretli show
İTVAW

CelestialCipherXY123456789 said...

ankara parça eşya taşıma
takipçi satın al
antalya rent a car
antalya rent a car
ankara parça eşya taşıma
GKLZİ

CBF56AlvaroF6D1E said...

EC67C
Aksaray Evden Eve Nakliyat
Bayburt Lojistik
Uşak Lojistik
Çanakkale Evden Eve Nakliyat
Edirne Evden Eve Nakliyat

76923MaliaC569E said...

50015
Çerkezköy Çekici
Nevşehir Evden Eve Nakliyat
Rize Şehir İçi Nakliyat
Çerkezköy Sineklik
Tunceli Lojistik
Karapürçek Boya Ustası
Burdur Lojistik
Vindax Güvenilir mi
Gate io Güvenilir mi

BDB02AvahEF600 said...

54067
Hatay Şehirler Arası Nakliyat
Samsun Lojistik
Giresun Parça Eşya Taşıma
Iğdır Şehir İçi Nakliyat
Yalova Şehirler Arası Nakliyat
Düzce Parça Eşya Taşıma
Edirne Şehirler Arası Nakliyat
Kocaeli Parça Eşya Taşıma
Diyarbakır Evden Eve Nakliyat

3C82CFletcher10830 said...

82077
osmaniye sohbet odaları
kayseri görüntülü sohbet yabancı
ucretsiz sohbet
seslı sohbet sıtelerı
Kırşehir Canlı Ücretsiz Sohbet
Ordu Ucretsiz Sohbet
kayseri bedava sohbet
karaman en iyi görüntülü sohbet uygulamaları
afyon sohbet odaları

745A1SophiaC91BB said...

4A114
ığdır sohbet odaları
sohbet odaları
ordu sesli görüntülü sohbet
bitlis canlı sohbet uygulamaları
agri bedava görüntülü sohbet
kastamonu kadınlarla görüntülü sohbet
mersin rastgele sohbet odaları
bingöl görüntülü canlı sohbet
telefonda kadınlarla sohbet

53023Ansley1B09F said...

D9C7C
Referans Kimliği Nedir
Bitcoin Nasıl Kazanılır
Facebook Beğeni Hilesi
Twitter Beğeni Hilesi
Threads Yeniden Paylaş Hilesi
Instagram Beğeni Hilesi
Binance Referans Kodu
Arg Coin Hangi Borsada
Coin Madenciliği Nasıl Yapılır

0C754Anaya26724 said...

AA587
Youtube İzlenme Satın Al
Görüntülü Sohbet
Periscope Beğeni Satın Al
Dxy Coin Hangi Borsada
Twitter Retweet Satın Al
Youtube Beğeni Hilesi
Paribu Borsası Güvenilir mi
Binance Referans Kodu
Tiktok İzlenme Hilesi

Post a Comment