Creating Distributed Applications Using RMI and JDBC
Creating Distributed Applications Using RMI and JDBC
Creating Distributed Applications Using RMI and JDBC
10
Creating Distributed
Applications Using
RMI and JDBC
In this chapter:
275
Understanding Remote Method Invocation (RMI)
The RMI technology lets you easily develop networked Java applica-
tions that hide the underlying mechanisms for transporting method
arguments and return values.
RMI enables programmers to create distributed Java-to-Java pro-
grams. Under distributed Java computing, one part of the
program—running in one Java Virtual Machine as a client—can
invoke the methods of server objects in another virtual machine,
often on a different host.
However, client programs do not communicate directly with
server objects. When invoking remote methods, clients instead
invoke the methods of a remote object’s stub, which resides on the
client host. The local stub does the networking needed to pass
remote method invocations to the skeleton (another interface to the
remote object) that resides on the server host.
Figure 10-1 shows the RMI architecture.
The RMI allows client and server objects to interact as if they were
local objects residing in the same Java Virtual Machine. Additionally,
server objects can be RMI clients of other remote objects.
method parameters and return values. Figure 10-2 shows the char-
acteristics of object marshalling.
What Is Marshalling?
Marshalling refers to the process of packaging method arguments and return
values so that they can be moved across the network. This process involves seri-
alization, which is a way to convert objects so they can be passed over the net-
work. Serializable objects include primitive types, remote Java objects, AWT
components, and any other object that implements the serializable interface.
Note that, if you declare a Java property as transient, then that property will
not be serialized.
Useful Links
For more information about RMI, you can view the following docu-
mentation:
http://Java.sun.com/products/jdk/1.1/docs/guide/rmi/
index.html
Component Function
RMI compiler (rmic) Generates the stubs and skeletons for the remote server class.
Stubs A client view of the remote methods.
Skeletons On the server, connects the stub to the remote server class.
Remote interface An interface that defines the remote methods that the remote
server class will implement in code.
Remote server class A class that implements the methods defined in the interface file.
Server factory A program that generates an instance of the remote server class,
and registers it with an RMI registry.
RMI registry service The RMI bootstrap registry program that runs on the server host
and registers remote RMI objects by name on the network.
http://Java.sun.com/products/jdk/1.1/docs/guide/rmi/
faq.html
http://Java.sun.com/products/jdk/1.1/docs/guide/
rmi/spec/rmiTOC.doc.html
Try to maintain the design of the remote interfaces. If you are using
parameters, try to encapsulate all the related parameters into a single
object. If you need to add another parameter, you don’t have to change
the remote interface, only the parameter class.
import java.rmi.*;
import java.sql.*;
javac JR.java
You can place compiled interfaces anywhere on the RMI server. Make
sure the CLASSPATH environment variable used when starting the serv-
er program points to the location of these interface classes.
import java.rmi.*;
import java.rmi.server.*;
import java.sql.*;
//Default constructor
public JRImpl () throws RemoteException { }
javac JRImpl.java
Remote server objects must already be running on the server host when
note a service is requested from the client.
rmic JRImpl
JRImpl_Stub.class
JRImpl_Skel.class
If the compiled class is part of a Java package, give the full package
note name to rmic.
Naming.rebind(
"//dellcpi.eu.informix.com/rmiExample", servlet );
Object Description
servlet An instance of the class that implements the
remote methods the client will invoke.
Naming.rebind Naming provides the default registry service. The
rebind method adds an object to the RMI registry.
//dellcpi:1099 Host and port on which the RMI registry runs.
rmiExample A label for the registered object; all clients can use
the label.
import java.rmi.*;
import java.rmi.registry.*;
import java.net.*;
try {
JRImpl servlet = new JRImpl ();
set JAVA_HOME=D:\java\jdk1.1.7
set PATH=%JAVA_HOME%\bin;%PATH%
unsetenv CLASSPATH
rmiregistry &
On Windows:
unset CLASSPATH
start rmiregistry
java JRServer
//dellcpi.eu.informix.com/rmiExample
//dellcpi.eu.informix.com:1090/rmiExample
Listing 10-4 shows the init() method of a Java applet that uses
RMI to connect to the remote instance of the JR class that is stored
in the RMI registry.
import java.rmi.*;
import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;
connectionId = servlet.openConnection();
}
catch (RemoteException e) {
showStatus("Failed to Open Connection");
}
}
}
For applets, compiled stubs are bundled with the applet code. You
need to place the stub classes into the same directory on the RMI
server host in which the applet resides. In addition, place the com-
piled interfaces (e.g., JR.class) into the same directory.
The remote object that an applet can reference is not prevented from
connecting to other machines and objects on the network. For exam-
ple, the remote object on machine 1 can implement a method to
invoke another remote method in an object on another machine,
machine 2. If an applet required service from a remote object on
machine 2, it would call the remote method on machine 1 to man-
age this interface.
note Registry and server objects must be running before the applet starts.
To run RMI-based applets, the viewer or browser used to run the applet
must support the RMI features of Java 1.1. Browsers not supporting
these features may crash.
import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;
import java.rmi.*;
import java.rmi.registry.*;
int connectionId;
JR servlet;
validate();
setVisible( true );
try {
// install security manager
if (System.getSecurityManager() == null) {
System.setSecurityManager(
new RMISecurityManager() );
}
searchResults.addItem("RemoteSQLApplet:init: Preparing
for registry lookup..." );
registryName = "//" + getCodeBase().getHost() + "/";
registryName += "rmiExample";
searchResults.addItem("RemoteSQLApplet:init: Looking up
'"+registryName+"'..." );
try {
searchResults.addItem(
"RemoteSQLApplet:init: Starting OPEN db connection task..." );
connectionId = servlet.openConnection();
searchResults.addItem(
"RemoteSQLApplet:init: Finished OPEN db connection task..." );
if ( connectionId == -1 ) {
searchResults.addItem(
"RemoteSQLApplet:init: Error during OPEN db connection task..." );
searchResults.addItem(
"-1: Cannot OPEN DATABASE connection." );
}
}
catch (Exception ex) {
searchResults.addItem(
"RemoteSQLApplet:init: Exception during OPEN db connection task..."
);
searchResults.addItem(
"Exception: Cannot OPEN DATABASE connection." );
ex.printStackTrace();
}
}
super.destroy();
}
showStatus( "" );
clearListBox();
}
return;
}
clearListBox();
searchString = searchCriteria.getText();
<HTML>
<APPLET CODE="RemoteSQLApplet" WIDTH=600 HEIGHT=300></APPLET>
</HTML>
int connectionId;
System.out.println(
"JRImpl:openConnection: Starting...");
System.out.println(
"JRImpl:openConnection: Opening connection to DATABASE...");
jrc [connectionId].openConnection();
return connectionId;
}// end openConnection