Showing posts with label cdi. Show all posts
Showing posts with label cdi. Show all posts

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.

Sunday, March 28, 2010

What’s so wrong with EJB’s?

It’s not that they are heavy. It’s not that they are difficult to write. So, what’s wrong with EJB’s?

EJB’s can be either Stateless, Stateful or Singleton. However, when you are working on a web environment for example, these lifecycles will not suffice. Request, session and application lifecycles would be much better suited in that case. Another example is a business process application, where you could have a task or a process lifecycle; again, EJB’s will not match those lifecycles. This is what I call the Lifecycle Mismatch.

Through the years, EJB’s have become more POJO-like, through the use of annotations and without requirements such as XML descriptors and Java interfaces. However, it doesn’t matter how simple they get, until they don’t remove the lifecycle restriction, you will end up creating additional layers in your application and different component models to adapt your required lifecycles.

Note: The lifecycles I’m referring are also known as contexts or scopes in other frameworks/specifications.

For example, take a look at JSF. They introduced the JSF Managed Beans to handle this problem. JSF Managed Beans can be bound to request, session or application contexts. From there, you are on your own on how you connect them to the EJB’s different lifecycle.

CDI (Contexts and Dependency Injection) is a specification, part of the JEE stack, that is trying to fill that gap. It provides dependency injection and lifecycle management to POJO’s and EJB’s. But providing lifecycle management to EJB’s doesn’t feels right, because they already provide their own. CDI does its best effort to accommodate this mismatch.

On the other hand, CDI could provide to POJO’s, all the services EJB’s currently have, through extensions. So, do we really need EJB’s? Well, not really! You can check my post EJB’s - Time to let them go? for more information.

Conclusion

EJB’s have become light weighted and easy to write. But the lifecycle mismatch is still there. POJO’s, on the other hand, don’t have this restriction and, with CDI, they could have all the services EJB’s currently provide.

Thursday, March 4, 2010

Understanding and Comparing Dependency Injection Frameworks

If you have used a modern Dependency Injection (DI) framework like JBoss Seam, Google Guice or CDI (Contexts and Dependency Injection), you might already be familiar with the following line of code:

@Inject MyBean myBean;

But, to really understand how a DI framework works and what makes one different from the other, we are going to build one from scratch. Let’s call it OurDI. Then, we will compare it with some of the most popular DI frameworks out there.

So, let’s start by writing a Quick Start Guide for OurDI that shows how it works.

Quick Start Guide

As any other modern DI framework, OurDI allows you to inject dependencies using annotations as in the following example:

public class UsesInjection {
  @Inject MyBean myBean;
  ... 
}

In order to configure OurDI, all you need to do is to populate a class named Injector with all the objects that can be injected at runtime; each object must be identified by a unique name. In the following example, we are going to configure the Injector with two classes MyBean and AnotherBean, bound to the names “myBean” and “anotherBean” respectively:

public class Main {
  public final static void main(String[] args) {  
    Injector injector = Injector.instance();  
    injector.bind(“myBean”, new MyBean());  
    injector.bind(“anotherBean”, new AnotherBean(); 
  }
}

So, when a method of the UsesInjection class (defined above) is called, a search will be done for the name of the attribute “myBean” on the Injector instance, and the value associated with that name will be injected.

Building the framework

Well, that was a quick Quick Start Guide! Now let's see how OurDI works underneath.

OurDI is composed of two classes and an annotation:

  • A singleton class named Injector, that will store the bound objects.
  • A class named InjectorInterceptor, which will use AOP (Aspect Oriented Programming) to inject the dependencies at runtime.
  • The @Inject annotation.

Let’s take a look at the Injector class:

public class Injector {

  private Map<String,Object> bindings = new HashMap<String,Object>();

  // static instance, private constructor and static instance() method 
 
  public void bind(String name, Object value) {
    bindings.put(name, value);
  }
 
  public Object get(String name) {
    return bindings.get(name);
  }
}

As you can see, Injector is singleton class backed by a Map<String,Object> that binds each object to a unique name. Now, let’s see how injection is done when an @Inject annotation is found.

We can use any AOP library to intercept method calls and look for all the dependencies that need to be injected on the target object. In this case, we are going to use AspectJ:

@Aspect
public class InjectorInterceptor {

  @Around("call(* *.*(..)) && !this(InjectorInterceptor)")
  public Object aroundInvoke(ProceedingJoinPoint joinPoint) throws Throwable {
  
    // this should return the target class
    Class clazz = joinPoint.getTarget().getClass();
  
    // inject fields annotated with @Inject
    for (Field field : clazz.getDeclaredFields()) {
      if (field.isAnnotationPresent(Inject.class)) {
        doInjection(joinPoint.getTarget(), field);
      }
    }
  
    return joinPoint.proceed();
  }
 
  private void doInjection(Object target, Field field) throws IllegalAccessException {
    String name = field.getName();
    field.setAccessible(true);
    field.set(target, Injector.instance().get(name));
  }
}

Before each method call, the aroundInvoke method will be called. It will look at all the fields of the target object to see if it finds any @Inject annotation. For each of the annotated fields, it uses the name of the field to find the corresponding object in the Injector class.

Finally, here is our @Inject annotation:

@Target(value={FIELD})
@Retention(value=RUNTIME)
@Documented
public @interface Inject {}

That’s all! you can check the full source here. Now, let’s check some aspects of our solution and compare them with other popular frameworks out there.

Configuration

In OurDI, we have to manually populate the Injector instance with the objects that are going to be injected. This is similar to Google Guice. However, in Guice, there is no need to use a name and, instead of binding objects, we bind classes:

Injector injector = Guice.createInjector(new Module() {
  public void configure(Binder binder) {
    binder.bind(Notifier.class).to(SendSMS.class);
    binder.bind(Database.class).to(MySqlDatabase.class);
  }
});

JBoss Seam and CDI take a different approach. Instead of binding each class manually, they scan all your classes on bootstrap to populate the “injector”. In JBoss Seam, you will need to register the Seam Servlet Listener on your web.xml; for CDI, no configuration is required (besides the beans.xml descriptor), the application server will do the scanning automatically (one of the benefits of being part of the JEE stack).

Scanning all classes and choosing the ones suitable for injection can take a while. So, Google Guice (and OurDI) will be faster starting up. However, with JBoss Seam or CDI, you won’t have to worry about binding each class/object manually.

Type safety

As you might already have noticed, OurDI will break at runtime with a ClassCastException if the injected object is not of the expected type. The same happens with JBoss Seam, which also uses a name-based approach (components are named using the @Name annotation).

On the other hand, Google Guice and CDI are type safe, meaning that the injected objects are not identified by a name, but by their type.

Overriding/changing implementations

In OurDI, to override/change the implementation of an injected class, all we need to do is change the object bound to the Injector class. This is very similar to Google Guice as shown before.

For JBoss Seam and CDI, we need to provide more information about the classes we want to use. I won’t dive into the details but you can check how this works in the Weld documentation for CDI and in this post for JBoss Seam.

Constructor and method injection

Besides field injection, some DI frameworks provide constructor and method injection to initialize your objects. OurDI doesn’t support any of these, neither JBoss Seam. Both CDI and Google Guice support them.

Injection of external resources

Sometimes, you need to inject things you don’t have control of. For example, DataSources, 3rd party libraries, JNDI resources, etc. OurDI doesn’t support this. JBoss Seam supports it with factories and manager components, Google Guice supports it with provider methods and CDI supports it with producer methods and fields.

Scopes

Scopes, also known as Contexts, are a fundamental part of development. They allow you to define different lifecycles for each object (i.e. request, session, or application). OurDI doesn’t support scopes. However, Google Guice, JBoss Seam and CDI, all support scopes in one way or another. You can read more about scopes and their importance on this post.

You can also check the documentation of scopes for each framework/specification: Google Guice, JBoss Seam and CDI.

Static vs. Dynamic Injection

In OurDI, every time a method is called, it will scan the object to find dependencies that need to be injected. This is called Dynamic Injection and is how JBoss Seam works. The advantage of dynamic injection is that if a dependent object is changed, the new object will be injected in the next method call, so, you’ll always end up with the “correct” instance.

Google Guice and CDI uses Static Injection, which means that injection will only occur once after the object is created. The problem here, as stated above, is that if a dependent object is changed, you will still have the reference to the old object. CDI solves this problem by using proxies that will always point to the correct instance. So, even though it uses static injection (the field is injected only once), it works like dynamic injection.

Lazy Loading of objects

In OurDI, you will need to instantiate all the classes that need to be injected on startup. This is definitely not a good idea as you are loading things in memory that you are not still using. Google Guice, JBoss Seam and CDI all use a lazy loading approach where the objects will be loaded only when needed, which is a good thing.

Aspect Oriented Programming

Most DI frameworks provide some type of method interceptor mechanism that simplifies AOP development, usually with annotations. This is another feature that OurDI lacks! However, Google Guice, JBoss Seam and CDI, all support this feature with a very similar approach.

Integration

Integration with other environments is really simple with OurDI and Google Guice. You just need to configure the Injector on startup and that’s it. JBoss Seam is a complete development platform that integrates multiple technologies and it would be almost impossible to integrate it on a different environment different from JEE. CDI is part of the JEE 6 stack, however, implementations like Weld can run on different environments with the appropriate hookups. 

Conclusion

Ok, let’s face it. Our own DI framework sucks!:

  • It doesn’t support constructor or method injection (or provide an alternate solution).
  • It doesn’t support injection of external resources.
  • It needs all classes to be instantiated on startup.
  • It doesn’t support scopes. 
  • It doesn’t provides a method interceptor mechanism.

However, I hope OurDI was useful enough to compare different DI frameworks. We only talked about Google Guice, JBoss Seam and CDI, but you can do the exercise with any other DI framework out there.

Sunday, January 17, 2010

From JBoss Seam to CDI (JEE6)

Seam is a popular open source application framework that has led to the creation of CDI (Contexts and Dependency Injection), a specification that is now part of the JEE 6 ecosystem. In this post I’ll show you the architectural similarities and differences between both and how Seam has influenced CDI. So lets start!

Contexts

Contexts are definitely one of the most exciting features of Seam (you can read more about them in this post) and remain in the core of CDI.  Seam defines six stateful contexts: request (event), session, application, page, conversation and business process context. CDI only define 4, leaving page and business process contexts out. However, CDI allows you to define new contexts which was not possible in Seam. You can see an example of creating a context (the equivalent of the page context in Seam) by Steven Verborgh here.

Additionally, CDI now defines a new “dependent” context which allows a bean to have the same context as the bean that declares it. They will share the same lifecycle meaning that “it [the dependent bean] is instantiated when the object it belongs to is created and destroyed when the object it belongs is destroyed”, as stated in the Weld documentation.

Dependency Injection

Even though Seam and CDI both make heavy use of the Dependecy Injection pattern, they take different approaches to implement it. The most notable differences are the following (I’ll explain each one in more detail below):

  • Seam uses a string-based approach to search for components which is not type safe while CDI brings type safety to the limit.
  • Seam uses dynamic injection while CDI uses static injection.

Type safety

In Seam, every component has a name defined by the @Name annotation. When an injection occurs, Seam searches for the name of the component which can lead to runtime exceptions. For example, suppose you have the following component:

@Name("myBean")
public class MyBean {
 ...
}

Now, suppose you mistakenly inject MyBean into a String like this:

@In
private String myBean;

This will compile just fine, but at runtime you will get an exception. In large applications, this is a problem as you will potentially have a lot of bugs at runtime, something you really want to avoid.

CDI implements dependency injection based on the type of the bean like in Google Guice. There is no need to name a bean unless you want to access it from EL, in which case, you will need to annotate your bean with the @Named annotation. Lets look at a simple case of injection in CDI:

public class Bean1 {
 ...
}

public class Bean2 {
 @Inject
 private Bean1 bean1;
 ...
}

When Bean2 gets instantiated, Bean1 will be injected on Bean2. As you can see, there is no need to name the beans.

Static vs. Dynamic Injection

In Seam, injection occurs on each method call. After the method completes, all injected values are desinjected (set to null). This is known as dynamic injection and it has its benefits and drawbacks. The most outstanding benefit is that you can inject components from different contexts (i.e. a request component injected in a conversation component)  and you will always have the “correct” instance on each method call. However, dynamic injection has some problems including performance and null values on concurrency.

CDI uses static injection, meaning that all the values are injected on the creation of the bean and they are not desinjected between method calls. To handle injection of beans from different contexts, it uses proxies that reference the “correct” instance of each bean. A much more elegant solution in my opinion.

Factories

Remember the @Factory annotation in Seam? It allows you to obtain objects that are not Seam components; or it could also be used when you need to perform some custom initialization on a component before returning it. In CDI, there is an equivalent functionality called “producer method”:

@Produces
public User getUser {
      ...
}

Every time a User object is injected, this method will be called to obtain a reference. CDI provides a simpler alternative to a producer method called a producer field:

@Produces
private User user;

Events

In Seam, you can decouple your components using events. Each event must have a name. You can raise an event using the @Raise(“<name_of_event>”) annotation or programmatically using the Events.instance().raiseEvent(“<name_of_event>”) method. To observe for an event, you mark the method you want to be called on the event with the @Observer(“<name_of_event>”) annotation.

CDI grabs this concept from Seam and makes it type safe. So, for raising an event we can obtain an Event object by injection:

@Inject
private Event<User> userEvent;

And then call the fire method on the Event object:

userEvent.fire(user);

Now, for observing an event you use the @Observes annotation:

public void observeUserEvent(@Observes User user) {
 ...
}

Interceptors

Seam relies heavily on interceptors for injection, security, persistence and much more. CDI also provides an interception facility called interceptors bindings, based on the Java Interceptors specification. Furthermore, CDI provides the concept of “decorator”, which is a kind of interceptor for implementing the decorator pattern.

Wrapping up

Let’s take a look at the services provided by CDI and see if they were inspired by Seam:

  • Contexts: heavily inspired by Seam.
  • Dependency Injection: mostly inspired by Google Guice but we have an equivalent in Seam (which is not type safe).
  • EL integration (the #{} notation): completely inspired by Seam.
  • Interceptors: completely inspired by Seam.
  • Events: heavily inspired by Seam but type safe.

Wait a minute! Are these all the services provided by CDI? What about all the out-of-the-box functionality I used to have in Seam (page flows, business process integration, security, scheduling, caching, remoting, etc.)? Don’t worry! Portable Extensions, the only service we are missing in this list, will solve this question, so just keep reading!

Portable Extensions and Seam 3

Besides the services described above, CDI provides a powerful SPI (Service Provider Interface) you can use to create extensions (called Portable Extensions in CDI). This is where Seam 3 enters the game!

Seam 3 will be a set of portable extensions that will provide almost all of the out-of-the-box functionality you actually have in Seam 2. At the time of this writing, Seam 3 is on its first steps and there is no official release yet. However, you can start developing your own portable extensions on top of CDI. Take a look at this post by Matt Corey to start writing your own first portable extension!

Conclusion

CDI has been heavily influenced by Seam with two major architectural changes:

  • Instead of providing everything out-of-the-box as Seam, CDI provides a set of core technologies and a powerful SPI that will enable any one write its own portable extensions.
  • Type safety. This was included in every aspect of CDI (Contexts, DI and events), except for the EL integration.

Remember that Seam is a framework and CDI is a specification (Weld is the Reference Implementation). For more information on CDI, check the Weld documentation and the CDI specification.

Saturday, December 5, 2009

EJB’s: Time to let them go?

If you are a JEE developer, you may already be familiar with the benefits of using EJB’s (Enterprise Java Beans) instead of POJO’s (Plain Old Java Objects) in your applications. The list includes, but is not limited to:
  • Transaction management.
  • Scalability – you can distribute your application across multiple machines.
  • Lifecycle management.
  • Security management.
  • Dependency Injection.

EJB’s have been with us for a long time and have certainly evolve in the right direction. From the cumbersome EJB 2.x specification with all those interfaces, a very verbose XML definition and an over-designed Entity Beans, to a more convenient EJB 3.0 spec which uses annotations and better persistence management with the introduction of JPA (Java Persistence API).  The new EJB 3.1 spec even gets simpler with no need of the Local interface and the possibility to run inside a Servlet Container.

On the other hand, we have initiatives like Spring and JBoss Seam that try to bring the benefits of the EJB’s to POJO’s. They have been very successful in this task and are being widely adopted. In fact, the reason EJB’s are getting much more simpler lies in the success of these frameworks. The idea behind them is very easy to understand: use annotations inside your POJO’s when you want the benefits of EJB’s and we will use AOP (Aspect Oriented Programming) to deliver that functionality.

They even go further and bind each object to a scope. So, for example, you may want an object to last through the duration of a request or through the whole session of the user. I will not get into the details of this powerful feature but you can read more in this post where I explain how this works in JBoss Seam.

As you can see, there are two approaches to achieve the same goal. The top-down approach is used by the JCP (Java Community Process) expert group to make EJB’s simpler and the bottom-up approach used by frameworks like Spring and JBoss Seam to empower simple POJO’s with enterprise services.

We still need the standards!

Standards are good. They allow us as developers to focus on what we have to learn, facilitates the technology selection process, promotes vendor independence and are easily accepted by the executive team in companies, among other benefits.

There have been some efforts to standardize some of the bottom-up approaches. The JSR-299 (Context and Dependency Injection) is one of these efforts leaded by the Seam group which has been approved by the JCP. With JSR-299 you could have POJO’s that behave like EJB’s with dependency injection support and scope demarcation (contexts). So the question is: do we still need EJB’s?

Well, the answer is we do. Unfortunately, the JCP group wants to keep the EJB specification and the JSR-299 group had to make the concept of component (called bean in the JSR-299) more abstract to support EJB’s. I think is confusing and not good for the Java community. While other languages are moving to the KISS (keep it simple, stupid!) principle, we are making things more confusing to developers. With JSR-299, you will be able to work with or without EJB’s. The only benefit of using EJB’s will be the clustered services and JMS but that is something that could have been added to the JSR-299 component model.

Conclusion

I don’t think it’s healthy to continue changing the EJB specification to adapt it to a new simpler model. The JCP group should really let them go, create a unified component model based on POJO’s and add it to the JSR-299. We really need to keep it that simple ;)

K6QA68WYDWM2