Developers must implement a strategy and design that offers flexibility, scalability, and reuse of application
Developing and deploying a J2EE application requires three distinct phases: development, assembly, and deployment. During development, web component providers and developers build components that encapsulate presentation logic. The reusable components are deployed as WAR files. EJB component developers create the EJB components that encapsulate business logic, and subsequently deploy them as EJB-JAR files.
In the assembly phase, an assembler puts together both the WAR and EJB-JAR files and merges them into an EAR file. The assembler is responsible for examining both types of files and customizes fields in the deployment descriptor file.
Finally, the deployer examines the EAR file, resolving any external dependencies, and configures the application to execute and deploy in an operational environment.
Several different development models exist within the Java environment. They include the time-
Remote presentation model
Distributed logic model
Remote data management model
Distributed data management model
In the remote presentation model, commonly referred to as the thin client paradigm, the only tool a client needs for communicating with the server is a web-enabled browser for submitting HTML-based
All server-side components, including business logic, servlets, Java Server Pages, and data management components, reside on the server.
The server-side controller (a servlet) provides dynamic content to a client.
The only tool needed is a web browser.
Developers face minimal challenges when
Figure 2-2 represents a client-side presentation model and
Figure 2-2:
Applying a filter to the J2EE’s infrastructure
The web server is a server-side program that invokes a servlet to manage and execute a server application. The servlet’s chief task extends the functionality of a web server and functions in two separate
Servlets interface with existing JavaBeans or Enterprise JavaBeans. In either case, they access databases or transactional systems, providing such
Servlets offer
Distributed logic business solutions divide the application roles between client and server. This solution offers application flexibility and features both Remote Procedure Calls (RPCs) and messaging services.
| Note |
The more traditional RPCs are invoked on procedural-type applications rather than on object-oriented web-based applications. |
RPCs are synchronous, and using them has a significant drawback. Synchronous calls mean the calling program is blocked until the procedure returns a response. The Remote Method Invocation (RMI) solution allows developers to transmit messages remotely to an object. RMI includes a naming registry, which tracks instances and
All distributed object protocols are built using the same architecture. This design makes an object residing on one computer look as though it sits on a local machine. This model contains three components: the business object, the stub, and the skeleton.
The
stub
resides on the client, whereas the
skeleton
exists on a middle layer that contains the business logic. Every business object contains matching stub and skeleton classes
public interface Widget {
public int getSku()throws Throwable;
public String getName()throws Throwable;
}
The interface implementation contains both business logic and state for the Widget:
public class WidgetServer implements Widget {
int sku;
String
name
;
public WidgetServer (String name, int sku){
// perform initialization here
this.sku = sku;
this.name = name;
}
public int getSku() {
return sku;2345 }
public String getName () {
return name;
}
}
The
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.net.Socket;
public class Widget_Stub implements Widget {
Socket socket;
public Widget_Stub throws Throwable {
/* Create a connection to the skeleton.
Select either local host or the skeleton's IP address if it resides
on a remote computer. */
socket = new Socket("localhost" 9000):
public int getSku() throws Throwable {
ObjectOutputStream oStr =
new ObjectOutputStream(socket.getOutputStream());
oStr.writeObject("sku");
oStr.flush();
ObjectInputStream inStr =
new ObjectInputStream(socket.getInputStream());
return inStr.readInt();
}
public String getName() throws Throwable {
ObjectOutputStream oStr =
new ObjectOutputStream(socket.getOutputStream());
oStr.writeObject("name");
oStr.flush();
ObjectInputStream inStr =
new ObjectInputStream(socket.getInputStream());
return (String)inStr.readObject();
}
}
A String token is created and streamed to the skeleton when a method is invoked on the Widget_Stub. The token identifies the specific method invoked on the stub. Next, the skeleton parses the token and calls the corresponding method on the business object, and subsequently streams back the result. When the stub reads the skeleton’s reply, it parses the value and returns it to the client. This process actually makes the stub look as though it were processing the request locally.
Here is the skeleton code:
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.net.Socket;
import java.net.ServerSocket;
public class Widget_Skeleton extends Thread {
WidgetServer myServer;
public Widget_Skeleton(WidgetServer server){
//this establishes a reference to the object this skeleton wraps
this.myServer = server;
}
public void run(){
try {
//generate a server socket on port 9000
ServerSocket servSocket = new ServerSocket(9000);
Socket socket = servSocket.accept();
while(socket != null){
//create an input stream to receive requests from the stub
/*remember, the skeleton sits on the middletier and listens
for requests from the stub */
ObjectInputStream inStr =
new ObjectInputStream(socket.getInputStream());
//Read the next stub method request.
String method = (String)inStr.readObject();
if(method.equals ("sku")){
int sku = myServer.getSku();
ObjectOutputStream oStr =
new ObjectOutputStream(socket.getOutputStream());
//send results back to the stub
oStr.writeInt(sku);
oStr.flush();
}else if(method.equals("name")){
//invoke business method on the server object
String name = myServer.getName();
//Create an output stream to send return values to the stub
ObjectOutputStream oStr =
new ObjectOutputStream(socket.getOutputStream());
//return the results to the stub
oStr.writeObject(name);
oStr.flush();
}
}
}catch(Throwable t) {t.printStackTrace();System.exit(0);}
}
public static void main(String args[]){
WidgetServer widget = new WidgetServer("DLink100", 2345);
Widget_Skeleton wSkel = new Widget_Skeleton(widget);
wSkel.start();
}
}
The Widget_Skeleton directs requests received from the stub to the business object, WidgetServer. The Widget_Skeleton functions solely as a listener awaiting stub requests. When it receives a request, the skeleton parses it and delegates the task to the corresponding method on the WidgetServer. The business object’s return value is streamed back to the stub, returning the result and making it look as though it were
The final step in describing the roles of both stub and skeleton is creating a client that utilizes the Widget:
public class WidgetClient {
public static void main(String [] args){
try {
Widget widget = new Widget_Stub():
int sku = widget.getSku();
String name = getName();
System.out.println(name+" is "+sku+ " hub product ");
}catch(Throwable t ) {t.printStackTrace();}
}
}
The client application demonstrates how the stub is used on a client machine. Note how the client is unaware that the Widget business object is in reality a network proxy to the business object on the middle tier.
RMI represents the basis for distributed object systems. Its primary task is making distributed objects location transparent. This means a server’s actual object location is always unknown to the client.
Summarizing the functionality for this example, the developer creates an interface that extends the
java.rmi.Remote interface.
This interface describes all remote
The remote data management model provides a consistent methodology for
Retrieve and scroll through query results returned by a server.
Treat database results as JavaBeans.
Manage and pool database connections.
Persist objects in relational databases.
Forward SQL statements to the database server.
The following steps are required for establishing a database connection and manipulating data:
Initialize and allocate drivers and database connections.
Create and prepare statements for database execution.
Navigate and process query results.
Perform any cleanup
Replication is the key to distributed data processing. This business solution requires data management on both client and server. The administrator must synchronize both client and server databases. The drawback to this scenario is that it is a proprietary solution. Concurrency is also an issue.