EJB 3.0

Sang Shin, sang.shin@sun.com, www.javapassion.com/j2ee



Java Platform, Enterprise Edition 5 (Java EE 5) focuses on making development easier, yet retains the richness of the J2EE 1.4 platform. Offering new and updated features such as Enterprise JavaBeans (EJB) Technology 3.0, JavaServer Faces (JSF) Technology, and the latest web services APIs, Java EE 5 makes coding simpler and more straightforward, but maintains the power that has established Java EE as the premier platform for web services and enterprise application development.

This hands-on lab takes you through the basic features of EJB 3.0. 


Expected duration: 90 minutes


Software Needed

Before you begin, you need to install the following software on your computer. 


Change Log


Things to do (by Sang Shin)


Lab Exercises



Exercise 1: Build EJB 3.0 Application using Annotations


In this exercise, you are going to build a simple HelloWorld EJB application in which a stateless session bean is created and accessed from web tier servlet.
  1. Create a stateless session bean
  2. Create a servlet that accesses the stateless session bean
  3. Build and run the project

(1.1) Create a stateless session bean


In this step, you are going to create a stateless session bean using @Stateless annotation.

1. Create a new NetBeans project

Figure-1.10: Create Enterprise Application project


Figure-1.11: Give project name EJBDemo

Figure-1.12: EJBDemo project is created

2. Create a session bean

Figure-1.13: Create session bean

Figure-1.14: MySesssionBean is created

3. Study the files that have been ceated.


3. Add a business method - sayHello(String name) - to the MySessionBean.

Figure-1.15: Add a business method to the bean

Figure-1.16: Add Business Method dialog box

Figure-1.17: Enter Method Parameter
package mypackage;

import javax.ejb.Stateless;

/**
 *
 * @author sang
 */
@Stateless
public class MySessionBean implements MySessionLocal {

    public String sayHello(String name) {
        return "Hello " + name + "!";
    }

}
Code-1.18: Modified MySessionBean.java



                                                                                                                    return to the top of the exercise


(1.2) Create a servlet that accessed the stateless session bean


1. Create a servlet.

Figure-1.20: Choose File Type

Figure-1.21: Name the Location pane

Figure-1.22: Configure Servlet Deployment pane

2. Add code to the servlet that accesses the stateless session bean leveraging NetBeans code generating wizard.

Figure-1.23: Call Enterprise Bean

Figure-1.24: Call Enterprise Bean

Figure-1.25: Observe dependency injection

package mypackage;

import java.io.IOException;
import java.io.PrintWriter;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 *
 * @author sang
 */
public class MyServlet extends HttpServlet {
    @EJB
    private MySessionLocal mySessionBean;
  
    /**
    * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
    * @param request servlet request
    * @param response servlet response
    */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
       
        try {
            // TODO output your page here - start of the uncommented section
            out.println("<html>");
            out.println("<head>");
            out.println("<title>Servlet MyServlet</title>"); 
            out.println("</head>");
            out.println("<body>");
            //out.println("<h1>Servlet MyServlet at " + request.getContextPath () + "</h1>");
            out.println("<h1>Returned string from Session bean is " + mySessionBean.sayHello("Sang Shin")  + "</h1>");
            out.println("</body>");
            out.println("</html>");
            // end of the uncommented section
        } finally {
            out.close();
        }
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /**
    * Handles the HTTP <code>GET</code> method.
    * @param request servlet request
    * @param response servlet response
    */
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
    * Handles the HTTP <code>POST</code> method.
    * @param request servlet request
    * @param response servlet response
    */
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
    * Returns a short description of the servlet.
    */
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>

}
Code-1.26: Modified MyServlet.java




                                                                                                                    return to the top of the exercise

(1.3) Build and run the project


1. Set the Relative URL of the project (so that when you run the project, the URL is accessed by the browser)


Figure-1.27: Set the Relative URL

2. Build and run the project

Figure-1.28: Result of running the project

                                                                                                                    return to the top of the exercise

Solution


The solution to this exercise is provided as a ready-to-open-and-run NetBeans project as part of hands-on lab zip file.  You can just open it and run it.  If you are experiencing a problem and the problem is not obvious to find while doing this exercise, please open and run the EJBDemo project and see how it behaves. 

Summary

In this exercise,  you have learned how to create a session bean from a POJO class by adding @Stateless annotation.  You also learned how a session bean is dependency injected through @EJB annotation in the client code. 

                                                                                                                        return to the top


Exercise 2: Build and run "Interceptor Stateless" sample application


In this exercise, you are going to build a Interceptor Stateless sample application that comes with NetBeans.  This application has a simple EJB 3.0 Stateless Session Bean with a remote business interface that uses EJB 3.0 interceptor mechanism to validate the parameter passed to a business method.
  1. Create a new project
  2. Build and run the project
  3. Look under the hood ofthe application

(2.1) Create a new sample project


1. Create a new NetBeans project

Figure-2.10: Interceptor Stateless

Figure-2.11: Name and Location

(2.2) Build and run the project


1. Right click InterceptorStateless project node and select Run. (Figure-2.21 below)


Figure-2.21: Build and run the project

2. Observe the result. (Figure-2.22 and Figure-2.23 below)

Converted duke to Duke
Cannot convert (BadArgument) duke
Cannot convert (BadArgument)null
Cannot convert (BadArgument) duke
Cannot convert (BadArgument)4duke
Converted Duke to Duke
Figure-2.22: Result


Figure-2.23: Result

(2.3) Look under the hood of the application


1. Open StatelessSessionBean.java

package enterprise.interceptor_stateless_ejb;

import javax.ejb.Stateless;
import javax.interceptor.Interceptors;

// This bean uses two interceptors to validate
// the input to its (only) business method.
// Note that a single interceptor would suffice
// but to demonstrate the use of interceptor
// chaining, we use two interceptors

@Stateless
@Interceptors( { NullChecker.class, ArgumentsChecker.class })
public class StatelessSessionBean
    implements StatelessSession {

    // This business method is called after
    // the above two interceptor's @AroundInvoke
    // methods are invoked. Hence it is guaranteed
    // that the argument to this method is not null
    // and it starts with a letter
    public String initUpperCase(String val) {
        String first = val.substring(0, 1);
        return first.toUpperCase() + val.substring(1);
    }

}

2. NullChecker.java

package enterprise.interceptor_stateless_ejb;

import java.lang.reflect.Method;

import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;

public class NullChecker {

    @AroundInvoke
    public Object checkIfNull(InvocationContext ctx)
        throws Exception {
        Method method = ctx.getMethod();
        if (method.getName().equals("initUpperCase")) {
            String param = (String) (ctx.getParameters()[0]);
            if (param == null) {
                // An interceptor can throw any runtime exception or
                // application exceptions that are allowed in the
                // throws clause of the business method
                throw new BadArgumentException("Illegal argument: null");
            }
        }

        // Proceed to the next interceptor
        return ctx.proceed();
    }

}

3. ArgumentChecker.java

package enterprise.interceptor_stateless_ejb;

import java.lang.reflect.Method;

import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;

public class ArgumentsChecker {

    @AroundInvoke
    public Object checkArgument(InvocationContext ctx) throws Exception {
        Method method = ctx.getMethod();
        if (method.getName().equals("initUpperCase")) {
            String param = (String) (ctx.getParameters()[0]);
            // Note that param cannot be null because
            // it has been validated by the previous interceptor
            char c = param.charAt(0);
            if (!Character.isLetter(c)) {
                // An interceptor can throw any runtime exception or
                // application exceptions that are allowed in the
                // throws clause of the business method
                throw new BadArgumentException("Illegal argument: " + param);
            }
        }

        // Proceed to call the business method
        return ctx.proceed();
    }

}


Exercise 3: Build and run "Annotation Lottery" sample application


In this exercise, you are going to build a simple application that uses Java EE 5 annotation facility.
  1. Create a new sample project
  2. Build and run the project
  3. Look under the hood of the application

(3.1) Create a new sample project


1. Create a new NetBeans project


(3.2) Build and run the project


1. Right click LotteryAnnotation project node and select Run.










(3.3) Look under the hood of the application


1. LotteryBean.java under LotteryAnnotation-ejb->Source Packages->enterprise.lottery_annotation_ejb_stateful.



package enterprise.lottery_annotation_ejb_stateful;


import javax.ejb.EJB;
import javax.ejb.Stateful;

import enterprise.lottery_annotation_ejb_stateless.Date;


@Stateful
public class LotteryBean implements Lottery {

    public String getName() {
        return name;
    }

    public String getNumber() {
        return number;
    }

    public String getDate() {
        return date.today();
    }

    public void select(int number) {
        if( (number > -1) && (number < 10) ) {
            this.number = this.number + SPACE +
                java.lang.Integer.toString(number);
    }
    }

    public void setName(String name) {
     this.name = name;
    }


    //Dependency injection to get an instance of the Date EJB.
    @EJB(name="Date")
    private Date date;

    private String name = "Super Lotto";
    private String number = "";
    private static final String SPACE = " ";
}

2. Lottery.java

package enterprise.lottery_annotation_ejb_stateful;

import javax.ejb.Remote;

@Remote
public interface Lottery {

    public String getName();
    public String getNumber();
    public String getDate();

    public void select(int number);
    public void setName(String name);
}




Homework Exercise (for people who are taking Sang Shin's "Java EE Programming online course")


1. The homework is to create a new NetBeans project as described below.  (You can name the homework project in any way you want but here I am going to call it MyEJB30.)
public int addNumber(int x, int y){
      return (x+y);
}
2. Send the following files to j2eehomeworks@sun.com with Subject as J2EEHomework-javaee5ejb30.