搬运维基百科的代码,已实际测试过。记录下一些注意事项
远程服务接口需要继承 java.rmi.Remote 接口方法需要申明抛出java.rmi.RemoteException,接口方法参数或返回值的class类型需要实现序列化接口即java.io.Serializable或者为八种基本数据类型。远程调用时是通过序列化的方法传递数据,int类型可能会被转换为double类型远程调用参数或返回值的class类型必须两个jvm中都有。这里的class类型是实例的具体类型,而不是申明类型,匿名类,由spring框架切面生产的代理类都会报错。
下述代码仅为本地localhost测试,实际不同主机使用时,需要考虑权限问题。
package study.rmi; import java.rmi.Remote; import java.rmi.RemoteException; public interface RmiServerIntf extends Remote { public String getMessage() throws RemoteException; } package study.rmi; import java.rmi.Naming; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; import java.rmi.server.UnicastRemoteObject; public class RmiServer extends UnicastRemoteObject implements RmiServerIntf { public static final String MESSAGE = "Hello World"; public RmiServer() throws RemoteException { super(0); // required to avoid the 'rmic' step, see below } @Override public String getMessage() { return MESSAGE; } public static void main(String args[]) throws Exception { System.out.println("RMI server started"); try { //special exception handler for registry creation LocateRegistry.createRegistry(1099); System.out.println("java RMI registry created."); } catch (RemoteException e) { //do nothing, error means registry already exists System.out.println("java RMI registry already exists."); } //Instantiate RmiServer RmiServer obj = new RmiServer(); // Bind this object instance to the name "RmiServer" Naming.rebind("//localhost/RmiServer", obj); System.out.println("PeerServer bound in registry"); } } package study.rmi; import java.rmi.Naming; public class RmiClient { public static void main(String args[]) throws Exception { RmiServerIntf obj = (RmiServerIntf) Naming.lookup("//localhost/RmiServer"); System.out.println(obj.getMessage()); } }