EJB
3.0
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.
- Java Standard Development Kit (JDK™) version
6.0 (download)
- If you already have installed JDK 5.0 or JDK 6.0, you
can skip this.
- NetBeans IDE 6.1 (download)
- When you install NetBeans IDE, it will ask you which JDK
you want to use.
- 3400_javaee5ejb30.zip (download)
- It contains this document and the lab contents
- Download it and unzip in a directory of your choice
Change Log
- Jan. 12th, 2007: Cosmetic changes are made
- Dec. 7th, 2007: EJB 3.0 contents is separated out from J2EE 5
Basics contents
- Jan. 10th, 2008: Exercise 2 is added
- Aug. 7th, 2008: NetBeans 6.1 and GlassFish v2 are used, Exercise
3 is added
Things to do (by Sang Shin)
Lab Exercises
Exercise 1: Build EJB 3.0 Application
using Annotations
(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
- Select File->New Project (Ctrl+Shift+N). The New Project dialog box appears.
- Under Choose Project
pane,
select Enterprise under Categories and Enterprise
Application under Projects.
- Click Next. (Figure-1.10
below)

Figure-1.10: Create Enterprise Application project
- Observe that the Name and Location pane appears.
- For the Project Name
field, type in EJBDemo as
project name.
- Click Next.
- Observe that the Server and Settings pane appears.
- Accept other default values.
(Figure-1.11
below)
- Click Finish.

Figure-1.11: Give project name EJBDemo
- Observe that EJBDemo project
appears.
- Observe that EJBDemo-ejb
module and EJBDemo-war module
also appear. (Figure-1.12 below)

Figure-1.12: EJBDemo project is created
2. Create a session bean
- Right click EJBDemo-ejb
and select New->Session Bean.

Figure-1.13: Create session bean
- Observe that the Name and
Location pane gets displayed.
- For the EJB Name field,
type in MySession.
- For the Package field,
type in mypackage.
- Select both Remote and Local for Create Interface option.
- Click Finish.
(Fugure-2.14 below)

Figure-1.14: MySesssionBean is created
3. Study the files that have been ceated.
- Expand EJBDemo-ejb->Source
Packages->mypackage (if it has not been done already).
- Observe that three Java source files - MySessionBean.java, MySessionLocal.java, and MySessionRemote.java - are created
and the MySessionBean.java
file is displayed in the source editor.
- Observe that the MySessionBean
class implements MySessionRemote and MySessionLocal Java
interfaces.
- Observe @Stateless
annotation is added to the MySessionBean
class.
3. Add a business method -
sayHello(String name) - to the
MySessionBean.
- Right click any point in the MySessionBean.java
and select EJB Methods->Add
Business Method. (Figure-1.15 below)

Figure-1.15: Add a business method to the bean
- Observe that Add Business Method
dialog box appears.
- For the Name field,
type in sayHello.
- For the Return Type field, type in String. (Figure-1.16 below)
- Click Add to add input
parameter.

Figure-1.16: Add Business Method dialog box
- For the Name field, type
in name.
- Click OK. (Figure-1.17
below)

Figure-1.17: Enter Method Parameter
- Observe that sayHello(String
name) method is added to the MySessionBean.java.
- Modify the sayHello(String name)
method as shown in Code-1.18
below. The code fragment that needs to be changed is highlighted
in bold and
blue-colored font.
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
- You might encouter some complie error conditions. If you
see them click Save All button.
- Observe that the compile errors are gone.
return to the top of the
exercise
(1.2)
Create a servlet that accessed the stateless session bean
1. Create a servlet.
- Right click EJBDemo-war
and select New->Servlet.

Figure-1.20: Choose File Type
- Observe that the Name and
Location pane gets displayed.
- For the Class Name
field,
type in MyServlet.
- For the Package field,
type in mypackage.
(Fugure-2.21 below)
- Click Next.

Figure-1.21: Name the Location pane
- Observe that Configure Servlet
Deployment pane appears.
- Accept the default values given in the Servlet Name and URL Pattern(s) fields and click Finish. (Figure-1.22 below)

Figure-1.22: Configure Servlet Deployment pane
2. Add code to the servlet that
accesses the stateless session bean leveraging NetBeans code generating
wizard.
- Add a blank line at line number 30 in the IDE generated MyServlet.java.
- Right click on the newly created blank line and select Enterprise
Resources->Call Enterprise
Bean. (Figure-1.23 below)

Figure-1.23: Call Enterprise Bean
- Observe that the Call
Enterprise Bean dialog box appears.
- Select MySessionBean.
- Click OK. (Figure-1.24
below)

Figure-1.24: Call Enterprise Bean
- Observe that dependency injection statement of stateless session
bean is added to the code through @EJB
annotation to the mySessionBean.
(Figure-1.25 below) Now you can access the stateless
session bean through mySessionBean
variable.

Figure-1.25: Observe dependency injection
- Modify the MyServlet.java
as shown in Code-1.26 below. The modification is to add code that
access the bean through mySessionBean
variable. The
code fragments that need to be
added are highlighted in bold and blue
colored font.
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)
- Right click EJBDemo project
and select Properties.
- Observe Project Properties - EJBDemo dialog box appears.
- Select Run under Categories on the left.
- For the Relative URL
field, type in /MyServlet.
(Figure-1.27 below)
- Click OK.

Figure-1.27: Set the Relative URL
2. Build and run the project
- Right click EJBDemo project
node and select Run Project.
- Observe that browser gets displayed with Returned string from Session bean is Hello
Sang Shin!.
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.
- You can find it
under <LAB_UNZIPPED_DIRECTORY>/javaee5ejb30/solutions/EJBDemo.
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.
Exercise 2: Build and run "Interceptor
Stateless" sample application
(2.1)
Create a new sample project
1. Create a new NetBeans project
- Select File->New Project (Ctrl+Shift+N). The New Project dialog box appears.
- Under Choose Project
pane,
expand Samples and select Enterprise under Categories and Interceptor
Stateless under Projects.
- Click Next. (Figure-2.10
below)

Figure-2.10: Interceptor Stateless
- Click Finish.
(Figure-2.11 below)

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
(3.1)
Create a new sample project
1. Create a new NetBeans project
- Select File->New Project (Ctrl+Shift+N). The New Project dialog box appears.
- Under Choose Project
pane,
expand Samples and select Enterprise under Categories and Lottery Annotation
under Projects.
- Click Next. (Figure-2.10
below)
(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.)
- Create a Stateless session bean called MyOwnEJB30SessionBean.
- The MyOwnEJB30SessionBean has the following method
public int addNumber(int x, int
y){
return (x+y);
}
|
- Create a servlet in which the addNumber() method above is invoked
2
. Send the following files to
j2eehomeworks@sun.com
with Subject
as J2EEHomework-javaee5ejb30.
- Zip file of the the MyEJB30
NetBeans project. (Someone else
should be able to open and run it as a NetBeans project.) You can
use your favorite zip utility or you can use "jar" utility that comes
with JDK as following.
- cd <parent directory that contains MyEJB30 directory>
(assuming you named your project as MyEJB30)
- jar cvf MyEJB30.zip MyEJB30 (MyEJB30
should
contain nbproject directory)
- Captured output screen -
name it as J2EEHomework-javaee5ejb30.gif
orJ2EEHomework-javaee5ejb30.jpg (or J2EEHomework-javaee5ejb30.<whatver
graphics format>)
- Any screen capture that shows that your program is working is
good enough.
- If you decide to use
different IDE other than NetBeans, the zip
file should contain all the files that are needed for rebuilding the
project - war file with necessary source files is OK.