RMI Basic Concepts
RMI (remote method invocation), which is implemented from java1.1, greatly enhances the ability of Java to develop distributed applications. RMI has a strong dependency on the interface, when we need to create a remote object, we pass an interface to hide the implementation details of the grassroots, so the client gets a handle to the remote object, they really get the interface handle, and then the local code through the interface to manipulate the remote object. It is easy to implement distributed Java applications through RMI programming.
When you create a remote interface, you must observe the following rules: The remote interface must be a public property (not "package access"), or the client will get an error once it attempts to load a remote object that implements the remote interface; The remote interface must extend the (extends) interface Java.rmi.Remote, in addition to the exception that the application itself may throw out, Each method in the remote interface must also declare a java.rmi.RemoteException in its own throws clause (otherwise the java.rmi.server.ExportException will be thrown when the server is run); A remote object that is passed as a parameter or return value must be declared as a remote interface and cannot be declared as an implementation class. The RMI Development Step first creates a remote interface and declares a remote method that needs to be inherited from Java.rmi.Remote (client and server need to share this interface); This class must inherit from Java.rmi.server.UnicastRemoteObject (only server needs this implementation class, client can not); Write server, bind port, register object, write client, listen on port and find object. instance
Write a basic, Bean object (person) to be transferred, which can be a basic data type or a custom type that implements Java.io.Serializable.
Package com.liu.models;
public class Person implements java.io.Serializable {
private static final long serialversionuid = 1L;
private int id;
private String name;
private int age;
public int getId () {return
ID;
}
public void setId (int id) {
this.id = ID;
}
Public String GetName () {return
name;
}
public void SetName (String name) {
this.name = name;
}
public int getage () {return age
;
}
public void Setage (int age) {
this.age = age;
}
Public String toString () {return
"ID:" + getId () + "Age:" + getage () + "name:" + getName ();
}
}
Create the remote interface Personservice, which is common to server and client, must inherit from remote, and all its methods must throw java.rmi.RemoteException.
Package com.liu.models;
Import Java.rmi.Remote;
Import java.rmi.RemoteException;
Import java.util.List;
Public interface Personservice extends Remote {public
list<person> getpersonlist (int n) throws remoteexception;
}
To create a remote interface implementation class Persionserviceimpl, you need to inherit from the UnicastRemoteObject, this class only needs the server to have.
Package com.liu.models;
Import java.rmi.RemoteException;
Import Java.rmi.server.UnicastRemoteObject;
Import java.util.List;
public class Personserviceimpl extends UnicastRemoteObject implements personservice{
private static final long Serialversionuid = 1L;
Public Personserviceimpl () throws RemoteException {
super ();
}
@Override public
list<person> getpersonlist (int n) throws RemoteException {
System.out.println ("Get Persons ");
return utils.createpersonlist (n);
}
}
Create server-side code, bind specific ports, and register implementation classes for remote interfaces.
Package com.liu.server;
Import Java.rmi.registry.LocateRegistry;
Import Javax.naming.Context;
Import Javax.naming.InitialContext;
Import Com.liu.models.PersonServiceImpl;
Import Com.liu.models.PersonService;
public class Server {public
static void Main (string[] args) {
try {
Personservice personservice = new PersonS Erviceimpl ();
Locateregistry.createregistry (6600);
This method can also implement binding
//naming.rebind ("Rmi://127.0.0.1:6600/personservice", personservice);
Context NamingContext = new InitialContext ();
Namingcontext.rebind ("Rmi://127.0.0.1:6600/personservice", personservice);
System.out.println ("Service start!");
} catch (Exception e) {
e.printstacktrace ();}}}
Create the client-side code, obtain the remote implementation class for the remote interface, and manipulate the remote interface through the remote interface.
Package com.liu.client;
Import java.rmi.Naming;
Import java.util.List;
Import Com.liu.models.Person;
import Com.liu.models.PersonService;;
public class Client {public
static void Main (string[] args) {
try{
//remote object invocation port and registration class
Personservice Personservice= (Personservice) naming.lookup ("Rmi://127.0.0.1:6600/personservice");
list<person> personlist = personservice.getpersonlist (5);
for (person person:personlist) {
System.out.println (person);
}
} catch (Exception ex) {
ex.printstacktrace ();}}}
It also adds a helper class for the implementation class to randomly generate the person object.
Package com.liu.models;
Import java.util.ArrayList;
Import java.util.List;
Import Java.util.Random;
Import Com.liu.models.Person;
public class Utils {public
static final Random rand = new Random (a);
public static final String names[] = {"AAA", "BBB", "CCC", "ddd", "Eee", "fff", "GGG"};
public static list<person> createpersonlist (int n) {
list<person> List = new arraylist<> ();
for (int i = 0, I < n;i++) {person
p = new Person ();
P.setid (i);
P.setage (rand.nextint);
P.setname (Names[rand.nextint (names.length)));
List.add (P);
}
return list;
}
How to run methods to run in the command line
The server and client folders are created first and will be com.liu.models. person. Java, com.liu.models. personservice. Java, com.liu.models. Persionserviceimpl. Java, com.liu.models. Utils. Java and Com.liu.server. server. Java is placed in the server folder and will be com.liu.models. person. Java, com.liu.models. Personservice. Java and com.liu.client. client. Java is put into the client folder.
Then compile server:server> javac Com/liu/server/server.java in the Server folder;
Compile Client:client>javac Com/liu/client/client.java in the Client folder;
Finally, start Server:server>java com/liu/server/server, then run Client:client>java com/liu/client/client.
how to run under Eclipse
Create three projects, structure as shown:
In addition, you need to add a reference to the project models in the Modelsserver and modelsclient projects.
You can finally run the server and then run the client to see a similar result with the command line.
Two possible errors 1. If you do not define person as serializable, the java.rmi.UnmarshalException exception will occur;
/* person does not realize java.io.Serializable caused by the exception java.rmi.UnmarshalException:error unmarshalling return; Nested exception is:java.io.WriteAbortedException:writing aborted; Java.io.NotSerializableException:com.liu.models.Person at Sun.rmi.server.UnicastRef.invoke (Unknown Source) at Java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod (Unknown Source) at Java.rmi.server.RemoteObjectInvocationHandler.invoke (Unknown Source) at Com.sun.proxy. $Proxy 0.getPersonList ( Unknown Source) at Com.liu.client.Client.main (client.java:14) caused by:java.io.WriteAbortedException:writing aborted; Java.io.NotSerializableException:com.liu.models.Person at Java.io.ObjectInputStream.readObject0 (Unknown Source) at Java.io.ObjectInputStream.readObject (Unknown source) at Java.util.ArrayList.readObject (Unknown source) at Sun.reflect.NativeMethodAccessorImpl.invoke0 (Native method) at Sun.reflect.NativeMethodAccessorImpl.invoke ( Unknown Source) at Sun.reflect.DelegatingMethodAccessorImpl.invoke (UnKnown source) at Java.lang.reflect.Method.invoke (Unknown source) at Java.io.ObjectStreamClass.invokeReadObject ( Unknown source) at Java.io.ObjectInputStream.readSerialData (Unknown source) at Java.io.ObjectInputStream.readOrdinaryObject (Unknown Source) at Java.io.ObjectInputStream.readObject0 (Unknown SOURCE) at Java.io.ObjectInputStream.readObject (Unknown source) at Sun.rmi.server.UnicastRef.unmarshalValue (Unknown Source) ... 5 More * *
2. If a remote method that does not define Personservice throws a remoteexception, it can cause run-time java.rmi.server.ExportException.
/* Personservice remote method is missing throws RemoteException statement exception Java.rmi.server.ExportException:remote object implements illegal Remote interface; Nested exception Is:java.lang.IllegalArgumentException:illegal Remote method Encountered:public abstract Java.util.Li
St Com.liu.models.PersonService.getPersonList (int) at Sun.rmi.server.UnicastServerRef.exportObject (Unknown Source) At Java.rmi.server.UnicastRemoteObject.exportObject (Unknown Source) at Java.rmi.server.UnicastRemoteObject.exportObject (Unknown Source) at Java.rmi.server.unicastremoteobject.<init > (Unknown Source) at java.rmi.server.unicastremoteobject.<init> (Unknown source) at Com.liu.models.persionserviceimpl.<init> (persionserviceimpl.java:11) at Com.liu.server.Server.main ( SERVER.JAVA:14) caused By:java.lang.IllegalArgumentException:illegal remote method Encountered:public Abstract
Java.util.List com.liu.models.PersonService.getPersonList (int) at Sun.rmi.server.Util.checkMethod (Unknown Source) At Sun.rmi. server. Util.getremoteinterfaces (Unknown source) at Sun.rmi.server.Util.getRemoteInterfaces (Unknown source) at Sun.rmi.server.Util.createProxy (Unknown Source) ... 7 More * *
SummaryThe above approach is the easiest way to achieve RMI, and there are some statements on the Web that follow these steps:
Define the remote interface, implement the remote interface implementation class, define the client and server, use rmic to generate root (Stub) and dry (skeleton) files for the remote interface, use the Rmiregistry program to open the server RMI registry, run server, Run the client. The above method requires extra generation of root (Stub) and dry (skeleton) files, which is obsolete and is now not required for these two files. In addition, running RMI requires that the Rmiregistry program be turned on, but there are two ways to open it: Run Rmiregistry on the direct command line; use Locateregistry.createregistry (port) in the program To open (that is, the way the above program is used).
Code Download: Javarmi Sample Program
References: Learning notes: JAVA RMI Remote Method invocation Simple instance
RMI Instance (ii) (No DOS run rmic and rmiregistry)
"Thinking in Java" third edition of Network programming related content