Sunday, November 7, 2010

Adding and injecting the EJB3 session bean

In the last post the managed bean was creating the data. As a good practice the get method should never ideally do load from database or do complex time consuming operations. Its time to move the data retrieval code to a session bean( subsequently use JPA) method. In Java EE 6 it is no longer required to put the ejbs in jar files with tons of deployment descriptors. The ear file is no longer mandatory in Java EE 6. You can put your EJBs in the same war file as the web components. Ah! life is so easy and simple.
The stateless session beans(SLSB) are POJOs and can be marked as SLSB with the @Stateless annotation. Things are even easier with EJB 3.1. You no longer require the business interface. Just a concrete class will do. Although program to interface is a great principle, but for simplicity, speed of development and ease of maintenance I will stick to the new ways. The purists may frown but I cannot think when I changed an implementation midway or in later stages of a project for whatever reason in my entire career. When we select a technology stack we need to build competency and stick to it rather than continuing to chop and change.
Listing 1 shows the simple stateless session bean.
Listing 1 – ProductService.java
package com.windowshop.business;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.ejb.Stateless;

import com.windowshop.domain.entities.Product;

/**
* @author Dhrubo
*
*/
@Stateless
public class ProductService {

public List getProductsByMonth(){
System.out.println("Hurray!!!!! SLSB called");
//TODO - use JPA to fetch from db
List products = new ArrayList();
Product product = null;
for(int i = 1 ; i <= 34; i++) {
product = new Product(i,"Abc",new Date(),"","",i+1.20d,"Rs");
products.add(product);
}

return products;
} 
}


Now that we have the SLSB, its time to refactor the managed bean - “move method” to the session bean. The “getProductsByMonth” will undergo few more rounds of refactoring in the future for sure. Listing 2 shows the modified managed bean.
package com.windowshop.web.controller;

import java.util.List;

import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import com.windowshop.business.ProductService;
import com.windowshop.domain.entities.Product;

/**
* @author Dhrubo
*
*/
@ManagedBean(name="productController")
public class ProductController {
@EJB 
ProductService productService;
public List getProductsByMonth(){
return productService.getProductsByMonth();
}
}

So we can see that the SLSB is injected into the managed bean using @EJB annotation. The getProductsByMonth method is slimmer as the call is dedicated now to the SLSB. You will need to add some dependencies to the pom.xml file. Listing 3 shows the modified pom.xml file.

Listing 3 – pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.windowshop</groupId>
<artifactId>shopweb</artifactId>
<packaging>war</packaging>
<version>1.0.0</version>
<name>shopweb Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
<scope>test</scope>
</dependency>
<!-- Prime faces , JSF -->

<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>2.2.RC1-SNAPSHOT</version>
<scope>runtime</scope>
<type>jar</type>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-api</artifactId>
<version>2.0.3</version>
<scope>provided</scope>
<type>jar</type>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-impl</artifactId>
<version>2.0.3</version>
<scope>provided</scope>
<type>jar</type>
</dependency>

<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.5</version>
<scope>runtime</scope>
<type>jar</type>
</dependency>

<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>6.0</version>
<scope>provided</scope>
</dependency>

</dependencies>
<repositories>
<repository>
<id>prime-repo</id>
<name>Prime Technology Maven Repository</name>
<url>http://repository.prime.com.tr/</url>
</repository>
<repository>
<id>maven2-repository.dev.java.net</id>
<name>Java.net Repository for Maven</name>
<url>http://download.java.net/maven/2/</url>
</repository>

</repositories>
<build>
<finalName>shopweb</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
</project>


This was the easiest SLSB based project I have ever done in my life. Java EE 6 has been a refreshing experience so far. I intend to get more into depth and try out Java EE 6 and possibly all its facets possible with JBOSS 6. Now if you deploy this project you will the following lines in your JBOSS console confirming the deployment of EJB, registration in JNDI. You can launch the browser and check if the landing page is working as before. I did not find any problem.

JBOSS6 console

17:05:39,480 WARN  [InterceptorInfoRepository] EJBTHREE-1852: InterceptorInfoRepository is deprecated
17:05:40,347 INFO  [JBossASKernel] Created KernelDeployment for: shopweb.war
17:05:40,352 INFO  [JBossASKernel] installing bean: jboss.j2ee:jar=shopweb.war,name=ProductService,service=EJB3
17:05:40,352 INFO  [JBossASKernel]   with dependencies:
17:05:40,352 INFO  [JBossASKernel]   and demands:
17:05:40,352 INFO  [JBossASKernel]     jboss.ejb:service=EJBTimerService; Required: Described
17:05:40,353 INFO  [JBossASKernel]   and supplies:
17:05:40,353 INFO  [JBossASKernel]     jndi:ProductService
17:05:40,353 INFO  [JBossASKernel]     jndi:ProductService/no-interface
17:05:40,354 INFO  [JBossASKernel] Added bean(jboss.j2ee:jar=shopweb.war,name=ProductService,service=EJB3) to KernelDeployment of: shopweb.war
17:05:50,041 INFO  [TomcatDeployment] deploy, ctxPath=/shopweb
17:05:50,237 INFO  [config] Initializing Mojarra 2.0.2 (FCS b10) for context '/shopweb'
17:05:54,557 INFO  [AbstractNoInterfaceViewJNDIBinder] Binding the following entry in Global JNDI:

    ProductService/no-interface - EJB3.1 no-interface view

17:05:54,561 INFO  [SessionSpecContainer] Starting jboss.j2ee:jar=shopweb.war,name=ProductService,service=EJB3
17:05:54,573 INFO  [EJBContainer] STARTED EJB: com.windowshop.business.ProductService ejbName: ProductService
17:05:54,579 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:

No comments:

Post a Comment