RMI in Java (remote method call) __java

Source: Internet
Author: User
Tags abstract rand stub
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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.