`

RMI 入门

rmi 
阅读更多

RMI : remote method invocation,远程方法调用。

 

有Client object, client helper(Stub), Service Helper(Skeleton), service object四个参与者。前两个是客户端,后两个是服务器端的,两个helper都是用于对信息的包装(pack)和解包(unpack),以方便网络传输。

 

五个步骤:

一,make a remote interface(MyService.java)。定义服务器端提供的方法。远程客户就是调用这个接口的方法。Stub和Skeleton都会实现这个接口。

 

二,make a remote implementation(MyServiceImpl.java)。这是实际的服务类,实际的操作由这个类来实现。

 

三,generate the stubs and skeletons using rmic。在cmd下输入: rmic MyServiceImpl,会产生MyServiceImpl_Stub.class 和 MyServiceImpl_Skel.class两个类文件,rmic是jdk自带的一个工具。

 

四,start the RMI registry(rmiregistry),在cmd输入:rmiregistry,启动这项服务后,客户端就可以通过这项服务找对对应的Proxy/client helper(stub)。

 

五,start the remote service。cmd输入:java MyServiceImpl,就会在rmi registry里注册这个服务,令这服务可以被远程调用。

 

以建立一个向服务器端请求获取一个String为实例,具体说明:

初次尝试可以在同一机器上进行,但在实际应用中,应在不同机器上,才能体现rmi的用处

 

在服务器端的操作:

1.建立远程接口。

package chapter11.proxy.rmi;

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface MyRemote extends Remote{
	public String sayHello() throws RemoteException;
}

 说明:远程接口,是客户端调用服务器端的接口,就是这个接口提供什么方法,那客户端也就只能调用远程对象的这些方法。接口需要继承Remote类,查看Remote类源码,可知它只是个空的接口,没任何方法在里面,在rmi调用中,这是作为一个标志接口("marker" interface)。另外每个远程方法都必须抛出RemoteException,因为每个远程方法都被认为是不安全的。还有远程方法的返回值和参数的类型必须是可序列化的(serializable,int,char,long等所有原始类型和jdk自带的集合类型都是可序列化,如果是自己创建的类,就必须extendsSerializable接口)。本例中的sayHello()的返回值String是可序列化的。

 

2.实现远程接口。

package chapter11.proxy.rmi;

import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;


public class MyRemoteImpl extends UnicastRemoteObject implements MyRemote{

	public MyRemoteImpl() throws RemoteException{
	}
	
	@Override
	public String sayHello() throws RemoteException {
		return "server syas, 'hey'";
	}
	
	public static void main(String[] args) {
		try{
			MyRemote service = new MyRemoteImpl();
			Naming.rebind("RemoteHello", service);
		}catch(Exception e){
			e.printStackTrace();
		}
	}

}

 新建一个类实现远程接口。继承UnicastRemoteObject 是为了继承一些作为一个远程服务对象的功能,该类提供四个静态方法:

RemoteStub exportObject(Remote obj);(其中一个),可导出(export)远程对象。

另外因为UnicastRemoteObject类的构造器抛出RemoteException,所以其子类的构造器都需要抛出同样的异常(Java语法所定,因为实例化子类前,jvm会实例化其父类)。

main方法是在Rmi Registry里注册这个服务的,Main方法可以放到另外一个类里执行,不一定要放要实现类里,这里为了演示简单而放这。

注册通过java.rmi.Naming类的静态方法rebing(String name, Remote obj)。name是客户端获取的服务的名称,obj是service类。

 

3.生成stubs和skeleton(在Jdk5以后,默认是-v1.2[rmic 的stub协议版本],只会生成stub)。

这一步,需要要用到jdk自带的工具:rmic。先确定你系统的Path环境变量里已经设了%java_home%\bin(或不设,就把工具的路径全称写全)。rmic命令如下说明:

 

rmic 参数: 
-classpath <path> 指定查找输入类文件的位置; 
-d <dir> 指定存放生成文件的位置

对于没放在package里的类:直接进入.class目录,
运行 rmic MyRemoteImpl,会在.class目录生成xx_stub.class文件

对于package chapter11.proxy.rmi下的MyRemoteImpl.class。(本例子就是这情况)
就是bin\chapter11\proxy\rmi\MyRemoteImpl.class。(在eclipse的.class文件默认放在bin目录)
进入对应的bin目录,运行:rmic chapter11.proxy.rmi.MyRemoteImpl


就会在bin\chapter11\proxy\rmi\目录下生成xx_stub.class文件。

可以通过 -d <dir>,配置生成stub的目录,但生成的目录是上层目录,在dir下会
根据Package信息,自动创建目录层次:dir\chapter11\proxy\rmi\xx_stub.class。
 

我是开始以为对.java文件调用rmic。在src目录下(eclipse建的工程),试过很多次后,发现我错了,原来是要cmd进入到.class的bin目录里调用rmic命令。并且rmic 命令中的文件名不需要.class后缀。调用后会生成

(总之,在这里提出一点很重要的,所有的命令都要在bin目录下执行 ,这样才能保证不浪费时间ClassNotFound之类的错误,我在cmd下运行命令时,由于有时切换到不同目录,导致浪费很多时间在尝试。。。人生苦短啊,大家别浪费时间在低级错误上)

 

4.生成xx_stub.class文件后(stub.class应该在bin目录中,与MyRemoteImpl同一目录),在bin目录中执行命令:

 rmiregistry

这应该在一个新的终端执行。这就在服务器端启动了一个“注册管理器”(我这样称呼的,书上是这样描述的:RMI registry(on server))。“注册管理器”是负责管理各种服务对象的(MyRemoteImpl)和返回对应stub对象。

 

5.启动服务。在cmd运行: java chapter11.proxy.rmi.MyRemoteImpl 。记住是在bin目录里运行该命令。

 

6.好了,最后就写客户端代码来测试。(接下来的代码,可以在客户端写,不需要在服务器端写,但在客户端需要MyRemote.class和MyRemoteImpl.class两个类文件)

package chapter11.proxy.rmi;

import java.rmi.Naming;

public class MyRemoteClient {
	public static void main(String[] args) {
		try {
			MyRemote service = (MyRemote) Naming
					.lookup("rmi://127.0.0.1/RemoteHello");
			String s = service.sayHello();
			System.out.println(s);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}
}

对于客户端代码,首先通过java.rmi.Naming的lookup(url)方法来找到服务器的服务对象,接着rmi registry返回该对象,这样客户端就保存一个stub(服务对象,相当于MyRemoteImpl的引用) ,客户端这时就可以调用服务对象的方法sayHello()来返回结果。

 

以下是三个cmd的内容:

rmi registry:

D:\My Documents\chow\workspace\headfirstDf\bin>rmiregistry

 

server:(客户端调用两次,所以打印两次request...)

D:\My Documents\chow\workspace\headfirstDf\bin>java chapter11.proxy.rmi.MyRemoteImpl
get a sayHello request...
get a sayHello request...
 

client:

D:\My Documents\chow\workspace\headfirstDf\bin>java chapter11.proxy.rmi.MyRemote
Client
server syas, 'hey'

D:\My Documents\chow\workspace\headfirstDf\bin>java chapter11.proxy.rmi.MyRemote
Client
server syas, 'hey'

 

geek bits:

这里提到客户端需要服务器端的class文件,可以简单地从服务器端发送到客户端。

在jdk5后,还有一种方法,叫“动态类下载”(dynamic class downloading)。客户端通过url来找到class文件,会通过http的get来获取类文件。

 

 

分享到:
评论

相关推荐

    RMI入门好例子

    这个“RMI入门好例子”旨在帮助初学者理解并实践RMI的基本原理和操作流程。 首先,RMI的核心思想是通过接口实现远程对象的透明调用。在示例中,`rmidemo`可能包含了服务器端的代码,它会定义一个接口,例如`...

    JAVA RMI入门教程

    【JAVA RMI入门教程】 Java Remote Method Invocation (RMI) 是Java平台中用于构建分布式应用程序的一个关键技术。RMI使得不同Java虚拟机(JVM)之间的对象可以相互通信,从而共享资源和处理能力,实现分布式计算。其...

    java Spring+RMI入门程序源代码

    本项目提供了一个入门级的源代码示例,帮助开发者理解如何在 Spring 环境下集成 RMI 技术。以下是关于这两个技术及其整合的详细知识点: **Spring 框架** 1. **Spring 概述**:Spring 是一个开源的 Java 应用开发...

    RMI入门小结

    这篇博客“RMI入门小结”主要探讨了RMI的基础概念、实现步骤以及常见问题。 1. RMI的基本原理: RMI的核心是通过接口定义服务,服务端实现接口,并将实现类注册到RMI注册表中。客户端通过引用远程接口,即可调用...

    RMI入门例子和教程,分初级、进阶,还有与Spring整合的

    自己收集了一些跑得通的教程,并自己整理给出了,入门例子。包括:最原生的使用javac和rmic的例子;还有进一步的,使用IDM,用代码代理原生rmic编译的例子;还有RMI和Spring整合的例子。 另外附有:例子说明 和 一些...

    java RMI入门例子

    这个"java RMI入门例子"将带你深入理解RMI的工作原理和主要组件。 RMI的核心概念包括: 1. **远程接口**:这是定义远程方法的接口,通常继承自java.rmi.Remote。这些方法声明抛出java.rmi.RemoteException,表示...

    rmi入门

    【标题】:“RMI入门” 远程方法调用(Remote Method Invocation,简称RMI)是Java平台提供的一种用于在分布式环境中实现对象间通信的技术。RMI允许一个Java对象调用网络另一端的Java对象的方法,就像调用本地对象...

    rmi入门(带源码)

    这个“rmi入门(带源码)”的资源可能是一个教学资料或实践项目,帮助初学者理解和应用RMI技术。 首先,我们来详细了解一下RMI的基本概念: 1. **远程接口(Remote Interface)**:这是定义远程方法的接口。它继承了...

    《EJB-RMI入门》

    《EJB-RMI入门》是一本专注于讲解Java企业级应用开发技术的书籍,特别是针对RMI(Remote Method Invocation,远程方法调用)的使用。RMI是Java平台中用于构建分布式应用程序的关键技术,它允许Java对象在不同的Java...

    rmi入门学习,实用的小例子

    ### RMI基础知识与实践 #### 一、Java RMI简介 Java Remote Method Invocation (RMI) 是Java平台提供的一种分布式计算技术,允许开发者在不同Java虚拟机(JVM)之间调用远程对象的方法,从而实现分布式应用程序的...

    JAVA之RMI入门

    简约而不简单的描述了RMI技术,希望对大家有所帮助。

    RMI 入门学习资料

    RMI(Remote Method Invocation)是Java提供的一种用于构建分布式应用程序的机制,它允许Java对象在不同的网络环境中相互调用方法,实现了远程对象间的无缝通信。RMI是在JDK1.1版本中引入的,它是纯Java实现的,遵循...

    RMI入门(二)实例 --- 亲自将代码调试成功

    在本文中,我们将深入探讨Java Remote Method Invocation (RMI)技术,通过一个具体的实例来学习如何设置、构建和调试RMI应用。RMI是Java提供的一种远程对象调用机制,它允许Java对象在不同的JVM之间进行通信。在这个...

    编程语言JavaRMI入门教程.pdf

    本文档是关于Java远程方法调用(Java RMI)的入门教程,适用于JDK 1.1版本。文档首次发布于1997年2月10日,由Sun Microsystems公司版权所有。Sun Microsystems公司授予用户一个全球性的、非独家的、不可转让的、无...

    RMI入门教程

    RMI,远程方法调用(Remote Method Invocation)是Enterprise JavaBeans的支柱,是建立分布式Java应用程序的方便途径。RMI是非常容易使用的,但是它非常的强大。

    rmi学习资料

    "RMI基础教程 - 深海有约 - BlogJava.files"和"rmi入门教程,简单明了(转).files"可能包含了相关的源代码或者图片资源,帮助读者更好地理解和实践RMI编程。 通过深入阅读这些资料,你可以了解如何设置RMI环境,...

    JavaRMI快速入门

    Java Remote Method Invocation(Java RMI)是Java编程语言中用于在网络间进行远程对象调用的技术。它是Java平台的标准部分,允许程序员在分布式环境中调用对象的方法,就像它们在同一台计算机上一样。Java RMI对于...

Global site tag (gtag.js) - Google Analytics