0% found this document useful (0 votes)
21 views31 pages

Aejp Unit Iii

Advanced enterprise java programming... Using buisness java.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
21 views31 pages

Aejp Unit Iii

Advanced enterprise java programming... Using buisness java.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 31

UNIT - III: ENTERPRISE JAVA BEANS

EJB: Session Bean, Entity Bean, Message driven

Session Bean

Session bean encapsulates business logic only, it can be invoked by local, remote and webservice client.

It can be used for calculations, database access etc.

The life cycle of session bean is maintained by the application server (EJB Container).

Types of Session Bean

There are 3 types of session bean.

1) Stateless Session Bean: It doesn't maintain state of a client between multiple method calls.

2) Stateful Session Bean: It maintains state of a client across multiple requests.

3) Singleton Session Bean: One instance per application, it is shared between clients and supports
concurrent access.

Stateless Session Bean

Stateless Session bean is a business object that represents business logic only. It doesn't have state
(data).

In other words, conversational state between multiple method calls is not maintained by the container in
case of stateless session bean.

The stateless bean objects are pooled by the EJB container to service the request on demand.

It can be accessed by one client at a time. In case of concurrent access, EJB container routes each request
to different instance.

Annotations used in Stateless Session Bean

There are 3 important annotations used in stateless session bean:

1. @Stateless
2. @PostConstruct
3. @PreDestroy

Life cycle of Stateless Session Bean

There is only two states of stateless session bean: does not exist and ready. It is explained by the figure
given below.
EJB Container creates and maintains a pool of session bean first. It injects the dependency if then calls the
@PostConstruct method if any. Now actual business logic method is invoked by the client. Then,
container calls @PreDestory method if any. Now bean is ready for garbage collection.

Example of Stateless Session Bean

To develop stateless bean application, we are going to use Eclipse IDE and glassfish 3 server.

To create EJB application, you need to create bean component and bean client.

1) Create stateless bean component

To create the stateless bean component, you need to create a remote interface and a bean class.

File: AdderImplRemote.java

1. package com.javatpoint;
2. import javax.ejb.Remote;
3.
4. @Remote
5. public interface AdderImplRemote {
6. int add(int a,int b);
7. }

File: AdderImpl.java

1. package com.javatpoint;
2. import javax.ejb.Stateless;
3.
4. @Stateless(mappedName="st1")
5. public class AdderImpl implements AdderImplRemote {
6. public int add(int a,int b){
7. return a+b;
8. }
9. }
2) Create stateless bean client

The stateless bean client may be local, remote or webservice client. Here, we are going to create remote
client. It is console based application. Here, we are not using dependency injection. The dependency
injection can be used with web based client only.

File: AdderImpl.java

1. package com.javatpoint;
2. import javax.naming.Context;
3. import javax.naming.InitialContext;
4.
5. public class Test {
6. public static void main(String[] args)throws Exception {
7. Context context=new InitialContext();
8. AdderImplRemote remote=(AdderImplRemote)context.lookup("st1");
9. System.out.println(remote.add(32,32));
10. }
11. }

Output
Output: 64

Stateful Session Bean

Stateful Session bean is a business object that represents business logic like stateless session bean. But,
it maintains state (data).

In other words, conversational state between multiple method calls is maintained by the container in
stateful session bean.

Annotations used in Stateful Session Bean

There are 5 important annotations used in stateful session bean:

1. @Stateful
2. @PostConstruct
3. @PreDestroy
4. @PrePassivate
5. @PostActivate

Example of Stateful Session Bean

To develop stateful session bean application, we are going to use Eclipse IDE and glassfish 3 server.

As described in the previous example, you need to create bean component and bean client for creating
session bean application.

1) Create stateful bean component

Let's create a remote interface and a bean class for developing stateful bean component.
File: BankRemote.java

1. package com.javatpoint;
2. import javax.ejb.Remote;
3. @Remote
4. public interface BankRemote {
5. boolean withdraw(int amount);
6. void deposit(int amount);
7. int getBalance();
8. }

File: Bank.java

1. package com.javatpoint;
2. import javax.ejb.Stateful;
3. @Stateful(mappedName = "stateful123")
4. public class Bank implements BankRemote {
5. private int amount=0;
6. public boolean withdraw(int amount){
7. if(amount<=this.amount){
8. this.amount-=amount;
9. return true;
10. }else{
11. return false;
12. }
13. }
14. public void deposit(int amount){
15. this.amount+=amount;
16. }
17. public int getBalance(){
18. return amount;
19. }
20. }

2) Create stateful bean client

The stateful bean client may be local, remote or webservice client. Here, we are going to create web based
client and not using dependency injection.

File: index.jsp

1. <a href="OpenAccount">Open Account</a>

File: operation.jsp

1. <form action="operationprocess.jsp">
2. Enter Amount:<input type="text" name="amount"/><br>
3.
4. Choose Operation:
5. Deposit<input type="radio" name="operation" value="deposit"/>
6. Withdraw<input type="radio" name="operation" value="withdraw"/>
7. Check balance<input type="radio" name="operation" value="checkbalance"/>
8. <br>
9. <input type="submit" value="submit">
10. </form>

File: operationprocess.jsp

1. <%@ page import="com.javatpoint.*" %>


2. <%
3. BankRemote remote=(BankRemote)session.getAttribute("remote");
4. String operation=request.getParameter("operation");
5. String amount=request.getParameter("amount");
6.
7. if(operation!=null){
8.
9. if(operation.equals("deposit")){
10. remote.deposit(Integer.parseInt(amount));
11. out.print("Amount successfully deposited!");
12. }else
13. if(operation.equals("withdraw")){
14. boolean status=remote.withdraw(Integer.parseInt(amount));
15. if(status){
16. out.print("Amount successfully withdrawn!");
17. }else{
18. out.println("Enter less amount");
19. }
20. }else{
21. out.println("Current Amount: "+remote.getBalance());
22. }
23. }
24. %>
25. <hr/>
26. <jsp:include page="operation.jsp"></jsp:include>

File: OpenAccount.java

1. package com.javatpoint;
2. import java.io.IOException;
3. import javax.ejb.EJB;
4. import javax.naming.InitialContext;
5. import javax.servlet.ServletException;
6. import javax.servlet.annotation.WebServlet;
7. import javax.servlet.http.HttpServlet;
8. import javax.servlet.http.HttpServletRequest;
9. import javax.servlet.http.HttpServletResponse;
10. @WebServlet("/OpenAccount")
11. public class OpenAccount extends HttpServlet {
12. //@EJB(mappedName="stateful123")
13. //BankRemote b;
14. protected void doGet(HttpServletRequest request, HttpServletResponse response)
15. throws ServletException, IOException {
16. try{
17. InitialContext context=new InitialContext();
18. BankRemote b=(BankRemote)context.lookup("stateful123");
19.
20. request.getSession().setAttribute("remote",b);
21. request.getRequestDispatcher("/operation.jsp").forward(request, response);
22.
23. }catch(Exception e){System.out.println(e);}
24. }
25. }

Introduction to Entity Beans

An “entity bean” is a business encodes persistent object which forms and integral part of JAVA
Enterprise edition. This represents a persistent data object from the database. Beans are commonly known
and EJB (Entity JAVA Bean). They can persistent independently or can delegate this to the container. It is
very resilient and thus was widely used over the distributed network over JAVA EE 6 and before
versions. A container is used to host the EJB Services and in case container or server crashes, then also
beans survive the crash as these are linked to primary keys present in the database.

These were released as EJB 3.0 and then its superset Java Persistence API (application programming
interface) was released. This is now deprecated technology as from JAVA EE 6 version onwards Java
Persistence API is used.

Components of Entity Bean

Entity beans form an object view of a primary key stored in the database system. Some examples, if we
talk about ERP Database are orders, customer master data, material, etc. Since the objects stored in the
database is in a different format than the format data is stored in JAVA beans so to vanish this difference
in formats object persistence property is used.

Entity beans link with other entity beans via establishing relationships as they have primary keys
assigned. Beans can be broken into some components explained below:

1. Remote component: This interface is responsible to store all the methods pertaining to beans.
Generally, multiple business logic are stored with get and set methods to ensure that parameters are
properly passed onto the function and retrieved back with proper business logic applied. This information
is stored in a bean that is loosely coupled (this means that the bean can be present anywhere over the
network and linked with entity bean so that it can be called whenever required).

2. Home interface: The home interface is used to create entity bean methods. These methods can be set,
get or find the entity beans which can be located anywhere over the distributed network.

3. Primary key class: This is one of the main classes which differentiate entity beans from session beans.
Online session beans which are non-persistent after the session is terminated, entity beans do persist as it
contains the primary key class. The primary key is stored in the database as a unique identifier for a table.
Due to the presence of a primary key in the database, entity banns can be accessed by multiple clients and
do not crash even when the server or container for that bean is crashed. Some functions like hash() and
equal() are used for this functionality to be used.

4. Bean class: Bean is a class that links to entity beans and contains business logic which are to be
applied on entity beans. These contain life session duration as well if there is a requirement as such.

How the Entity Bean Works?

There are two things involved majorly in entity beans and these are server and client. We need to build
client applications separately which will call the server. The server has business logics and other
synchronization techniques which consumes the business request and sends out response to the client
application. This application can then deliver the information in the desired format to the requester. We
need to have a one client application that retrieval logic. The server should have an annotation defined as
per its function which may be remote or local.
This can be well understood with the example below:

Examples to Implement Entity Beans

The example for entity bean is provided below with the help of projects created in Eclipse IDE and a
server used is wildly 19. We need to ensure some prerequisites to be fulfilled before running any project
of JAVA EJB. Some of the prerequisites are Maven installed or not, Javaeee-api-7.0.jar API should be
imported in the project. For this case, one jboss-client.jar JAR file and one file of a previous project
(MsgServer) should be imported in the MsgClientEJB project for errors to go away. The below
screenshots clarify how project directories are placed.

Example #1

Project:

Main1: MsgClientEJB

File 1: ClientApp.java

Code:

package MsgClientEJB;
import javax.naming.*;
import MsgServer.*;
import java.util.*;
public class ClientApp {
public static void main(String[] args) {
// TODO Auto-generated method stub
try{
System.out.println("Client App Started");
Properties props = new Properties();
props.put("java.naming.factory.url.pkgs","org.jboss.ejb.client.naming");
InitialContext context = new InitialContext(props);
String appName = "";
String moduleName = "MsgFromServerEJB";
String distinctName = "";
String beanName = Serverone.class.getSimpleName();
String interfaceName = ServeroneRemote.class.getName();
String name = "ejb:" + appName + "/" + moduleName + "/" + distinctName + "/" + beanName + "!" +
interfaceName;
System.out.println(name);
ServeroneRemote bean = (ServeroneRemote)context.lookup(name);
String msg = bean.getMsg();
System.out.println(msg);
}catch(Exception e){
e.printStackTrace();
}
}
}

File 2: jobs-ebb-client.properties

Code:

remote.connections=default
remote.connection.default.host=127.0.0.1
remote.connection.default.port=8080
remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false

File3: module-info.java

Code:

/**
*
*/
/**
*@authormeghnadwivedi
*
*/
module MsgClientEJB {
requires java.naming;
requires MsgFromServerEJB;
}

Output:

Example #2

Main2: MsGFromServerEJB

File1: Serverone.java

Code:

package MsgServer;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
/**
* Session Bean implementation class ExampleServer. This has stateless attribute as mentioned below. We
can have stateful bean as
Well we implemented session bean.
*/
@Stateless
@LocalBean
public class Serverone implements ServeroneRemote, ServeroneLocal {
/**
* Default constructor.
*/
public Serverone() {
//TODO Auto-generated constructor stub
}
@Override
public String getMsg() {
return "This is a message from Server";
}
}

File2: ServeroneLocal.java
Code:

package MsgServer;
import javax.ejb.Local;
// This is local component of the server in JAVA language with an annotation local declared below.
@Local
public interface ServeroneLocal {
public String getMsg();
}

File3: Serveroneremote.java

Code:

package MsgServer;
import javax.ejb.Remote;
// This is remote component of the server in JAVA language with an annotation remote declared below.
@Remote
public interface ServeroneRemote {
public String getMsg();
}

Message Driven Beans

A message driven bean is a type of enterprise bean, which is invoked by EJB container when it receives a
message from queue or topic. Message driven bean is a stateless bean and is used to do task
asynchronously.

To demonstrate use of message driven bean, we will make use of EJB-persistence chapter and we need to
do the following tasks −

 Step 1 − Create table in database (Refer to EJB-Persistence chapter).


 Step 2 − Create Entity class corresponding to table (Refer to EJB-Persistence chapter).
 Step 3 − Create DataSource and Persistence Unit (Refer to EJB-Persistence chapter).
 Step 4 − Create a stateless EJB having EntityManager instance (Refer to EJB-Persistence
chapter).
 Step 5 − Update stateless ejb.Add methods to add records and get records from database via
entity manager (Refer to EJB-Persistence chapter).
 Step 6 − Create a Queue named BookQueue in JBoss default application directory.
 Step 7 − A console based application client will send message to this queue.
 Step 8 − Create a Message driven bean, which will use the stateless bean to persist the client data.
 Step 9 − EJB Container of jboss will call the above message driven bean and pass it the message
that client will be sending to.

Create Queue

Create a file named jbossmq-destinations-service.xml if not exists in <JBoss Installation Folder> >
server > default > deploy folder.

Here we are creating a queue named BookQueue −

jbossmq-destinations-service.xml

<mbean code="org.jboss.mq.server.jmx.Queue"
name="jboss.mq.destination:service=Queue,name=BookQueue">
<depends optional-attribute-name="DestinationManager">
jboss.mq:service=DestinationManager
</depends>
</mbean>

When you start the JBoss, you will see a similar entry in jboss log.

...
10:37:06,167 INFO [QueueService] Queue[/queue/BookQueue] started, fullSize=200000,
pageSize=2000, downCacheSize=2000
...

Create Message Driven Bean

@MessageDriven(
name = "BookMessageHandler",
activationConfig = {
@ActivationConfigProperty( propertyName = "destinationType",
propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty( propertyName = "destination",
propertyValue ="/queue/BookQueue")
}
)
public class LibraryMessageBean implements MessageListener {

@Resource
private MessageDrivenContext mdctx;

@EJB
LibraryPersistentBeanRemote libraryBean;

public LibraryMessageBean() {
}

public void onMessage(Message message) {


}
}

 LibraryMessageBean is annotated with @MessageDriven annotation to mark it as message driven


bean.
 Its properties are defined as destinationType - Queue and destination - /queue/BookQueue.
 It implements MessageListener interface, which exposes onMessage method.
 It has MessgeDrivenContext as a resource.
 LibraryPersistentBeanRemote stateless bean is injected in this bean for persistence purpose.

Build the EjbComponent project and deploy it on JBoss. After building and deploying the EJB module,
we need a client to send a message to jboss queue.

Example Application

Let us create a test EJB application to test Message Driven Bean.

Step Description

Create a project with a name EjbComponent under a package com.tutorialspoint.entity as explained


1
in the EJB - Create Application chapter. You can also use the project created in EJB - Create
Application chapter as such for this chapter to understand EJB persistence concepts.
2
Create Book.java under package com.tutorialspoint.entity as created in EJB-Persistence chapter.
3 Create LibraryPersistentBean.java and LibraryPersistentBeanRemote as created in EJB-Persistence
chapter.
Create jboss-ds.xml in EjbComponent > setup folder and persistence.xml in EjbComponent > src
4
> conf folder. These folders can be seen in files tab in Netbeans as created in EJB-Persistence
chapter.
5 Create LibraryMessageBean.java under a package com.tutorialspoint.messagebean and modify it as
shown below.
6
Create BookQueue queue in Jboss as described above.
7
Clean and Build the application to make sure business logic is working as per the requirements.
8 Finally, deploy the application in the form of jar file on JBoss Application Server. JBoss Application
server will get started automatically if it is not started yet.
9 Now create the EJB client, a console based application in the same way as explained in the EJB -
Create Application chapter under topic Create Client to access EJB. Modify it as shown below.

EJBComponent (EJB Module)

LibraryMessageBean.java
package com.tutorialspoint.messagebean;

import com.tutorialspoint.entity.Book;
import com.tutorialspoint.stateless.LibraryPersistentBeanRemote;
import javax.annotation.Resource;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.EJB;
import javax.ejb.MessageDriven;
import javax.ejb.MessageDrivenContext;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;

@MessageDriven(
name = "BookMessageHandler",
activationConfig = {
@ActivationConfigProperty( propertyName = "destinationType",
propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty( propertyName = "destination",
propertyValue ="/queue/BookQueue")
}
)
public class LibraryMessageBean implements MessageListener {

@Resource
private MessageDrivenContext mdctx;

@EJB
LibraryPersistentBeanRemote libraryBean;

public LibraryMessageBean() {
}

public void onMessage(Message message) {


ObjectMessage objectMessage = null;
try {
objectMessage = (ObjectMessage) message;
Book book = (Book) objectMessage.getObject();
libraryBean.addBook(book);

} catch (JMSException ex) {


mdctx.setRollbackOnly();
}
}
}

EJBTester (EJB Client)

EJBTester.java
package com.tutorialspoint.test;

import com.tutorialspoint.entity.Book;
import com.tutorialspoint.stateless.LibraryPersistentBeanRemote;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;
import javax.jms.ObjectMessage;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class EJBTester {

BufferedReader brConsoleReader = null;


Properties props;
InitialContext ctx;
{
props = new Properties();
try {
props.load(new FileInputStream("jndi.properties"));
} catch (IOException ex) {
ex.printStackTrace();
}
try {
ctx = new InitialContext(props);
} catch (NamingException ex) {
ex.printStackTrace();
}
brConsoleReader =
new BufferedReader(new InputStreamReader(System.in));
}

public static void main(String[] args) {

EJBTester ejbTester = new EJBTester();


ejbTester.testMessageBeanEjb();
}

private void showGUI() {


System.out.println("**********************");
System.out.println("Welcome to Book Store");
System.out.println("**********************");
System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
}

private void testMessageBeanEjb() {

try {
int choice = 1;
Queue queue = (Queue) ctx.lookup("/queue/BookQueue");
QueueConnectionFactory factory =
(QueueConnectionFactory) ctx.lookup("ConnectionFactory");
QueueConnection connection = factory.createQueueConnection();
QueueSession session =
connection.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
QueueSender sender = session.createSender(queue);

while (choice != 2) {
String bookName;
showGUI();
String strChoice = brConsoleReader.readLine();
choice = Integer.parseInt(strChoice);
if (choice == 1) {
System.out.print("Enter book name: ");
bookName = brConsoleReader.readLine();
Book book = new Book();
book.setName(bookName);
ObjectMessage objectMessage =
session.createObjectMessage(book);
sender.send(objectMessage);
} else if (choice == 2) {
break;
}
}

LibraryPersistentBeanRemote libraryBean =
(LibraryPersistentBeanRemote)
ctx.lookup("LibraryPersistentBean/remote");

List<Book> booksList = libraryBean.getBooks();

System.out.println("Book(s) entered so far: " + booksList.size());


int i = 0;
for (Book book:booksList) {
System.out.println((i+1)+". " + book.getName());
i++;
}
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}finally {
try {
if(brConsoleReader !=null) {
brConsoleReader.close();
}
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
}
}

EJBTester performs the following tasks −

 Load properties from jndi.properties and initialize the InitialContext object.


 In testStatefulEjb() method, jndi lookup is done with the name - "/queue/BookQueue" to obtain
treference of queue available in Jboss. Then sender is created using queue session.
 Then user is shown a library store User Interface and he/she is asked to enter choice.
 If user enters 1, the system asks for book name and sender sends the book name to queue. When
JBoss container receives this message in queue, it calls our message driven bean's onMessage
method. Our message driven bean then saves book using stateful session bean addBook() method.
Session Bean is persisting the book in database via EntityManager call.
 If user enters 2, then another jndi lookup is done with name -
"LibraryStatefulSessionBean/remote" to obtain the remote business object (stateful EJB) again
and listing of books is done.

Run Client to Access EJB

Locate EJBTester.java in project explorer. Right click on EJBTester class and select run file.

Verify the following output in Netbeans console −

run:
**********************
Welcome to Book Store
**********************
Options
1. Add Book
2. Exit
Enter Choice: 1
Enter book name: Learn EJB
**********************
Welcome to Book Store
**********************
Options
1. Add Book
2. Exit
Enter Choice: 2
Book(s) entered so far: 2
1. learn java
1. learn EJB
BUILD SUCCESSFUL (total time: 15 seconds)

Defining Client Access with Interfaces


The material in this section applies only to session and entity beans and not to message-driven beans.
Because they have a different programming model, message-driven beans do not have interfaces that
define client access.
A client can access a session or an entity bean only through the methods defined in the bean's interfaces.
These interfaces define the client's view of a bean. All other aspects of the bean--method
implementations, deployment descriptor settings, abstract schemas, and database access calls--are hidden
from the client.

Well-designed interfaces simplify the development and maintenance of J2EE applications. Not only do
clean interfaces shield the clients from any complexities in the EJB tier, but they also allow the beans to
change internally without affecting the clients. For example, even if you change your entity beans from
bean-managed to container-managed persistence, you won't have to alter the client code. But if you were
to change the method definitions in the interfaces, then you might have to modify the client code as well.
Therefore, to isolate your clients from possible changes in the beans, it is important that you design the
interfaces carefully.

When you design a J2EE application, one of the first decisions you make is the type of client access
allowed by the enterprise beans: remote, local, or Web service.

Remote Clients

A remote client of an enterprise bean has the following traits:

 It can run on a different machine and a different Java virtual machine (JVM) than the enterprise
bean it accesses. (It is not required to run on a different JVM.)
 It can be a Web component, an application client, or another enterprise bean.
 To a remote client, the location of the enterprise bean is transparent.

To create an enterprise bean that has remote access, you must code a remote interface and a home
interface. The remote interface defines the business methods that are specific to the bean. For example,
the remote interface of a bean named BankAccountBean might have business methods named deposit and
credit. The home interface defines the bean's life-cycle methods: create and remove. For entity beans, the
home interface also defines finder methods and home methods. Finder methods are used to locate entity
beans. Home methods are business methods that are invoked on all instances of an entity bean class.
Figure 23-2 shows how the interfaces control the client's view of an enterprise bean.

Figure 23-2 Interfaces for an Enterprise Bean with Remote Access

Local Clients

A local client has these characteristics:


 It must run in the same JVM as the enterprise bean it accesses.
 It can be a Web component or another enterprise bean.
 To the local client, the location of the enterprise bean it accesses is not transparent.
 It is often an entity bean that has a container-managed relationship with another entity bean.

To build an enterprise bean that allows local access, you must code the local interface and the local home
interface. The local interface defines the bean's business methods, and the local home interface defines its
life-cycle and finder methods.

Local Interfaces and Container-Managed Relationships

If an entity bean is the target of a container-managed relationship, then it must have local interfaces. The
direction of the relationship determines whether or not a bean is the target. In Figure 23-1, for example,
ProductBean is the target of a unidirectional relationship with LineItemBean. Because LineItemBean
accesses ProductBean locally, ProductBean must have the local interfaces. LineItemBean also needs local
interfaces, not because of its relationship with ProductBean, but because it is the target of a relationship
with OrderBean. And because the relationship between LineItemBean and OrderBean is bidirectional,
both beans must have local interfaces.

Because they require local access, entity beans that participate in a container-managed relationship must
reside in the same EJB JAR file. The primary benefit of this locality is increased performance: local calls
are usually faster than remote calls.

Deciding on Remote or Local Access

Whether to allow local or remote access depends on the following factors.

 Container-managed relationships: If an entity bean is the target of a container-managed


relationship, it must use local access.
 Tight or loose coupling of related beans: Tightly coupled beans depend on one another. For
example, a completed sales order must have one or more line items, which cannot exist without
the order to which they belong. The OrderBean and LineItemBean entity beans that model this
relationship are tightly coupled. Tightly coupled beans are good candidates for local access.
Because they fit together as a logical unit, they probably call each other often and would benefit
from the increased performance that is possible with local access.
 Type of client: If an enterprise bean is accessed by application clients, then it should allow remote
access. In a production environment, these clients almost always run on different machines than
the Application Server does. If an enterprise bean's clients are Web components or other
enterprise beans, then the type of access depends on how you want to distribute your components.
 Component distribution: J2EE applications are scalable because their server-side components can
be distributed across multiple machines. In a distributed application, for example, the Web
components may run on a different server than do the enterprise beans they access. In this
distributed scenario, the enterprise beans should allow remote access.
 Performance: Because of factors such as network latency, remote calls may be slower than local
calls. On the other hand, if you distribute components among different servers, you might
improve the application's overall performance. Both of these statements are generalizations;
actual performance can vary in different operational environments. Nevertheless, you should keep
in mind how your application design might affect performance.

If you aren't sure which type of access an enterprise bean should have, then choose remote access. This
decision gives you more flexibility. In the future you can distribute your components to accommodate
growing demands on your application.

Although it is uncommon, it is possible for an enterprise bean to allow both remote and local access. Such
a bean would require both remote and local interfaces.
Web Service Clients

A Web service client can access a J2EE application in two ways. First, the client can access a Web
service created with JAX-RPC. (For more information on JAX-RPC, see Chapter 8, Building Web
Services with JAX-RPC.) Second, a Web service client can invoke the business methods of a stateless
session bean. Other types of enterprise beans cannot be accessed by Web service clients.

Provided that it uses the correct protocols (SOAP, HTTP, WSDL), any Web service client can access a
stateless session bean, whether or not the client is written in the Java programming language. The client
doesn't even "know" what technology implements the service--stateless session bean, JAX-RPC, or some
other technology. In addition, enterprise beans and Web components can be clients of Web services. This
flexibility enables you to integrate J2EE applications with Web services.

A Web service client accesses a stateless session bean through the bean's Web service endpoint interface.
Like a remote interface, a Web service endpoint interface defines the business methods of the bean. In
contrast to a remote interface, a Web service endpoint interface is not accompanied by a home interface,
which defines the bean's life-cycle methods. The only methods of the bean that may be invoked by a Web
service client are the business methods that are defined in the Web service endpoint interface.

For a code sample, see A Web Service Example: HelloServiceBean.

Method Parameters and Access

The type of access affects the parameters of the bean methods that are called by clients. The following
topics apply not only to method parameters but also to method return values.

Isolation

The parameters of remote calls are more isolated than those of local calls. With remote calls, the client
and bean operate on different copies of a parameter object. If the client changes the value of the object,
the value of the copy in the bean does not change. This layer of isolation can help protect the bean if the
client accidentally modifies the data.

In a local call, both the client and the bean can modify the same parameter object. In general, you should
not rely on this side effect of local calls. Perhaps someday you will want to distribute your components,
replacing the local calls with remote ones.

As with remote clients, Web service clients operate on different copies of parameters than does the bean
that implements the Web service.

Granularity of Accessed Data

Because remote calls are likely to be slower than local calls, the parameters in remote methods should be
relatively coarse-grained. A coarse-grained object contains more data than a fine-grained one, so fewer
access calls are required. For the same reason, the parameters of the methods called by Web service
clients should also be coarse-grained.

For example, suppose that a CustomerBean entity bean is accessed remotely. This bean would have a
single getter method that returns a CustomerDetails object, which encapsulates all of the customer's
information. But if CustomerBean is to be accessed locally, it could have a getter method for each
instance variable: getFirstName, getLastName, getPhoneNumber, and so forth. Because local calls are
fast, the multiple calls to these finer-grained getter methods would not significantly degrade performance.
The Life Cycles of Enterprise Beans

An enterprise bean goes through various stages during its lifetime, or life cycle. Each type of enterprise
bean (stateful session, stateless session, or message-driven) has a different life cycle.

The descriptions that follow refer to methods that are explained along with the code examples in the next
two chapters. If you are new to enterprise beans, you should skip this section and run the code examples
first.

The Life Cycle of a Stateful Session Bean

Figure 20-3 illustrates the stages that a session bean passes through during its lifetime. The client initiates
the life cycle by obtaining a reference to a stateful session bean. The container performs any dependency
injection and then invokes the method annotated with @PostConstruct, if any. The bean is now ready to
have its business methods invoked by the client.

Figure 20-3 Life Cycle of a Stateful Session Bean

While in the ready stage, the EJB container may decide to deactivate, or passivate, the bean by moving it
from memory to secondary storage. (Typically, the EJB container uses a least-recently-used algorithm to
select a bean for passivation.) The EJB container invokes the method annotated @PrePassivate, if any,
immediately before passivating it. If a client invokes a business method on the bean while it is in the
passive stage, the EJB container activates the bean, calls the method annotated @PostActivate, if any, and
then moves it to the ready stage.

At the end of the life cycle, the client invokes a method annotated @Remove, and the EJB container calls
the method annotated @PreDestroy, if any. The bean’s instance is then ready for garbage collection.

Your code controls the invocation of only one life-cycle method: the method annotated @Remove. All
other methods in Figure 20-3 are invoked by the EJB container. See Chapter 34, Resource Connections
for more information.

The Life Cycle of a Stateless Session Bean

Because a stateless session bean is never passivated, its life cycle has only two stages: nonexistent and
ready for the invocation of business methods. Figure 20-4 illustrates the stages of a stateless session bean.

Figure 20-4 Life Cycle of a Stateless Session Bean


The client initiates the life cycle by obtaining a reference to a stateless session bean. The container
performs any dependency injection and then invokes the method annotated @PostConstruct, if any. The
bean is now ready to have its business methods invoked by the client.

At the end of the life cycle, the EJB container calls the method annotated @PreDestroy, if any. The
bean’s instance is then ready for garbage collection.

The Life Cycle of a Message-Driven Bean

Figure 20-5 illustrates the stages in the life cycle of a message-driven bean.

Figure 20-5 Life Cycle of a Message-Driven Bean

The EJB container usually creates a pool of message-driven bean instances. For each instance, the EJB
container performs these tasks:

1. If the message-driven bean uses dependency injection, the container injects these references
before instantiating the instance.
2. The container calls the method annotated @PostConstruct, if any.

Like a stateless session bean, a message-driven bean is never passivated, and it has only two states:
nonexistent and ready to receive messages.

At the end of the life cycle, the container calls the method annotated @PreDestroy, if any. The bean’s
instance is then ready for garbage collection.

Creating the Enterprise Bean

The enterprise bean in our example is a stateless session bean called ConverterBean. The source code for
ConverterBean is in the tut-install/javaeetutorial5/examples/ejb/converter/converter-ejb/src/java/
directory.

Creating ConverterBean requires these steps:

1. Coding the bean’s business interface and class (the source code is provided)
2. Compiling the source code with the Ant tool

Coding the Enterprise Bean

The enterprise bean in this example needs the following code:

 Remote business interface


 Enterprise bean class

Coding the Business Interface

The business interface defines the business methods that a client can call. The business methods are
implemented in the enterprise bean class. The source code for the Converter remote business interface
follows.

package com.sun.tutorial.javaee.ejb;

import java.math.BigDecimal;
import javax.ejb.Remote;

@Remote
public interface Converter {
public BigDecimal dollarToYen(BigDecimal dollars);
public BigDecimal yenToEuro(BigDecimal yen);
}

Note the @Remote annotation decorating the interface definition. This lets the container know that
ConverterBean will be accessed by remote clients.

Coding the Enterprise Bean Class

The enterprise bean class for this example is called ConverterBean. This class implements the two
business methods (dollarToYen and yenToEuro) that the Converter remote business interface defines.
The source code for the ConverterBean class follows.

package com.sun.tutorial.javaee.ejb;

import java.math.BigDecimal;
import javax.ejb.*;

@Stateless
public class ConverterBean implements Converter {
private BigDecimal yenRate = new BigDecimal("115.3100");
private BigDecimal euroRate = new BigDecimal("0.0071");

public BigDecimal dollarToYen(BigDecimal dollars) {


BigDecimal result = dollars.multiply(yenRate);
return result.setScale(2, BigDecimal.ROUND_UP);
}

public BigDecimal yenToEuro(BigDecimal yen) {


BigDecimal result = yen.multiply(euroRate);
return result.setScale(2, BigDecimal.ROUND_UP);
}
}
Note the @Stateless annotation decorating the enterprise bean class. This lets the container know that
ConverterBean is a stateless session bean.

Compiling and Packaging the converter Example

Now you are ready to compile the remote business interface (Converter.java) and the enterprise bean
class (ConverterBean.java), and package the compiled classes into an enterprise bean JAR.

Compiling and Packaging the converter Example in NetBeans IDE

Follow these instructions to build and package the converter example in NetBeans IDE.

1. In NetBeans IDE, select File→Open Project.


2. In the Open Project dialog, navigate to tut-install/javaeetutorial5/examples/ejb/.
3. Select the converter folder.
4. Select the Open as Main Project and Open Required Projects check boxes.
5. Click Open Project.
6. In the Projects tab, right-click the converter project and select Build. You will see the output in
the Output tab.

Compiling and Packaging the converter Example Using Ant

To compile and package converter using Ant, do the following:

1. In a terminal window, go to this directory:

tut-install/javaeetutorial5/examples/ejb/converter/

2. Type the following command:

ant

This command calls the default task, which compiles the source files for the enterprise bean and the
application client, placing the class files in the build subdirectories (not the src directory) of each
submodule. Then the default task packages each submodule into the appropriate package file: converter-
app-client.jar for the application client, converter-ejb.jar for the enterprise bean JAR, and converter-
war.war for the web client. The web client in this example requires no compilation. For more information
about the Ant tool, see Building the Examples.

Note - When compiling the code, the preceding ant task includes the javaee.jar file in the classpath. This
file resides in the lib directory of your Application Server installation. If you plan to use other tools to
compile the source code for Java EE components, make sure that the classpath includes the javaee.jar file.

Web Client

What Does Web Client Mean?

The Web client is a client-side component within the Java 2 Platform Enterprise Edition (J2EE), a
distributed multi-tiered application model used for building and developing enterprise applications.
Client-side components are typically computer applications running on a user's computer and connect to a
server. These components perform client-side operations as they might need access to information
available only on the client side, like user input, or because the server lacks the processing power
necessary in such operations.

J2EE is comprised of a client-tier, Web-tier, business-tier, and enterprise information system (EIS)-tier.
Components that run on the client side of a machine are client-tier components.

Techopedia Explains Web Client

A client-tier component may be an application or Web client. A Web client contains two parts: dynamic
Web pages and the Web browser. Dynamic Web pages are produced by components that run in the Web
tier, and a Web browser delivers Web pages received from the server.

A Web client is also known as a thin client because it does not execute heavy-duty operations such as
querying databases, performing complex business tasks, or connecting to legacy applications. Heavy-duty
operations are performed by the J2EE server, which is secure, fast, and reliable.

Enterprise Bean features

Benefits of Enterprise Beans

For several reasons, enterprise beans simplify the development of large, distributed applications. First,
because the EJB container provides system-level services to enterprise beans, the bean developer can
concentrate on solving business problems. The EJB container, rather than the bean developer, is
responsible for system-level services such as transaction management and security authorization.

Second, because the beans rather than the clients contain the application’s business logic, the client
developer can focus on the presentation of the client. The client developer does not have to code the
routines that implement business rules or access databases. As a result, the clients are thinner, a benefit
that is particularly important for clients that run on small devices.

Third, because enterprise beans are portable components, the application assembler can build new
applications from existing beans. These applications can run on any compliant Java EE server provided
that they use the standard APIs.

When to Use Enterprise Beans

You should consider using enterprise beans if your application has any of the following requirements:

 The application must be scalable. To accommodate a growing number of users, you may need to
distribute an application’s components across multiple machines. Not only can the enterprise
beans of an application run on different machines, but also their location will remain transparent
to the clients.
 Transactions must ensure data integrity. Enterprise beans support transactions, the mechanisms
that manage the concurrent access of shared objects.
 The application will have a variety of clients. With only a few lines of code, remote clients can
easily locate enterprise beans. These clients can be thin, various, and numerous.

Types of Enterprise Beans

Table 20-1 summarizes the two types of enterprise beans. The following sections discuss each type in
more detail.

Table 20-1 Enterprise Bean Types

Enterprise Bean Type Purpose


Session Performs a task for a client; optionally may implement a web service
Message-Driven Acts as a listener for a particular messaging type, such as the Java

Message Service API

Exception Handling

EJBs are a part of enterprise applications which are normally based on distributed environments. So, apart
from the normal exceptions that can occur, there can be exceptions like communication failure, security
permissions, server down, etc.

EJB container considers exceptions in two ways −

 Application Exception − If business rule is violated or exception occurs while executing the
business logic.
 System Exception − Any exception, which is not caused by business logic or business code.
RuntimeException, RemoteException are SystemException. For example, error during EJB
lookup. RuntimeException, RemoteException are SystemException.

How Does EJB Container Handle Exceptions?

When Application Exception occurs, EJB container intercepts the exception, but returns the same to the
client as it is. It does not roll back the transaction unless it is specified in the code by
EJBContext.setRollBackOnly() method. EJB Container does not wrap the exception in case of
Application Exception.

When System Exception occurs, EJB container intercepts the exception, rollbacks the transaction and
start the clean up tasks. It wraps the exception into RemoteException and throws it to the client.

Handling Application Exception

Application exceptions are generally thrown in Session EJB methods as these are the methods responsible
to execute business logic. Application exception should be declared in throws clause of business method
and should be thrown in case business logic fails.

@Stateless
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {

...

public List<Book> getBooks() throws NoBookAvailableException {


List<Book> books =
entityManager.createQuery("From Books").getResultList();
if(books.size == 0)
throw NoBookAvailableException
("No Book available in library.");
return books;
}
...
}

Handling System Exception

System exception can occur at any time like naming lookup fails, sql error occurs while fetching data. In
such a case, such exception should be wrapped under EJBException and thrown back to the client.
@Stateless
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {

...

public List<Book> getBooks() {


try {
List<Book> books =
entityManager.createQuery("From Books").getResultList();
} catch (CreateException ce) {
throw (EJBException) new EJBException(ce).initCause(ce);
} catch (SqlException se) {
throw (EJBException) new EJBException(se).initCause(se);
}
return books;
}
...
}

At client side, handle the EJBException.

public class EJBTester {


private void testEntityEjb() {
...
try{
LibraryPersistentBeanRemote libraryBean =
LibraryPersistentBeanRemote)ctx.lookup("LibraryPersistentBean/remote");

List<Book> booksList = libraryBean.getBooks();


} catch(EJBException e) {
Exception ne = (Exception) e.getCause();
if(ne.getClass().getName().equals("SqlException")) {
System.out.println("Database error: "+ e.getMessage());
}
}
...
}
}

EJB Container

EJB is a server-side software element that summarizes the business logic of an application. Enterprise
Java Beans web repository yields a runtime domain for web-related software elements including
computer reliability, Java Servlet Lifecycle (JSL) management, transaction procedure, and other web
services.

What is an EJB container?

EJB container is a server-side component that comprises the business logic. It offers local and remote
access to the enterprise beans. In other words, we can say that it provides a runtime environment for EJB
applications within the application server. A single EJB container can have one or more EJB modules. It
acts as an intermediate action between business logic and enterprise application. The following figure
depicts the structure of the EJB container.
The typical behavior envisioned by the Java EE specification is that a developer writes an Enterprise
JavaBean, a simple component, and the EJB container adds the necessary infrastructure for
communications, transactions, and data access. It turns the business logic into something that executes.

In addition, the EJB container provides lifecycle management for the component to ensure that its
creation, usage, and destruction are both efficient and in accord with the specification.

When the EJB container is started, it has, at its highest level, the EJBContainerImpl class as its controller.
It is a subclass of the generic ContainerImpl class. EJBContainerImpl implements the EJBContainer
service interface and has listeners for changes to the deployed application modules and other parts of the
environment.

Let's see the inheritance dependencies, methods, and interfaces that define the EJB container.
But if we look at the WsComponent interface, we can see some key methods that explain how the
components, and therefore the container, are controlled by the WAS runtime environment. The
ContainerImpl class is a subclass of the ComponentImpl class, so it can be treated like any other
component by the loadComponents calls of the outer container that initializes it. It is how the base server
starts, controls, and interacts with the EJB container.

It is responsible for creating the enterprise bean, binding the enterprise bean to the naming service so that
other application components can access the enterprise bean, ensuring only authorized clients have access
to the enterprise bean's methods, saving the bean's state to persistent storage, caching the state of the bean,
and activating or passivating the bean when necessary.

The EJB Container Implementation Class

The EJBContainerImpl class is a complex class with many dependencies, as shown in the following
figure. Some of the dependencies are structural and inheritance-related, and some are dynamic and
collaborative in nature.

Using reflection, we can see the interfaces that the EJBContainerImpl class uses.

What does an EJB container do?

EJB container performs the following tasks:

 Instantiate beans on demand


 Manages a pool of bean instances
 Manage Transactions
 Loads/ saves bean data from/to a database
 Handles Security
 Provides other System Services
EJB Container Services

EJB Container provides the following valuable services for enterprise application development.

 Transaction support (start, rollback, and commit)


 Security Model
 Persistence Support
 Timing Services and Job Scheduling
 Messaging
 Remote Access
 Distribution
 Web-services
 Component Pooling
 Component Life-cycle
 Interceptors
 Asynchronous Interactions
 Thread-safety and Concurrency Control

Bean-Managed Transactions

In bean-managed transaction demarcation, the code in the session or message-driven bean explicitly
marks the boundaries of the transaction. Although beans with container-managed transactions require less
coding, they have one limitation: When a method is executing, it can be associated with either a single
transaction or no transaction at all. If this limitation will make coding your bean difficult, you should
consider using bean-managed transactions.

The following pseudocode illustrates the kind of fine-grained control you can obtain with application-
managed transactions. By checking various conditions, the pseudocode decides whether to start or stop
certain transactions within the business method:

begin transaction
...
update table-a
...
if (condition-x)
commit transaction
else if (condition-y)
update table-b
commit transaction
else
rollback transaction
begin transaction
update table-c
commit transaction

When coding an application-managed transaction for session or message-driven beans, you must decide
whether to use Java Database Connectivity or JTA transactions. The sections that follow discuss both
types of transactions.

JTA Transactions

JTA, or the Java Transaction API, allows you to demarcate transactions in a manner that is independent of
the transaction manager implementation. GlassFish Server implements the transaction manager with the
Java Transaction Service (JTS). However, your code doesn’t call the JTS methods directly but instead
invokes the JTA methods, which then call the lower-level JTS routines.

A JTA transaction is controlled by the Java EE transaction manager. You may want to use a JTA
transaction because it can span updates to multiple databases from different vendors. A particular
DBMS’s transaction manager may not work with heterogeneous databases. However, the Java EE
transaction manager does have one limitation: It does not support nested transactions. In other words, it
cannot start a transaction for an instance until the preceding transaction has ended.

To demarcate a JTA transaction, you invoke the begin, commit, and rollback methods of the
javax.transaction.UserTransaction interface.

Returning without Committing

In a stateless session bean with bean-managed transactions, a business method must commit or roll back a
transaction before returning. However, a stateful session bean does not have this restriction.

In a stateful session bean with a JTA transaction, the association between the bean instance and the
transaction is retained across multiple client calls. Even if each business method called by the client opens
and closes the database connection, the association is retained until the instance completes the transaction.

In a stateful session bean with a JDBC transaction, the JDBC connection retains the association between
the bean instance and the transaction across multiple calls. If the connection is closed, the association is
not retained.

Methods Not Allowed in Bean-Managed Transactions

Do not invoke the getRollbackOnly and setRollbackOnly methods of the EJBContext interface in bean-
managed transactions. These methods should be used only in container-managed transactions. For bean-
managed transactions, invoke the getStatus and rollback methods of the UserTransaction interface.

A Message Driven Bean with Bean Managed Transaction

Much the same way, we can code a Message Driven Bean using BMT. Here is an example:

import javax.annotation.Resource;

import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;

import javax.ejb.MessageDrivenContext;

import javax.ejb.TransactionManagement;

import javax.ejb.TransactionManagementType;

import javax.jms.Message;

import javax.jms.MessageListener;

import javax.jms.TextMessage;

import javax.transaction.UserTransaction;

import org.jboss.ejb3.annotation.ResourceAdapter;

@MessageDriven(name = "MDB_BMTExample", activationConfig = {


@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),

@ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/testQueue"),

@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Dups-ok-


acknowledge") })

@TransactionManagement(value = TransactionManagementType.BEAN)

@ResourceAdapter("hornetq-ra.rar")

public class MDB_BMTExample implements MessageListener

@Resource

MessageDrivenContext ctx;

public void onMessage(final Message message)

try

TextMessage textMessage = (TextMessage)message;

String text = textMessage.getText();

System.out.println("message " + text + " received");

// lets look at the user transaction to make sure there isn't one.

UserTransaction tx = ctx.getUserTransaction();

if (tx != null)

{
tx.begin();

System.out.println("we're in the middle of a transaction: " + tx);

tx.commit();

else

System.out.println("something is wrong, I was expecting a transaction");

catch (Exception e)

e.printStackTrace();

Rolling back an EJB Bean Managed Transaction

In a BMT EJB, either the UserTransaction ‘s rollback() or setRollbackOnly() methods are used to
explicitly rollback the transaction. In the above example, we have used the rollback() method of the
UserTransaction class, however it is also possible to invoke setRollBackOnly as in this example:

try {

// Starts the transaction

userTransaction.begin;

...

// Commits the transaction

userTransaction.commit();

} catch (FirstException fe ) {

userTransaction.setRollbackOnly();

} catch (SecondException se ) {

userTransaction.setRollbackOnly();

}
So what is the difference between UserTransaction ‘s rollback() or setRollbackOnly() ? The use of the
rollback() method results in the immediate rollback of the transaction. On the other hand, using the
setRollbackOnly method only marks the transaction for rollback. It will not be rolled back until the
transaction actually ends. Delaying the rollback can be advantageous since it permits other activities to be
performed, such as logging the error conditions.

Transactions not completed in a BMT

According to the EJB specification a transaction must be finished from a BMT bean if it was opened
there.

“If a stateless session bean instance starts a transaction in a business method, it must commit the
transaction before the business method returns.
The Container must detect the case in which a transaction was started, but not completed, in the business
method, and handle it as follows:

 Log this as an application error to alert the system administrator.


 Roll back the started transaction.
 Discard the instance of the session bean.
 Throw the java.rmi.RemoteException to the client”

Interview question

Q: And now a nice interview question: what happens if a Bean Managed Transaction EJB calls a CMT
EJB in its transaction ? and viceversa ?

A: Actually, it is possible a BMT will start a transaction and then invoke a method of a CMT. As a result,
the CMT will not be aware who started the transaction. In contrast, a BMT can only participate in a
transaction that it started. It is not possible to propagate a transaction to another BMT EJB.

You might also like