Escolar Documentos
Profissional Documentos
Cultura Documentos
- HashMap ejbHomes;
- EJBHomeFactory aHomeSingleton
- InitialContext ctx;
EJBClient ParticularHome
uses
Client code
AccountHome anAccountHome =
(AccountHome)EJBHomeFactory.getFactory().
lookUpHome(AccountHome.class);
import javax.ejb.*;
import java.rmi.*;
import java.util.*;
import javax.naming.*;
Context ctx;
private EJBHomeFactory() throws NamingException
{
ctx = new InitialContext();
this.ejbHomes =
Collections.synchronizedMap
(new HashMap());
}
if(anEJBHome == null)
{
anEJBHome = (EJBHome)
javax.rmi.PortableRemoteObject.narrow
(ctx.lookup(homeClass.getName()),
homeClass);
this.ejbHomes.put
(homeClass, anEJBHome);
}
return anEJBHome;
}
}
Business Delegate
Background
• When using Session and/or Message
Façade, the client is coupled to the EJB
layer, creating dependencies between client
and server.
Problems
• Complicates client logic with complex
error handling.
– NamingExceptions, RemoteExceptions,
EJBException to be caught
• Couples the clients directly to EJB and JMS
API’s.
• Lookup and exception handling code
Cont…
• Dependency of client and server
programmers on availability of the
complete and compiled session bean layer.
• Client programmers depend on the
implementation of the Session Façade in
order to compile and test their code.
Cont…
• Places recovery responsibility on clients.
– When a transaction fails.
– May not be necessary to propagate this error to
the end application user and ask them to retry.
– Instead, client code may automatically re-
execute the transaction.
– Client code needs to be explicitly aware of
catching these transactions and re-trying them
Solution
• Client-side Intermediary between a client
and the Session Façade
Solution
• Introduce intermediate class business delegate to
decouple business components from the code that
uses them.
• Manages the complexity of distributed
component lookup, exception handling and
recovery
• Adapts the business component interface to a
simpler interface for use by views.
• Plain java classes
How?
• Clients locally invoke methods on the BD
• BD delegates directly to a method with the
same signature on the session façade, or
populate a JMS message and send it to the
Message Façade.
• Maps one-to-one to session beans
• Wrap multiple message driven beans.
Functions of BD
• Delegate method calls to an EJB.
• Hide EJB specific system exceptions.
– RemoteException and EJBException
– JMS exceptions are caught in the business delegate and
re-thrown to the client as a non-ejb specific exceptions,
such as a BusinessDelegateException.
– Application level exceptions are passed to the client.
• Cache data locally.
• Transparently re-try failed transactions.
• Prototype business delegates can be written that
simply return dummy data
public class ForumServicesDelegate {
ForumServices sb;
public ForumServicesDelegate() throws
DelegateException {
try{
PortalControllerHome home =
(PortalControllerHome)
EJBHomeFactory.getFactory().lookUpHome
(PortalControllerHome.class,
"ForumServices");
this.sb = home.create();
} catch (Exception e){
throw new DelegateException();
}
}
public long addForum (long categoryPK, String
forumTitle, String summary, String imageName)
throws NoSuchCategoryException,
DelegateException {
try{
return sb.addForum(categoryPK, forumTitle,
summary, imageName);
} catch(CreateException e){
throw new DelegateException();
} catch(RemoteException e){
throw new DelegateException();
}
}
}
EJB Command
Problems with SF/BD
• Slower development process.
– Changing a use-case requires editing 3
different files (interface, bean class,
deployment descriptor) plus redeployment
– BD to be changed.
• Server resources often controlled by just
one team in a large corporation. Difficult to
effect any changes on existing classes.
EJB Command
• Developing with a session façade and
business delegates can result in long
change-deploy-test roundtrips, which can
become a bottleneck in a large project.
• The crux of the problem is that the business
logic is being placed in a layer of session
EJB’s, which can be pretty heavy weight to
develop with.
The Command Pattern
• Wrap business logic in lightweight
command objects
• Decouple the client from EJB
• Execute in one network call
• Act as a façade to the EJB layer
• plain java class with gets, sets and an
execute method
How?
• Clients interact with the command object
locally
• Execute within a remote EJB server,
transparently to the client.
• Encapsulate individual units of work in an
application.
• A use case’s business logic encapsulated in
a command.
Command client view
TransferFunds
w ithdraw AccountID
depositAccountID
transferAmount
w ithdraw AccountBalance
depositAccountBalance
setWithdraw AccountID(int)
setDepositAccountID(int)
setTransferAmountID(double)
execute()
getWithdraw AccountBalance()
getDepositAccountBalance()
Client interaction with a
command
• Client creates a Command
• Client sets attributes onto the command
• Client calls the command’s execute method
• Client calls gets on the command until it has
retrieved all the data resulting from the
execution of the command/use case.
Working
• The command is actually transferred to a
remote EJB server and executed within the
EJB servers JVM.
• When the command has completed
executing, it is returned to the client, who
can then call get methods to retrieve data.
Interaction
• The client instantiates the command object
• The client calls an executeCommand method on
the routing logic/CommandExecutor
• The CommandExecutor delegates the call to an
EJBCommandTarget (part of routing logic)
• The command target knows how to send the
command to the command server
• CommandServer is a stateless session bean.
• CommandServer calls the execute method on the
command, which then goes about its business
logic.
Benefits
• Rapid Application Development (RAD)
• Separation of business logic from presentation
logic.
• Forces execution of use cases in single roundtrip.
Client EJB
Network
getAttribute1()
getAttribute2()
getAttribute3()
getAttribute4()
getAttribute5()
Problem
• Each call to the server is a network call
• Blocking on the client while the EJB
server intercepts the call to the server and
performs transaction and security checks
and retrieval
• Each method call executes in its own
separate transaction if the client is not using
Java Transaction API client demarcated
transactions.
To Achieve
• Client exchange bulk data with the server
without making multiple fine-grained
network calls
Solution
• Create plain java classes called Value
Objects or DTOs, which contain and
encapsulate bulk data in one network
transportable bundle.
• A value object is a plain serializable Java
class that represents a snapshot of some
server side data
import java.io.Serializable;
public class SomeValueObject implements
Serializable {
private long attribute1;
private String attribute2;
private String attribute3;
public long getAttribute1();
public String getAttribute2();
public String getAttribute3();
}
The right way to read data from the server
getSomeValueObject()
getAttribute1()
getAttribute2()
getAttribute3() Network
getAttribute4()
getAttribute5()
How to design the DTO?
<<interface>> <<interface>>
javax.ejb.EJBObject javax.ejb.EJBLocalObject
getEJBHome() getEJBLocalHome()
getHandle() getPrimaryKey()
getPrimaryKey() isIdentical(obj)
isIdentical(obj) remove()
remove()
<<interface>> <<interface>>
Remote Local
businessMedthod1() businessMedthod1()
businessMedthod2() businessMedthod2()
.... ....
Cont…
• Clutters your enterprise bean class by writing
dummy implementations of these extra methods.
• The bean could be directly cast to one of these
interfaces, allowing a developer to pass an
instance of this to a client.
• Not allowed by the EJB specification.
• To pass a reference to one-self, a bean needs
should first get a reference to itself by calling
getEJBObject or getEJBLocalObject off of the
SessionContext or EntityContext interface.
Solution
• Create a super interface called a Business
Interface, which defines all business
methods.
• Both the remote/local interface and the
enterprise bean class implement this
interface, forcing compile-time consistency
checks.
Business Interface for Remote and Local Beans
<<interface>>
java.rmi.Remote
businessMedthod1() businessMedthod1()
businessMedthod2() businessMedthod2()
.... ....
//EJB Methods //EJB Methods
.... ....
JDBC for Reading
JDBC for Reading
• Present static server-side data to a client in
tabular form.
• Read-only
HTML Table of Employees
Employee Department
getAccountData()
get("accountNumber")
get("name")
get("balance")
put("balance", 123)
setAccountData(aHashMap)
• A client is passed a HashMap that contains
different sets of data, as needed by the particular
use case.
• Using a HashMap instead of a data transfer object
comes at the cost of additional implementation
complexity, since the client now needs to
explicitly know the strings used as keys to query
the HashMap for the attributes of interest.
• The session façade and the client agree on the
strings to be used by to populate and read from a
HashMap.
Benefits
• Excellent maintainability - eliminates the
Data Transfer Object layer.
• One data object (Map) across all clients. A Map
of attributes is reusable from the Session Façade
down to the JSPs. In particular, using a Map as a
data container significantly reduces the
complexity of the JSP code, as pages don’t need
to be written with use case specific Value Objects
that are tightly coupled to the entity bean layer.
• Low cost of maintenance over time. New views
of server side data can be created that does not
require any server side programming. Clients can
dynamically decide which attributes to display.
Tradeoffs
• Need to maintain a contract for attribute
keys. Extra dependency between client and
server.
• Loss of strong typing/compile time
checking.
Data Transfer Rowset
Data Transfer RowSet
• When using JDBC for Reading, relational
data needs to be transferred across the
network tier from the Session Façade to the
client.
• How can relational data be transferred to
the client in a generic, tabular format?
public class EmployeeDepartmentViewObject
{
public String employeeName;
public String employeeTitle;
...
public String departmentName;
public String departmentLocation;
...
}
• Session bean performs a JDBC call to get a
ResultSet that contains information about an
employee and their department.
• Session bean manually extracts fields from the
ResultSet and calls the necessary setters to
populate the DTO.
• Each row in the ResultSet will be transferred into
a DTO which will be added to a collection.
• This collection of DTO’s now forms a network
transportable bundle, transferable to the client for
consumption.
Problem
• Tabular to OO and back to tabular is
redundant.
• Preserve the tabular nature of the data being
transferred in a generic fashion, allowing
for simpler clients and simpler parsing into
the client UI.
Solution
• Use RowSets for marshalling raw relational
data directly from a ResultSet in the EJB
tier to the client tier.
RowSet
• An interface, a subclass of java.sql.ResultSet.
• CachedRowSet implementation allows you to
wrap ResultSet data and marshal it off to the client
tier.
• Client can operate directly on the rows and fields.
• CachedRowSet is disconnected from the database.
• Once the CachedRowSet has been initialized with
data, database connections can be closed – the
CachedRowSet now maintains a copy of the
results of the SQL query.
Value Objects vs. RowSets
{
Employee Department
{ }
Adam Berman Development
Adam Berman | Development Eileen Sauer Training
Ed Roman Management
Collection of Clay Roach Architecture
Employee Eileen Sauer | Training Single
Department RowSet
OR
Objects
Clay Roach | Architecture
Advantages
• Provides a common interface for all query
operations.
• All the clients can use the same interface for
all data querying needs.
• No matter what the use case is or what data
is being returned, the interface a client
operates on stays the same.
• Eliminates the redundant data translation.
Tradeoffs
• Clients need to know the name of database table
columns. Maintaining a ‘contract’ of attribute
names between client and server, as described in
the Generic Attribute Access pattern.
• Not object oriented.
• No compile-time checking of query results. Rather
than calling getXXX() on a value object, a client
must now call getString(“XXX”) on the RowSet,
possibility of mistyping the attribute name.
Data Access Object
Problem
• Access to data varies depending on the source of
the data. Access to persistent storage, such as to a
database, varies greatly depending on the type of
storage (relational databases, object-oriented
databases, flat files, and so forth) and the vendor
implementation.
• Code that depends on specific features of data
resources ties together business logic with data
access logic. This makes it difficult to replace or
modify an application's data resources.
Participants
• BusinessObject : requires access to the data source to
obtain and store data. a session bean, entity bean, Java
object, a servlet or helper bean.
• DataAccessObject : abstracts the underlying data access
implementation. Enables transparent access to the data
source.
• DataSource : a database such as an RDBMS, OODBMS,
XML repository, flat file system, another system
(legacy/mainframe), service (B2B service or credit card
bureau), or some kind of repository (LDAP).
• TransferObject : This represents a Transfer Object used
as a data carrier. To return/receive the data to/from the
client.
Benefits
• Separates a data resource's client interface
from its data access mechanisms
• Adapts a specific data resource's access API
to a generic client interface
• Allows data access mechanisms to change
independently of the code that uses the data.
References
• EJB Design Patterns by Floyd Marinescu - Wiley.
(available online at www.theserverside.com and
\\Kalpa)
• J2EE Design Patterns Catalog -
http://java.sun.com/blueprints/patterns/cata
log.html
• Core J2EE Patterns (online book) -
http://java.sun.com/blueprints/corej2eepatte
rns/Patterns/
• Sun Java Center J2EE Patterns -
http://developer.java.sun.com/developer/rest
ricted/patterns/J2EEPatternsAtAGlance.html