Remote Method Invocation (RMI) is the pillar of Enterprise JavaBeans and a convenient way to build distributed Java applications. RMI is very easy to use, but it is very powerful.
The foundation of RMI is interfaces. the RMI architecture is based on an important principle: the specific implementation of defining interfaces and defining interfaces is separated. The following example shows how to create a simple Remote Computing Service and a customer program that uses it.
A normally working RMI system consists of the following parts:
● Remote service interface definition
● Specific implementation of remote service interfaces
● Pile (stub) and framework (skeleton) files
● A server running remote services
● An RMI naming service that allows the client to discover this remote service
● File provider (an HTTP or FTP Server)
● A client program that requires this remote service
Next we will build a simple RMI system step by step. First, create a new folder on your machine to store the files we created. For simplicity, we only use one folder to store the client and server code, and run the server and client in the same directory.
If all the RMI files have been designed, you need to take the following steps to generate your system:
1. Compile and compile the Java code of the interface
2. Compile and compile the Java code implemented by the interface
3. Generate stub and skeleton files from the interface implementation class.
4. Compile the master program of the remote service
5. Write the RMI client program
6. Install and run the RMI system
1. Interface
The first step is to establish and compile the Java code of the service interface. This interface defines all functions that provide remote services. The following is the source program:
// Calculator. Java
// Define the interface
Import java. RMI. Remote;
Public interface calculator extends remote
{
Public long add (long a, long B)
Throws java. RMI. RemoteException;
Public long sub (long a, long B)
Throws java. RMI. RemoteException;
Public long MUL (long a, long B)
Throws java. RMI. RemoteException;
Public Long Div (long a, long B)
Throws java. RMI. RemoteException;
}
Note that this interface is inherited from remote. Each defined method must throw a RemoteException object.
Create this file, store it in the directory just now, and compile it.
> Javac calculator. Java
2. Specific implementation of interfaces
Next, we need to write the specific implementation of the remote service. This is a calculatorimpl file:
// Calculatorimpl. Java
// Implementation
Import java. RMI. server. unicastremoteobject
Public class calculatorimpl extends unicastremoteobject implements Calculator
{
// This implementation must have an explicit constructor and throw a RemoteException.
Public calculatorimpl ()
Throws java. RMI. RemoteException {
Super ();
}
Public long add (long a, long B)
Throws java. RMI. RemoteException {
Return A + B;
}
Public long sub (long a, long B)
Throws java. RMI. RemoteException {
Return A-B;
}
Public long MUL (long a, long B)
Throws java. RMI. RemoteException {
Return a * B;
}
Public Long Div (long a, long B)
Throws java. RMI. RemoteException {
Return A/B;
}
}
Similarly, save the file in your directory and compile it.
This implementation class uses unicastremoteobject to connect to the RMI system. In our example, we directly inherit from the class unicastremoteobject. In fact, we do not have to do this. If a class is not inherited from unicastrmeoteobject, you must use its exportobject () method to connect to RMI.
If a class inherits from unicastremoteobject, it must provide a constructor and declare to throw a RemoteException object. When this constructor calls super (), it activates the code in unicastremoteobject for a long time to complete the RMI connection and remote object initialization.
3. stubs and skeletons)
The next step is to use the RMI compiler rmic to generate the pile and framework files. This compilation runs on the remote service implementation class file.
> Rmic calculatorimpl
Run the above command in your directory. After successfully executing the above command, you can find a file named calculator_stub.class. If you are using java2sdk, you can also find the file named calculator_skel.class.
4. Host servers
The remote RMI service must run on a server. The calculatorserver class is a very simple server.
// Calculatorserver. Java
Import java. RMI. Naming;
Public class calculatorserver {
Public calculatorserver (){
Try {
Calculator c = new calculatorimpl ();
Naming. rebind ("RMI: // localhost: 1099/calculatorservice", C );
} Catch (exception e ){
System. Out. println ("trouble:" + E );
}
}
Public static void main (string ARGs []) {
New calculatorserver ();
}
}
Create this server program, save it to your directory, and compile it.
5. Client
The client source code is as follows:
// Calculatorclient. Java
Import java. RMI. Naming;
Import java. RMI. RemoteException;
Import java.net. malformedurlexception;
Import java. RMI. notboundexception;
Public class calculatorclient {
Public static void main (string [] ARGs ){
Try {
Calculator c = (calculator)
Naming. Lookup (
"RMI: // localhost
/Calculatorservice ");
System. Out. println (C. Sub (4, 3 ));
System. Out. println (C. Add (4, 5 ));
System. Out. println (C. Mul (3, 6 ));
System. Out. println (C. Div (9, 3 ));
}
Catch (malformedurlexception Murle ){
System. Out. println ();
System. Out. println (
"Malformedurlexception ");
System. Out. println (Murle );
}
Catch (RemoteException re ){
System. Out. println ();
System. Out. println (
"RemoteException ");
System. Out. println (re );
}
Catch (notboundexception NBE ){
System. Out. println ();
System. Out. println (
"Notboundexception ");
System. Out. println (NBE );
}
Catch (
Java. Lang. arithmeticexception
AE ){
System. Out. println ();
System. Out. println (
"Java. Lang. arithmeticexception ");
System. Out. println (AE );
}
}
}
Save the client program to your directory (note that this directory is created at the beginning, and all our files are under that directory) and compile it.
6. Run the RMI system
Now we have created all the files required to run this simple RMI system. Now we can finally run this RMI system! To enjoy it.
We run this system in the command console. You must open three console windows, one running server, one running client, and one running rmiregistry.
First, run the registration program rmiregistry. You must run the registration program in the directory containing the class you just wrote.
> Rmiregistry
Well, if this command is successful, the Registration Program has started to run. Don't worry about it. Now switch to another console. In the second console, we run the server calculatorservice, because the RMI security mechanism will work on the server, you must add a security policy. The following are examples of corresponding security policies:
Grant {
Permission java. Security. allpermission "","";
};
Note: This is the simplest security policy that allows anyone to do anything. For your more critical applications, you must specify more detailed security policies.
To run the server, you need all the class files except the client class (calculatorclient. class. After confirming that the security policy is in the policy.txt file, run the following command to run the server.
> JAVA -djava.security.policypolicpolicy.txt calculatorserver
The server started to work and loaded the interface implementation to the memory to wait for the client connection. Now switch to the third console and start our client.
To run client programs on other machines, you need a remote interface (calculator. Class) and a stub (calculatorimpl_stub.class ). Run the following command to run the client:
Prompt> JAVA -djava.security.policypolicpolicy.txt calculatorclient
If all of these operations are successful, you should see the following output:
1
9
18
3
If you see the above output, congratulations, you have succeeded. You have successfully created an RMI system and made it work correctly. Even if you are running on the same computer, RMI uses your network stack and TCP/IP for communication, and runs on three different Java virtual machines. This is a complete RMI system.