Introduction to Java Remote method call RMI
Java RMI (remote method invocation) is implemented in JDK1.1 with Java, which greatly enhances the ability of Java to develop distributed applications. Java as a rage network development language, its great power is embodied in its powerful development of distributed network applications, and RMI is the development of pure Java Network Distributed Application System is one of the core solutions. It can actually be viewed as a Java version of RPC. However, traditional RPC does not apply well to distributed object system. Java RMI, however, supports communication between program-level objects stored in different address spaces to achieve seamless remote invocation between remote objects. RMI is currently communicating using the Java Remote Message Exchange Protocol (JRMP) (Java sqlremote messaging Protocol). JRMP is a protocol designed specifically for Java remote objects. As a result, Java RMI has the advantages of "Write Once, Run Anywhere" in Java, and is a 100% pure Java solution for distributed Application systems. Application systems developed with Java RMI can be deployed on any platform that supports JRE (Java Run Environment Java, running environment). However, since JRMP is specifically designed for Java objects, RMI has insufficient support for application systems developed in non-Java languages. You cannot communicate with objects that are written in a non-Java language. This paper introduces how to use RMI to implement Java distributed application from the point of view of program.
operating mechanism of RMI system
RMI applications typically include two separate programs: Server programs and client programs. A typical server application will create multiple remote objects so that the remote objects can be referenced, and then wait for the client to invoke the methods of these remote objects. Typically, a client program obtains a reference to one or more remote objects from the server, and then invokes the method of the remote object. RMI provides a mechanism for both server and client communication and information delivery.
In communication with remote objects, RMI uses the standard mechanism: stub and skeleton. The stub of the remote object serves as the client local representative or agent role for the remote object. The calling program will call the method of the local stub, and the local stub will be responsible for executing the method call to the remote object. In RMI, the stub of a remote object is the same as the set of remote interfaces that the remote object implements. When you call a stub's method, the following actions are performed:
(1) Initialize the connection to the remote virtual machine that contains the remote object;
(2) The parameters of the remote virtual machine are grouped (written and transmitted);
(3) Waiting for the method to call the result;
(4) to extract (read) The return value or return the exception;
(5) Returns the value to the calling program.
To show a simpler invocation mechanism to the caller, the stub hides the details of the serialization of parameters and network-level communication. In a remote virtual machine, each remote object can have a corresponding skeleton (no use of skeleton in a JDK1.2 environment). Skeleton is responsible for assigning the call to the actual remote object implementation. It performs the following actions when receiving method calls:
(1) decoding (reading) The parameters of the remote method;
(2) To invoke the method of implementing the actual remote object;
(3) Group (write and transmit) The result (return value or exception) to the calling program. Stubs and skeleton are generated by the Rmic compiler.
Using RMI to write distributed object applications needs to do the following:
(1) Locate the remote object. An application can use one of two mechanisms to get a reference to a remote object. It can either register its remote object with the RMI simple naming tool rmiregistry, or it may pass and return the remote object reference as part of a regular operation.
(2) Communication with the remote object. The details of communication between remote objects are handled by RMI, and for programmers, remote communication looks like a standard Java method call.
(3) Load the class byte code for an object passed as a parameter or return value. Because RMI allows callers to pass a pure Java object to a remote object, RMI provides the necessary mechanism to load both the object's code and the object's data. When the RMI distributed application runs, the server invokes the registration service to associate the name with the remote object. The client uses the name of the remote object to locate the remote object in the registry service on the server, and then calls its method.
Second, the serialization of objects
In RMI Distributed Application Systems, the Java objects passed between the server and the client must be serializable objects. An object that is not serializable cannot be passed in the object stream. Object serialization extends the core Java input/output class and also supports objects. Object serialization supports the encoding of objects and the encoding of objects through which they can be accessed, as well as the complementary reconfiguration of object graphics in the stream. Serialization is used for lightweight persistence and communication with the aid of sockets or remote method calls (RMI). The serialization now includes an API (application programming Interface, Application Interface) that allows the class-independent domain to specify the serialized data for the object, and allows the serialization data field to be written to or read from the stream using an existing protocol. To ensure compatibility with the default read-write mechanism.
To write applications, you must have the ability to store and retrieve Java objects in addition to most transient applications. The key to storing and retrieving objects in a serialized way is to provide enough object state to reconstruct the object. Objects stored to the stream may support either Serializable (serializable) or externalizable (externalized) interfaces. For Java objects, the serialization form must be able to identify and validate the Java class that the object that stores its contents belongs to, and revert the content to a new instance. For serializable objects, the stream will provide enough information to restore the stream's domain to a compatible version of the class. For an Externalized object, the class is solely responsible for the external format of its contents. The purpose of serialization of Java objects is: Provides a simple but extensible mechanism to maintain the type and security attributes of Java objects in a serialized manner, with extended capabilities to support marshalling and reconciliation to meet the needs of remote objects; scalability to support simple persistence of Java objects; You need to provide serialization implementations for each class, and allow objects to define their external formats.
Third, the implementation of distributed applications and operation steps
Java Remote method Call (RMI) provides the remote communication capabilities of the Java program language, which enables programs running on a client computer to invoke objects on a remote server, enabling Java programmers to distribute operations in a networked environment. Creating a simple Java Distributed remote Method Invoker can be done in the following steps:
(1) Defining a remote interface
In Java, a remote object is an instance of a class that implements a remote interface, and the remote interface declares each method to be invoked remotely. When you need to create a remote object, we pass an interface to hide the implementation details of the base, the customer through the interface handle to send messages. The remote interface has the following characteristics:
1, the remote interface must be a public property. If this is not the case, unless the client is in the same package as the remote interface, the call gets the wrong result when an attempt is made to mount a remote object that implements the remote interface.
2, the remote interface must extend the interface java.rmi.Remote.
3. In addition to the specific exceptions to the application itself, each method in the remote interface must declare java.rmi.RemoteException in its own throws clause. (or RemoteException's parent class).
4. A remote object that is passed as a parameter or return value, whether embedded in a direct or local object, must be declared as a remote interface and should not be declared as an implementation class.
The following is the definition of the interface rmisample for the remote interface:
[Java] view plain copy package Com.rim.demo; Import Java.rmi.Remote; Import java.rmi.RemoteException; Public interface Rmisample extends Remote {public int sum (int a, int b) throws remoteexception; }
(2) Implement remote interface
The remote object implementation class must extend the remote object Java.rmi.UnicastRemoteObject class and implement the defined remote interface. The implementation class for the remote object contains code that implements the remote method specified by each remote interface. This class can also contain additional methods, but the customer can only use the methods in the remote interface. Because the customer is a handle to the interface, not which class it is. You must define a constructor for the remote object, even if you are only prepared to define a default constructor that calls the underlying class constructor. Because the underlying class constructor may throw a java.rmi.RemoteException, the java.rmi.RemoteException exception must be thrown even if it is not used. The following is a declaration of the remote object implementation class:[Java] View plain copy package com.rim.demo; import java.rmi.remoteexception; import java.rmi.server.unicastremoteobject; Public class rmisampleimpl extends unicastremoteobject implements rmisample { private static final long serialversionuid = 1l; protected rmisampleimpl () throws RemoteException { super (); } public int sum (int a, int b) { return a + b; } }
(3) Writing server classes
The class that contains the main method can either be the implementation class itself, or it can be entirely another class. The following rmisampleserver creates an instance of a remote object and initiates the registration service from the specified port number through the Createregistry method of the Java.rmi.registry.LocateRegistry class, or by executing the The Rmiregistry command launches the registration service program, and the default running port for the registration service is 1099. The remote object name must be bound to a reference to the remote object: Naming.rebind ("//localhost:8808/sample-server", SERVER);. The following is a declaration of the server class:[Java] View plain copy package com.rim.demo; import java.net.malformedurlexception; import java.rmi.naming; import java.rmi.remoteexception; import java.rmi.registry.locateregistry; public class rmisampleserver { public static void main (String[] args) { try { locateregistry.createregistry (8808); rmisampleimpl server = new rmisampleimpl (); naming.rebind ("//localhost:8808/sampLe-server ", server); } catch (remoteexception e) { E.printstacktrace (); } catch (malformedurlexception e) { e.printstacktrace (); } } }
(4) Writing client classes that use remote services
The main functions of the client class are two, one is to construct the registration service stub program instance through the Naming.lookup method, and the other is to invoke the remote method on the remote object of the server. The following is a declaration of the server class:[Java] View plain copy package com.rim.demo; import java.rmi.naming; import java.rmi.remoteexception; public class rmisampleclient { public static void main (String[] args) { try { String url = "//localhost:8808/sample-server"; RmiSample RmiObject = ( rmisample) naming.lookup (URL); system.out.println (" 1 + 2 = " + rmiobject.sum (1, 2));  &Nbsp; } catch (Remoteexception rex) { system.out.println ("Error in lookup: " + rex.tostring ()); } catch (java.net.malformedurlexception me ) { system.out.println ("malformed url: " + me.toString ()); } catch (java.rmi.notboundexception ne) { system.out.println ("NotBound: " + ne.tostring ()); } } }
(5) Compiling code
To compile the Java source file, run the Javac command:
Javac Rmisample.java Rmisampleimpl.java Rmisampleserver.java Rmisampleclient.java
(6) Create root and stem for remote object implementation:
To create a stub program and skeleton file, run the Rmic compiler with the full name of the compiled class package that contains the remote object implementation.
A stub is a proxy for a remote object on the client, which passes RMI calls to the server-side skeleton (skeleton), which is responsible for passing the call to the actual remote method input as follows:
D:/rmi>rmic-d D:/rmi Rmisampleimpl executes this command, and if Rmic runs successfully, there will be two more new classes in the RMI directory: Rmisampleimpl_stub.class rmisampleimpl_ Skel.class they correspond to stubs (stubs) and skeletons (skeleton) respectively.
(7) Run code:
Run the server-side program: Under Windows, start the Rmisampleserver program in the background by entering the following command:
D:/rmi>java Rmisampleserver
To run the client program:
D:/rmi>java rmisampleclient
Client output: 1 + 2 = 3