Remote Method Invocation
- What is RMI?
- What is CORBA?
- Developing RMI Application
- Steps to Compile, Run RMIServer and RMIClient
- RMI Example
What is RMI? |
RMI is the simplest and fastest way to implement a distributed object architecture due to its easy-to-use native-Java model. Therefore, it is a good choice for RAD prototypes and small-sized applications that are implemented completely in Java. The main issue with RMI is that its not as robust or as scalable as CORBA or DCOM solutions.
For example, RMI uses a native-transport protocol, JRMP (which is not currently CORBA/IIOP compliant), and can only communicate with other Java RMI objects. This "single-language" crutch makes it impossible for RMI to interact with objects not written in Java like legacy applications and prevents RMI from playing a more formidable role in large-scale enterprise solutions. Java RMI (Remote Method Invocation) is a distributed object model for the Java Platform. RMI is unique in that it is a language-centric model that takes advantage of a common network type system. In a nutshell, RMI extends the Java object model beyond a single virtual machine address space. Object methods can be invoked between different VMs across a network, and actual objects can be passed as arguments and return values during method invocation. Java RMI uses object serialization to convert object graphs to byte-streams for transport. Any Java object type can be passed during invocation, including primitive types, core classes, user-defined classes, and JavaBeans. The ability to pass actual objects enables clean system design, allowing system designers to focus on the overall object model, not the plumbing of an application. Java RMI could be described as a natural progression of procedural RPC (Remote Procedure Call), adapted to an object-oriented paradigm.
Because Java RMI can dynamically resolve method invocations across VM boundaries, it provides a fully object-oriented (OO) distributed environment. Developers can implement classic OO design patterns for distributed programming just as they would in local programming. Because RMI operates naturally in the Java domain, developers work within a single object model (the Java model), instead of working with multiple object models (Java, CORBA IDL, and others).
This removes a great deal of complexity. Unlike language-neutral object models, RMI requires no mapping to common interface definition languages. The syntax of remote method invocations is almost exactly the same as local method invocations. RMI removes the burden of memory management from the programmer, because the underlying system provides distributed garbage collection. All of these characteristics make programming in RMI simple and natural, an obvious choice for developing 100% Pure Java client/server, peer-to-peer, or agent-based applications.
RMI OVER IIOP
RMI-IIOP combines the usability of Java Remote Method Invocation (RMI) with the interoperability of the Internet Inter-ORB Protocol (IIOP). It provides you with a powerful environment in which to do distributed programming in Java.
Features at a glance
- Enables RMI programmers to use IIOP as the transport mechanism
- Enables interoperability between Java RMI programs and programs written in languages other than Java (e.g. C++)
- Compatible with Enterprise Java Beans
- RMI-IIOP reference implementation runs on Windows (NT, 95, and 98) and Solaris. RMI-IIOP also runs on OS/390, AIX, and OS/2 from JDK 1.1.8 onwards.
- Provides a new-generation Java ORB that allows passing of objects by value
- Standard extension to JDK 1.1.6 onwards, including Java 2
- Available for free download
About RMI-IIOP
Java RMI provides easy-to-use Java-based distributed computing facilities. Specifically, Java RMI enables developers of distributed Java applications to treat remote objects and their methods very much like normal Java objects. Java RMI brings a new level of functionality to distributed programs with features like distributed, automatic management of objects and passing objects themselves from machine to machine over the network. Java RMI is an important part of the Java platform and has been shipping as part of JDK 1.1.
A transport protocol is a defined set of message formats that allow data to be passed across a network from one computer to another. Java RMI supports its own protocol today (JRMP) and will support other industry standard protocols in the near future, including IIOP.
IIOP (Internet Inter-ORB Protocol) is a transport protocol which is part of the Object Management Group’s Common Object Request Broker Architecture (CORBA) for distributed computing.
CORBA |
Common Object Request Broker Architecture
(CORBA) takes a language-neutral approach which enables networks of distributed objects to contain code written in more than one langage. CORBA is an open standard developed under the auspices of the Object Management Group (OMG), an industry consortium with over 800 members. In a CORBA network, Object Request Brokers (ORBs) mediate requests between clients and servers in a standardized way. ORBs communicate with each other using the Internet Inter-ORB Protocol (IIOP), a higher-level protocol based on TCP/IP that provides a standard way to make method calls to remote objects.
Because IIOP is a standard communications protocol that must be supported by all ORBs, CORBA provides interoperability between ORB products produced by different vendors for a number of programming languages and platforms. Other components of CORBA such as its Interface Definition Language (IDL) and its programming language APIs for clients and implementations provide portability for CORBA applications from one ORB to another. This combination of interoperability and portability means that customers can invest in CORBA knowing that they are not locked in to the products of a single vendor. CORBA is also known for its robustness and scalability, making it a popular choice for enterprise middleware.
The pros and cons of CORBA
What makes CORBA an attractive architecture is its platform and language independence. Microsoft’s Distributed Component Object Model (DCOM) also supports multiple languages (Java, VB, C++), but is lacking platform independence since it was obviously geared toward the Windows environment. However, the CORBA platform independence advantage may soon fade away as Microsoft is combining efforts with other development firms in order to port DCOM to other platforms.
One of the major cons of the Java/CORBA environment is that only a few of the specified services have been implemented in the Java ORBS. For example, Visibroker 3.0 has only implemented the Naming and Event CORBA services to date. Important CORBAservices such as Security, Query, Transaction and Concurrency Control are not yet available but could be mission critical requirements for some types of distributed applications.
A short list of the pros and cons of implementing a Java-CORBA solution is provided below.
The Future Of CORBA
CORBA’s major competitor is the Distributed Component Object Model (DCOM) created by Microsoft. Microsoft’s product saturation in the business market makes them a very real competitor, claiming that COM and DCOM are used in over 150 million systems worldwide. Since COM/DCOM systems are in such abundance, the technology is not going away anytime soon.
For CORBA to really set itself apart from DCOM and emerge as the industry standard, it needs to forge a tighter relationship with Java. The technologies complement each other well, with CORBA providing network transparency and Java providing implementation transparency. Java enables CORBA clients to be easily distributed to remote machines, regardless of platform, via applets and browsers.
CORBA reciprocates by enabling Java to interface with different programming languages and extends Java by providing a framework for distributed object communications.
And fortunately for the CORBA backers, JavaSoft’s Remote Method Invocation (RMI), which formerly was thought of as a competitor to CORBA, is fast becoming one of CORBA’s main allies. This is supported by an announcement in the Java Spot News, dated February 18th, 1998, when the Object Management Group (OMG) publicly declared that it had finalized modifications of its IIOP communications protocol so that it could support most of the JDK1.1 functionality of the Java programming language’s RMI. This press release, found on JavaSoft’s site (www.javasoft.com), maintains that IIOP allows distributed objects to conform to OMG’s CORBA specification, thus by enabling RMI to run on top of IIOP, Java objects can now easily also conform to CORBA. JavaSoft also stated that support for running RMI over IIOP will be available as a standard extension to the next version of the Java Development Kit.
RMI applications are often comprised of two separate programs: a server and a client. A typical server application creates a number of remote objects, makes references to those remote objects accessible, and waits for clients to invoke methods on those remote objects. A typical client application gets a remote reference to one or more remote objects in the server and then invokes methods on them. RMI provides the mechanism by which the server and the client communicate and pass information back and forth. Such an application is sometimes referred to as a distributed object application.
Distributed object applications need to:
- Locate remote objects
Applications can use one of two mechanisms to obtain references to remote objects. An application can register its remote objects with RMI’s simple naming facility, the rmiregistry, or the application can pass and return remote object references as part of its normal operation. - Communicate with remote objects
Details of communication between remote objects are handled by RMI; to the programmer, remote communication looks like a standard method invocation. - Load class bytecodes for objects that are passed as parameters or return values
–Because RMI allows a caller to pass objects to remote objects, RMI provides the necessary mechanisms for loading an object’s code as well as transmitting its data.
–RMI can load class bytecodes using any URL protocol (e.g., HTTP, FTP, file, etc.) that is supported by the Java platform.
The Distributed and Nondistributed Models Contrasted
The Java platform’s distributed object model is similar to the Java platform’s object model in the following ways:
- A remote object can be cast to any of the set of remote interfaces supported by the implementation using the syntax for casting built into the Java programming language.
- The built-in instanceof operator can be used to test the remote interfaces supported by a remote object.
- The Java platform’s distributed object model differs from the Java platform’s object model in these ways:
- Clients of remote objects interact with remote interfaces, never with the implementation classes of those interfaces.
- Non-remote arguments to, and results from, a remote method invocation are passed by copy rather than by reference.
- This is because references to objects are only useful within a single virtual machine.
- A remote object is passed by reference, not by copying the actual remote implementation.
- The semantics of some of the methods defined by class java.lang.Object are specialized for remote objects.
- Since the failure modes of invoking remote objects are inherently more complicated than the failure modes of invoking local objects, clients must deal with additional exceptions that can occur during a remote method invocation.
Introduction to RMI
Java’s Remote Method Invocation (RMI) makes it possible for code in an object running in one Java Virtual Machine (JVM) to invoke methods in an object running in another JVM. The two JVMs may be running as separate processes on the same computer, or may be running on different computers connected by a TCP/IP network.
Since the Internet is a TCP/IP network, this means that a client machine anywhere in the world has the capability of invoking methods on an object on a server anywhere in the world. The potential benefits of such operation are staggering to the imagination.
The machine with the object whose methods are invoked remotely is the server, and the machine invoking the methods on the remote object is the client.
The two utility programs are:
- rmic.exe – a program that produces stub and skeleton class files used by the client and the server.
- rmiregistry.exe – a program that creates and maintains a registry of objects on a server whose methods can be invoked remotely by clients.
Developing RMI Application |
Remote Method Invocation
- Allows objects in different JVM’s belonging to different hosts to send and receive messages
- It uses the TCP protocol for transporting information
- Makes it easy to implement distributed applications
- Objects that are exported for remote access must implement the interface RemoteInterface
- All the methods that are to be invoked remotely must throw a RemoteException
- The rmic compiler is used to create the stub and the skeleton for implementing the server class
RMI Terminology
- Local objects are objects that execute on the local machine
- Remote objects are objects that execute on remote machines
- The Remote Registry Server is responsible for registering the exposed objects
- A stub is a local object on the client’s machine that acts as a proxy for a remote object which is called as a skeleton
- The remote reference layer controls the communication between the stub and the skeleton
RMI Packages
Available for remote method invocation in Java are:
- java.rmi – provides the Remote interface, a class for accessing the remote names registered on the server, and a security manager for RMI
- java.rmi.registry – provides classes and interfaces that are used by the remote registry
- java.rmi.server – provides classes and interfaces used to implement remote objects, stubs and skeletons, and provide support for RMI communication
- java.rmi.dgc– provides classes and interfaces that are used by the RMI-distributed garbage collector
The java.rmi Package
Declares the Remote interface, and the Naming and RMISecurityManager classes
- The Naming class provides the following static methods for accessing remote objects through URLs:
–rebind() – binds a remote object name to a specified URL, and is normally used by the Server object
–unbind() – removes the binding between an object name and a URL
–lookup() – returns the remote object specified by a URL, and is normally used by the client object
–list() – returns the list of URLs that are currently known to the RMIRegistry - The RMISecurityManager class defines the default security policy for remote object stubs in an application
- Applets use the AppletSecurityManager class for RMI
- The setSecurityManager() method of the System class is used to set an RMISecurityManager object as the security manager to be used for RMI stubs
The java.rmi.registry Package
Has the following interfaces and classes:
- Registry and the RegistryHandler interfaces – are used to register and access remote objects by a name
- RemoteObject class – implements the Remote interface and provides remote implementation of the Object class
- RemoteServer class – extends the RemoteObject class. Is a common class subclassed by specific types of remote objects
- UnicastRemoteObject class – extends the RemoteServer class and provides the default RemoteObject implementation. The subclass can use RMI’s default socket-based transport for communication by extending from it
- RemoteStub class – provides an abstract implementation of the local objects. The static setRef() method is used to associate a local object with its corresponding remote object
- RemoteCall interface – provides methods that are used by all the stubs and skeletons of RMI
- Skeleton interface – is implemented by the remote skeletons which provides the methods to access the remote object’s methods
- Unreferenced interface – is implemented by the remote object and enables it to determine when the client references is lost
The java.rmi.dgc Package
- Has classes and interfaces that are used by the distributed garbage collector
- Has the Lease class that creates objects which are used to keep track of object references
- Has the dirty() method which is used to indicate that a client is referencing a remote object
- Has the clean() method that is used to indicate that a remote reference has been completed
Steps for Creating a Distributed Application Using RMI
- A remote interface needs to be defined that specifies the methods that can be invoked remotely
- Implement the remote interface methods in a server implementation program
- Code the client to test the server
- Compile the source files
- Generate the stub and the skeleton using the rmic compiler
- Create a security policy that will grant the rights for specific resources
- Start the RMI remote registry, the server and the client
Defining Functionality for the Remote Interface
- The remote interface declares the methods that are called from the JVM of the client machine
- The remote interface HelloServer given below defines a method that returns the string “Hello to Client from Server”
package source.rmi.server; //Defining the package
import java.rmi.*; //Importing the necessary packages
public interface HelloServer extends Remote
{
String DisplayHello() throws RemoteException;
}
Implementing the Remote Interface
- In the code given below the HelloServerImpl class extends the UnicastRemoteObject class.
- It can be used to create the remote object that uses RMIs default socket-based transport for communication and runs all the time
package source.rmi.server;
import java.rmi.*;
public class HelloServerImpl extends UnicastRemoteObject implements HelloServer
{
}
Defining the Constructor for the Remote Object
- The constructor of the implementation class of the remote interface is given below:
public HelloServerImpl() throws RemoteException
{
super();
}
Providing Implementation for Remote Methods
- The implementation class for a remote object contains the code that implements the remote method declared in the remote interface.
- The implementation of the DisplayHello() method is given below:
public String DisplayHello() throws RemoteException
{
return “Hello RMI”
}
Creating and Installing the Security Manager
- A java.lang.SecurityManager object determines whether an operation that a program intends to perform is permitted
- The main() method of the server first needs to create and install a security manager using the RMISecurityManager class
System.setSecurityManager(new RMISecurityManager());
Creating an Instance of the Remote Object
- The main() method of the server needs to create an instance of the server which implements the remote interface to provide the service.
- Once created, the server object is ready to accept incoming requests
HelloServerImpl instance = new HelloServerImpl();
Registering the Remote Object
- For a client to access the method of a remote object, it should obtain a reference to the remote object using the Remote Object Registry
- The code which registers the name of the remote object to the RMI registry is:
Naming.rebind(“HelloServer”,instance);
- The rebind() method takes two parameters:
- The first parameter is a URL string that contains the location and name of the remote object which listens at the default port number 1099
- The second parameter is a reference to the object implementation.
Generating the Skeleton and the Stub
- The rmic compiler is used to generate the skeleton and the stub classes.
Syntax
rmic <fully qualified class name>
For example,
rmic source.rmi.HelloServerImpl will create the
HelloServerImpl_Skel.class and the HelloServerImpl_Stub.class files
Creating a Security Policy
- A policy file is a plain text file created by any text editor or by the graphical Policy Tool utility
- A file named .java.policy that contains the code to grant permissions to the required objects has to be created under users HOME directory
- Involves the following steps:
- start the policy tool utility
- grant the required permission
- save the policy file
Starting the Policy Tool
- To start the policy tool, type the command policytool at the command prompt.
- This will display the Policy Tool window as below:
Granting the Required Permissions
- To grant the required permissions, click the Add Policy Entry button in the Policy Tool window.
- This will display the Policy Entry window, which will allow you to add the required permissions
Choose the Add Permission button to display the Permissions dialog box as shown below:
Choose SocketPermission from the Permission: list box
Type the following in the text box to the right of Target Name:
*:1024-65535
- This specifies that you are granting the right to use sockets on any IP address and the port numbers ranging from 1024 to 65535
- Specify the Actions: as connect, resolve
- Click the OK button to close the Permission dialog box
- Choose the Save As option from the File menu
- Enter the filename as .java.policy and specify your home directory as the location
Starting the Remote Object Registry
- The RMI Registry is a server-side service that allows remote clients to get a reference to a remote object
- To start the RMI Registry on the server, execute the start rmiregistry command at the command prompt.
- By default, the registry runs on port 1099
- To start the RMI Registry on a different port, the port number has to be specified in the command line as given below:
start rmiregistry 1243
Starting the Server
- Start the server using the java command, after setting the codebase property.
- The codebase property must contain the location of the stub class so that the stub class is automatically downloaded to the client
- The next option that you need to specify is the security policy
- Given below is the command to start the server:
java Djava.rmi.server.codebase =
file:///<directory path to the file> -Djava.security.policy = .java.policy
<fully qualified classname>
Creating an RMI client
- Reference to the Remote Object is obtained through the RMI registry running in the server using the lookup() method of the Naming class
- The lookup() method takes the name registered in the server as a parameter. It takes care of:
- creating a stub instance to connect to the rmiregistry process running in the server
- receives the stub instance and loads the stub class from the codebase property
Syntax
HelloServer server = (HelloServer)
Naming.lookup(“HelloServer”);
Invoking the Remote Method
- RMI serializes and returns a string
- RMI deserializes the string and stores it
- Refer to the following code snippet below:
public static void main(String arg[])
{
try
{
HelloServer server = (HelloServer) Naming.lookup("HelloServer");
String str=server.DisplayHello();
System.out.println(str);
}
catch(Exception e)
{
System.out.println(e);
}
}
Starting the Client
- To start the client, use the command given below:
java <fully qualified class name>
RMI Example |
HelloServer Interface – HelloServer.java
package com.javaskool;
import java.rmi.*;
public interface HelloServer extends Remote
{
String sayHello() throws RemoteException;
}
RMI Server Program – RMIServer.java
package com.javaskool;
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
public class RMIServer extends UnicastRemoteObject implements HelloServer
{
public RMIServer() throws RemoteException
{
super();
}
public String sayHello() throws RemoteException
{
return "Hello to Client from javaskool Server"; }
public static void main(String args[])
{
//System.setSecurityManager(new RMISecurityManager());
try
{
RMIServer instance = new RMIServer();
Naming.rebind("HelloServer",instance);
System.out.println("Server Registered......");
}
catch(Exception e)
{
System.err.println(e);
}
}
}
RMI Client Program – RMIClient.java
package com.javaskool;
import java.rmi.*;
public class RMIClient
{
public static void main(String arg[])
{
try
{
com.javaskool.HelloServer server = (com.javaskool.HelloServer)Naming.lookup("HelloServer");
String str=server.sayHello();
System.out.println(str);
}
catch(Exception e)
{
System.out.println(e);
}
}
}
Steps to Compile , run , Start RMIServer and RMIClient
follow steps as screen shots below
Recent Comments