Wednesday, September 29, 2010

JDK 1.5 Features:


· Generics—Provides compile-time type safety for collections and eliminates the need for casting every time you get an object out of Collections.

· Enhanced For loop—Eliminates error-proneness of iterators.

· Autoboxing/unboxing—Eliminates need of manual conversion between primitive types (such as double) and wrapper types (such as Double).

· Typesafe enumsProvides all benefits of the Typesafe enum pattern.

· Static import—Eliminates the need for using class names prior to using the static member variables of other classes. This will make the code a bit neater.

· Metadata—Allows programmers to avoid writing boiler plate code and gives the opportunity for declarative programming.


Let's discuss each feature in detail and take a look at some examples.

Generics
Generics is one of the coolest features of JDK 1.5. By introducing generics, we will have compile-time type safety and possibly fewer ClassCastExceptions during run time. In JDK 1.5, you can declare the type of objects one collection will accept/return. In JDK 1.4, creating a List of employee names requires a collection object like the following statement:
List listOfEmployeeName = new ArrayList();

In JDK 1.5, you would use this statement:
List listOfEmployeeName = new ArrayList();

The cool part is that if you try to insert something that's not a string, you will find out at compile time and then you can fix the problem. Without generics, you discover such a bug when your customer calls and tells you that the program you shipped crashed with a ClassCastException.

The other cool thing is that you don't have to cast when you get an element out of the collection. So instead of this type of statement:
String employeeName = ((String) listOfEmployee.get(i));

It's simply:
String employeeName = listOfEmployee.get(i);

Casting objects without knowing the type of object is not good, and more importantly, it can fail at run time. Suppose the user accidentally passes in a collection that contains string buffers rather than strings.


Now it's clear from the method signature that the input collection must contain only strings. If the client tries to pass in a collection of string buffers, the program won't compile. And notice that the method doesn't contain any casts. It's one line shorter and, once you get used to reading generics, it's clearer too.

Enhanced For Loop
Here's the syntax for the For loop in the current version of the JDK:
void printAll(Collection c) {
for (Iterator i = c.iterator(); i.hasNext(); ) {
Employee emp = (Employee)i.next();
System.out.println(emp.getName());
}
}

Now here's the same method with an enhanced For statement:
void printAll(Collection c) {
for (Object o : c)
System.out.println((TimerTask)o).getName());
}

In this For loop, you should read the ":" as "in," so the example reads "for Object o in c". You can see this For loop has more readability.

Autoboxing and unboxing
In Java, we have primitive data types and wrapper classes around these primitive types. Most often programmers need to convert one type to another. Take a look at the following code.

int n=10;

Integer age= new Integer(30);

Integer ageAfterTenYear= new Integer(age.intValue +10);


Notice how messy the inner-loop code that calculates ageAfterTenYear looks. Now take a look at the same program rewritten with autoboxing, as shown

          int n=10;
         Integer age= new Integer(30);
         Integer ageAfterTenYear= age +10;

One thing worth noting: Previously, if you unboxed Null, it became zero. In this code, the compiler would automatically convert Integer to int and add 10 to it, then convert that back to Integer.

Typesafe enums
Typesafe enums provide the following features:

· They provide compile-time type safety.

· They are objects, so you can put them in collections.

· They are implemented as a class, so you can add some methods.

· They provide a proper name space for the enumerated type.

· Their printed values are informative—if you print an int enum, you just see a number, which may not be that informative.


Example 1:
enum Season { winter, spring, summer, fall }

Example 2:
public enum Coin {
penny(1), nickel(5), dime(10), quarter(25);
Coin(int value) { this.value = value; }
private final int value;
public int value() { return value; }
}

Static imports
Static imports make code more readable. Currently, you use constants defined in other classes, like this:
import org.yyy.pkg.Increment;

class Employee {
public Double calculateSalary(Double salary{
return salary + Increment.INCREMENT * salary;
}
}

But with static import, we can use those constants without providing the name of the class prior to constant name, like this:
import static org.yyy.pkg.Increment;

class Employee {
public Double calculateSalary(Double salary{
return salary + INCREMENT * salary;
}
}

Note that we are able to call the INCREMENT constant without using the class nameIncrement.

Metadata
The metadata feature is focused on making a developer's life simpler with the support of tools provided by vendors. Take a look at the following code

public interface EmployeeI extends Java.rmi.Remote {

public String getName() throws Java.rmi.RemoteException;

public String getLocation () throws Java.rmi.RemoteException;

}

With metadata support, you can write the code in Listing E like this:
import org.yyy.hr;

public class Employee {
@Remote public String getName() {
...
}
@Remote public public String getLocation() {
...
}
}

As you can see, all the boilerplate's code is gone.

Friday, August 27, 2010

How to create a Message Driven Bean in EJB 3 (Step by Step). Using RAD 7.5 and Websphere 7.0


In an enterprise application it is common to use asynchronous messaging. It is useful when you have to deliver a message (even if the destination is down) and you do not wait for a response in real time. In Java, we’ve got the JMS (Java Messaging Service) to work with asynchronous messaging.

JMS belongs to the Java Enterprise Platform since previous EJB version, however in EJB 3, the process to create a JMS component is much easier.

Basically, we can create a JMS component using the annotation @MessageDriven and also implementing the interface java.jms.MessageListener.

Although Message Driven Beans are simple to be created in EJB3, you should not use it for ALL situations. You should not use Message components when you need:

  • Real time response
  • The order of the requests are important
  • You need a synchronous request/response

Downloading Rational Application Developer 7.5 - Open Beta

In this article, we’re going to use the newest Rational Application Developer 7.5 - Open Beta. You can download it directly from its official website.

We’re going to use that version because RAD 7.5 has support for EJB3 component, as long as the RAD 7.0 (stable version) has not. However, you can test your JMS component in RAD 7.0 as well, but you will have to create the configuration file (.xmi) yourself manually.

Creating an Enterprise Application Project into RAD 7.5

Open the RAD 7.5 and go to the Java EE Perspective. Now, open the menu File -> New -> Enterprise Application Project. On the first screen, put the EAR project, in my case I’ve used TestJMS and click on Next.

On the next screen, check in the Generate Deployment Descriptor and click on New Module button. Check out theApplication client module and Connector Module. Hence we’re going to use only the EJB module and Web module. Click on Finish button and the EAR project, as well as the EJB and Web module are going to be created.

Creating the Message Driven Bean component

Let’s create our Message Driven Bean component using the @MessageDriven annotation. For a simple example, let’s create a single method that prints out a message on the screen coming from the client.

RAD 7.5 brings a wizard to create the MDB, so let’s use it.

Right mouse click on the TestJMSEJB -> New -> Message-Driven Bean. On the screen that will come up, fill up theJava Package, Class Name, Destination name, JMS and Destination type.

Click on Finish button and the Message Driven Bean will be created into jms package. Also, implement the method onMessage() like below:

import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
@MessageDriven(activationConfig = { 
@ActivationConfigProperty(propertyName = "destinationType",          
 propertyValue = "javax.jms.Queue" ) },
 mappedName = "jms/messageQueue" )
public class ConsumerBean implements MessageListener {
    public void onMessage(Message message) {
 if (message instanceof TextMessage) {
            TextMessage text = (TextMessage) message;
           try {
                System.out.println(text.getText());
            } catch (JMSException e) {
                e.printStackTrace();
         }
        }
    }

}


As you can see, the code is really simple. Test if the object is a javax.jms.TextMessage, if so, prints out its content.

It’s done, our Message Driven Bean component has been created and implemented, simple huh? Now, it is time to configure the JMS Provider into Websphere. Also, we need to setup the destination of the message.

Setting up the JMS Provider and the Destination

It’s time to setup the configuration from the server side. This setup is made only once and usually it is responsability from EJB Deployer.

Certainly, the most famous JMS Provider is the IBM MQ Series, however for this example, we’re going to use a simplest JMS Provider. Websphere Application Server 6.1 brings an own JMS Provider itself, let’s use it.

Creating the Service Integration BUS (SIB)

Run the Websphere Application Server (you can do that through the Server Perspective, right click on WAS -> Start) and open its Administrative Console (right click on WAS -> Administration -> Run Administrative console). There, go to the MENU Service Integration and click on Buses.

  • On the buses screen, click on New button.
  • Next, insert the name MDBBus and then click Next and Finish.
  • Back to the Buses screen, click on Save link and then the MDBus will be created and committed.

Now, click on MDBBus link to open a new screen.

We’re going to use the three links on the right side. The first one is the Bus Member. Click on it.

On the next screen, click on Add button. Choose the first option Server.

  • Click on Next
  • choose File store and Next again.
  • On third screen, change the values: Log size: 10, Minimum permanent store size: 20, Maximum permanent store size: 50,
  • Click on Next button, Finish and Save link.

Now, let’s create the Destionations. Go back to the MDBBus screen and click on Destinations link.

  • Click on New button
  • Select Queue and click on Next
  • Enter: MDBQueue as Identifier. Also, click on Next.
  • Click on Next again.
  • Finally, click on Finish.

The SIB (Service Integration Buses) is created. The next step is to create the JMS Provider. Let’s do it.

Creating the JMS Provider

Go to the menu Resources -> JMS -> JMS Providers. On the center screen, click on Default messaging provider.

On the Default messaging provider screen, let’s create the Queue connection factory, Queue and the Activation Specification.

Creating the Queue Connection factory

Click on Queue Connection factories link. On the new screen, click on New button.

On the new screen, fill up the following fields:

  • Name (MDBQueueCF)
  • JNDI name (jms/messageCF)
  • Bus name (MDBBus)

Click on Ok button and then Save link.

Creating the Queue

Click on Queue link and then New button. On the new screen, fill up the following fields:

  • Name (MDBQueue)
  • JNDI name (jms/messageQueue)
  • Bus name (MDBBus)
  • Queue name (MDBQueue)

Click on Ok button and then Save link.

Creating the Activation specifications

Click on Activation specifications link and then click on New button.

On the new screen, fill up the following fields.

  • Name (MDBActivationSpec)
  • JNDI name (jms/activationSpec)
  • Destination type (Queue)
  • Destination JNDI name (jms/messageQueue)
  • Bus name (MDBBus)

Click on OK button and then Save link.

Both SIB and the JMS Provider were setup. Make sure to restart the Websphere server before continue this article.

Setting up the Websphere Deployment Descriptor (on EJB Project).

So far, we have created the Message Driven-Bean component, as well as the required configuration into Websphere Application Server. There is a simple setup yet. This setup will be made into Websphere Deployment Descriptor.

Right click on EJB Module (TestJMSEJB) and go to the option Java EE -> Generate Websphere Bindings Deployment Descriptor.

After this operation, a file called “ibm-ejb-jar-bnd.xml” will be created into ejbModulo/META-INF directory.

Double click on it to edit it. On the design section:

  • Click on Add button
  • Select Message Driven
  • Insert the name ConsumerBean
  • Select Message Driven and click on Add button again
  • Select JCA Adapter
  • Insert jms/activationSpec into Activation Spec Binding Name
  • Insert jms/messageQueue into Destination Binding Name.

The Websphere Deployment Descriptor setup is done. Let’s create the JMS client now.

Creating the Web Module to be the JMS Client

Now it is time to play around the Web Module we have created early.

The first think to do is to setup the Resources. To do that, double click on Deployment Descriptor.

On the new screen, go to the References tab. Click on Add button and follow the steps:

  • Select Resource reference.
  • Name: jms/messageQueueCF Type: javax.jms.QueueConnectionFactory Authentication: Container click on Okbutton.
  • JNDI name: jms/messageQueueCF.

Repeat the same process, but now using the following values:

  • Select Resource reference.
  • Name: jms/messageQueue Type: javax.jms.Queue Authentication: Container click on Ok button.
  • JNDI name: jms/messageQueue.

Creating the Servlet

Finally, let’s create a servlet that will be client of our example. Actually, the servlet will send out a text message to the JMS Provider. Our Message Driven-Bean will consume this message and print out into the console. See the servlet’s code below:

package servlets;

import java.io.IOException;

import javax.annotation.Resource;

import javax.jms.JMSException;

import javax.jms.MessageProducer;

import javax.jms.Queue;

import javax.jms.QueueConnection;

import javax.jms.QueueConnectionFactory;

import javax.jms.QueueSession;

import javax.jms.Session;

import javax.jms.TextMessage;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

public class JMSProducerServlet extends HttpServlet {

private static final long serialVersionUID = 1L;

@Resource(name="jms/messageQueueCF" )

private QueueConnectionFactory qcf;

@Resource(name="jms/messageQueue" )

private Queue queue;

/**

* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)

*/ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

try {

QueueConnection connection = qcf.createQueueConnection();

QueueSession session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);

MessageProducer producer = session.createProducer(queue);

TextMessage message = session.createTextMessage();

message.setText("#### JMS Example Running #####");

producer.send(message);

session.close();

connection.close();

} catch (JMSException e) {

e.printStackTrace();

}

}

}

There is nothing special in the code above. We injected both Queue Connection Factory and the Queue to our Servlet, we started a QueueSession and sent out the TextMessage.

To run this code, right click on Servlet and go to Run As -> Run on Server. Select Websphere 6.1 and the code will be performed.

Look at the Console view, because when Message Driven Bean consume the message, it will prints out the result on the console, like image below.