1、RMI概述
RMI(Remote Method Invocation)
RMI是分布式对象软件包,方便了JAVA应用程序在多台计算机之间的通信。
必须在jdk1.1以上
RMI用到的类:
java.rmi.Remote
所有可以被远程调用的对象都必须实现该接口
java.rmi.server.UnicastRemoteObject
所有可以被远程调用的对象都必须扩展该类
优点:
方便了JAVA应用程序在多台计算机之间的通信。
只要按照RMI规则设计程序,可以不必再过问在RMI之下的网络细节了,如:TCP和Socket等等。
任意两台计算机之间的通讯完全由RMI负责。调用远程计算机上的对象就像本地对象一样方便。
创建远程方法调用的5个步骤:
1、定义一个继承了远程接口的接口,该接口中的每一个方法必须声明它将产生一个RemoteException异常。
2、定义一个实现该接口的类。
3、使用RMIC程序生成远程实现所需的残根和框架。存根(stub)和框架(skeleton)
4、创建一个客户程序和服务器进行RMI调用。
5、启动Registry并运行自己的远程服务器和客户程序。
对应上面的步骤分析:
1.
所有的RMI操作都应放到try-catch块中:
由于任何远程方法调用实际上要进行许多低级网络操作,因此网络错误可能在调用过程中随时发生.
2.
实现该接口的类(服务端类):必须继承UnicastRemoteObject类。
扩展java.rmi.server.UnicastRemoteObject
UnicastRemoteObject顾名思义,是让客户机与服务器对象实例建立一对一的连接。
3.
在RMI中,客户机上生成的调动调用参数和反调动返回值的代码称为残根。有的书上称这部分代码为“主干”。
服务器上生成的反调动调用参数和进行实际方法调用调动返回值的代码称为框架。
生成残根和框架的工具
Rmic命令行工具(RMI Compiler)
格式:
Rmic classname
4.
第五步、用RmiRegistry找到远程对象
这是一个使用工具,维护文本名和远程对象之间的映射,可以进行远程访问。
如下面的实例:
若手动运行的话,要用:
rmic RemotePrinterImpl 生成Stub 和 Skeleton,它们实际上是远程调用的底层的实现。
start rmiregistry 启动rmi的注册程序,使文本名和远程对象之间的映射,实现远程访问.
java RemotePrinterImpl 启动服务器
java PrintClient 启动客户端
===========================在eclipse中创建RMI实例=================================
(一)创建接口端:
1.
在eclpse中创建一个java project-->project's layout选择分开放置.
2.
在project中,添加一个package-->选择,新建一个 Remote Interface(不是简单的interface),默认完成.
3.
在接口在写入各抽象方法,都要用throws RemoteException.
如下:
public interface RemotePrinter extends Remote {
public int submitJob(String text) throws RemoteException;
public boolean isComplete(int jobID) throws RemoteException;
public String getPrinterStatus() throws RemoteException;
}
(二)创建服务端:
1.
在eclpse中创建一个java project-->project's layout选择分开放置-->切换到project分页,添加接口的project包-->默认完成.
2.
在project中,添加一个package-->新建一个JAVA类-->其父类要选择:UnicastRemoteObject-->其实现的接口,要添加刚创建的接口-->默认完成.
3.
添加自己的构造方法带throws RemoteException.
4.
对接口的方法,进行实现.
5.
在main方法中:
用try..catche,防止有异常.
进行注册: Registry r=LocateRegistry.getRegistry();
进行绑定:r.bind("printer", new RemotePrinterImpl());
输入成功提示:System.out.println("printer server is ready");
6.
生成子根:
点击 server的整个project package,右键-->RMI-->Enabel subs ... -->系统会自动生成子根.
(三)创建客户端:
1.
在eclpse中创建一个java project-->project's layout选择分开放置-->切换到project分页,添加接口的project包-->默认完成.
2.
在project中,添加一个package-->新建一个JAVA类,默认完成.
3.
在main方法中:
用try..catche,防止有异常.
设置安全管理;
连接服务端,利用接口实例化服务端对象;
用新建实例调用各方法进行运用.
如下:
System.setSecurityManager(new RMISecurityManager());
RemotePrinter jprinter=(RemotePrinter)Naming.lookup("rmi://localhost/printer");
int jobID=jprinter.submitJob("hello word");
System.out.println("submitted job's ID: "+jobID);
System.out.println("is complete ? "+jprinter.isComplete(jobID));
System.out.println("printer status: "+jprinter.getPrinterStatus());
(四)
如何运行:
1.
在RMI工具键,下拉选择start locale Registry; -->弹出提示,选择NO.
2.
右键点击SERVER类,用RMI application进行运行--->第一次运行时,会弹出配置对话框-->切换到RMI VM Properties -->选择java.rmi.server.codebase-->add-->点击compute from classpath-->完成即可.
3.
右键点击CLIENT类,用RMI application进行运行--->第一次运行时,会弹出配置对话框-->切换到RMI VM Properties -->选择java.security.policy-->add-->create-->选择CLIENT的project包-->完成即可.
--->上面记录具体是否有错,明晚再试.
===============================将RMI实例打包运行==================================
0.
先要运行:
C:\Program Files\Java\jre1.5.0_09\bin>start rmiregistry
==>
如何避免要进行此步后,才能进行启动SERVER.
原因:
因为在server端的代码中用: Registry r=LocateRegistry.getRegistry();
而要让程序自动启动RMI注册程序: Registry r=LocateRegistry.createRegistry(端口号);
而在客户端: -->也应该添加相应的端口
RemotePrinter jprinter=(RemotePrinter)Naming.lookup("rmi://localhost:8888/printer");
1.
对于SERVER端:
1.1
打包时,也要一起打上接口的包.不能单独只打SERVER包.
1.2
写运行bat时,只须:
java -Xmx350M -jar -Djava.rmi.server.codebase=file:///D:/printer/server/server.jar server.jar
分析:
-Djava.security.policy不是必要的, -->服务器不用去连接其它人,是其它人来连接它的.所以不用安全验证.
而-Djava.rmi.server.codebase则是必要的-->否则会出现找不到存根的错.-->codebase,是给客户端连接用的.所以一定要.
2.
对于CLIENT端: -->可放在任何放不用改路径.
第一种设置方法:
1)
打包时,也要一起打上接口的包.不能单独只打client包.
2)
写运行bat时:
java -Xmx350M -jar -Djava.security.policy=./etc/security.policy client.jar
分析:
-Djava.security.policy=./etc/security.policy:用来通过RMI的安全验证.否则不能进入.
双保险的方式是:
用上面的方式,同时用以下的方式(设置MANIFEST.MF以及添加相应的目录和jar包),两者同时存在.
以下方式,可以不用.
第二种设置方法: -->须加设置且加lib文件夹,但
2.1
打包时,不用也一起打上接口的包.
1.2
写运行bat时,只须:
java -Xmx350M -jar -Djava.security.policy=./etc/security.policy client.jar
分析:
-Djava.security.policy是必要的,
而-Djava.rmi.server.codebase则不是必要的.
1.3
同时要修改MANIFEST.MF:
Manifest-Version: 1.0
Class-Path: lib/interface.jar -->添加项,且在目录下建lib目录,放接口的包
Main-Class: demo.rmi.print.client.PrintClient
===============================另一实例===============================
-------------RMIInterface.java:
public interface RMIInterface extends Remote {
public int submitJob(String text) throws RemoteException;
public boolean isComplete(int jobID) throws RemoteException;
public String getPrinterStatus() throws RemoteException;
}
-----------RMIServer.java
public class RMIServer extends UnicastRemoteObject implements RMIInterface {
private static Logger logger=Logger.getLogger(RMIServer.class.getName());
public RMIServer() throws RemoteException
{
try
{
RMIConfig rmiconfig=new RMIConfig("etc/RMIconfig.cfg");
Registry r=LocateRegistry.createRegistry(Integer.parseInt(rmiconfig.getPort()));
String RMIurl="rmi://"+rmiconfig.getHostName()+":"+rmiconfig.getPort()+"/"+rmiconfig.getServiceName();
logger.info("rebind name :"+RMIurl);
Naming.rebind(RMIurl,this);
}
catch(Exception e)
{
e.printStackTrace();
}
}
public String getPrinterStatus() throws RemoteException {
System.out.println("requested the printer status");
return "OK";
}
public boolean isComplete(int jobID) throws RemoteException {
System.out.println("requested the job status");
return true;
}
public int submitJob(String text) throws RemoteException {
System.out.println("submitted job "+text);
return 0;
}
public static void main(String[] args) {
try
{
File f=new File("etc/log4j.properties");
if(!f.exists())
{
logger.fatal("the log4j.properties is not exist");
System.exit(0);
}
PropertyConfigurator.configure("etc/log4j.properties");
RMIServer server=new RMIServer();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
---------------RMIClient.java
public class RMIClient {
private static Logger logger=Logger.getLogger(RMIClient.class.getName());
public RMIClient()
{
try
{
logger.info("Start RMI Client ......");
RMIConfig rmiconfig=new RMIConfig("etc/RMIconfig.cfg");
System.setSecurityManager(new RMISecurityManager());
String rmiUrl="rmi://"+rmiconfig.getHostName()+":"+rmiconfig.getPort()+"/"+rmiconfig.getServiceName();
RMIInterface jprinter=(RMIInterface)Naming.lookup(rmiUrl);
int jobID=jprinter.submitJob("hello word");
System.out.println("submitted job's ID: "+jobID);
System.out.println("is complete ? "+jprinter.isComplete(jobID));
System.out.println("printer status: "+jprinter.getPrinterStatus());
}
catch(Exception e)
{
}
}
public static void main(String[] args) {
try
{
File file=new File("etc/log4j.properties");
if(!file.exists())
{
logger.fatal("the log4j.properties is not exist");
System.exit(0);
}
PropertyConfigurator.configure("etc/log4j.properties");
RMIClient client=new RMIClient();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
分享到:
相关推荐
**基于JAVA RMI的聊天室** Java Remote Method Invocation(RMI)是Java平台提供的一种用于在分布式环境中调用远程对象的方法。在这个“基于JAVA RMI的聊天室”项目中,开发者利用RMI技术构建了一个简单的多用户...
Java RMI(Remote Method Invocation)技术是Java平台中用于分布式计算的一种机制,它允许一个Java对象调用远程计算机上的另一个Java对象的方法。在本案例中,“java RMI技术实现的网络聊天室”是一个使用RMI构建的...
Java RMI(Remote Method Invocation,远程方法调用)是一种Java技术,允许在分布式环境中执行远程对象的方法。这个技术的核心是序列化和反序列化过程,它使得对象可以在网络上进行传输。然而,这个特性也可能引入...
根据提供的文件信息,我们可以深入探讨Java RMI(Java Remote Method Invocation)的相关知识点,包括其概念、原理、体系结构以及一个具体的示例。 ### RMI的概念 RMI是一种Java技术,它允许开发者创建分布式应用...
Java RMI(Remote Method Invocation,远程方法调用)是Java平台提供的一种分布式计算技术,它允许在不同的Java虚拟机之间进行远程对象的调用。RMI使得开发者可以像调用本地对象一样调用网络上的对象,极大地简化了...
Java Remote Method Invocation(Java RMI)是Java编程语言中用于在网络间进行远程对象调用的技术。它是Java平台的标准部分,允许程序员在分布式环境中调用对象的方法,就像它们在同一台计算机上一样。Java RMI对于...
### Java RMI (Remote Method Invocation) 概念与实践 #### 一、Java RMI简介 Java RMI(Remote Method Invocation)是一种允许调用不同Java虚拟机(JVM)上方法的机制。这些JVM可能位于不同的机器上,也可能在同一...
Java RMI(Remote Method Invocation,远程方法调用)是Java平台提供的一种分布式计算技术,它允许在不同网络节点上的Java对象之间进行透明的交互。在Java RMI中,一个对象可以调用另一个位于不同JVM(Java虚拟机)...
Java RMI (Remote Method Invocation) 是一种用于在Java应用程序之间进行远程通信的技术。为了提高RMI通信的安全性,我们可以使用SSL (Secure Sockets Layer) 或其后继者TLS (Transport Layer Security) 进行加密。...
Java RMI(Remote Method Invocation,远程方法调用)是Java平台提供的一种用于分布式计算的技术,它允许一个Java对象调用另一个在不同 JVM(Java虚拟机)上的对象的方法。这个简单的示例展示了如何创建一个基本的...
Java RMI(Remote Method Invocation,远程方法调用)是Java平台中用于构建分布式对象系统的关键技术。它允许Java应用程序在不同Java虚拟机(JVM)之间进行远程方法调用,这些虚拟机可能位于同一台计算机或网络上的...
Java RMI(Remote Method Invocation)是Java编程语言中用于实现远程过程调用的一种技术。它允许运行在客户机上的程序调用位于远程服务器上的对象的方法,从而实现分布式计算。RMI的核心思想是通过接口隐藏底层网络...
**JAVA RMI(远程方法调用)详解** Java RMI(Remote Method Invocation)是Java平台上的一个核心特性,它允许Java程序在不同的JVM(Java虚拟机)之间进行分布式计算,实现了对象间的远程调用。RMI使得开发者可以像...
Java RMI(Remote Method Invocation,远程方法调用)是Java平台提供的一种用于分布式计算的技术,它允许一个Java对象调用另一个在不同JVM上的对象的方法。这个简单的例子将引导我们了解如何利用Java RMI实现远程...
Java RMI,全称为Remote Method Invocation,是Java平台上的一个标准API,用于实现分布式计算,使得在不同Java虚拟机(JVM)上的对象能够互相调用方法。这个"java rmi HelloWorld版(源码)"的压缩包文件提供了一个...
Java RMI(Remote Method Invocation,远程方法调用)是Java平台提供的一种分布式计算技术,它允许Java对象在不同的网络环境中进行交互,就像调用本地方法一样。RMI是构建分布式应用的重要工具,尤其适用于需要跨...
Java Remote Method Invocation (RMI) 是Java平台提供的一种强大的分布式计算技术,允许在不同网络环境中的Java对象之间进行远程方法调用。这个可运行实例是一个实际应用RMI概念的示例,它展示了如何构建和运行一个...
Java RMI 完整版 Java Remote Method Invocation(RMI)是一种分布式对象技术,允许使用 Java 编写分布式对象,不同的 Java 虚拟机(JVM)之间进行对象间的通讯。这使得应用程序(Application)可以远程调用方法,...
Java RMI(Remote Method Invocation,远程方法调用)是Java平台提供的一种分布式计算技术,它允许在不同的Java虚拟机之间进行方法调用,仿佛这些方法都在本地对象上执行一样。这个"JAVA RMI简单例子"旨在帮助我们...