java的rmi
㈠ java Rmi如何实现两个客户端之间的通信 求说的具体点
RMI的开发步骤
先创建远程接口及声明远程方法,注意这是实现双方通讯的接口,需要继承Remote
开发一个类来实现远程接口及远程方法,值得注意的是实现类需要继承UnicastRemoteObject
通过javac命令编译文件,通过java -server 命令注册服务,启动远程对象
最后客户端查找远程对象,并调用远程方法
首先为服务建立一个Model层,注意因为此对象需要现实进行远程传输,所以必须继承Serializable
代码
packagermi.model;
importjava.io.Serializable;
//注意对象必须继承Serializable
{
privateintid;
privateStringname;
privateintage;
publicvoidsetId(intid){
this.id=id;
}
publicintgetId(){
returnid;
}
publicvoidsetName(Stringname){
this.name=name;
}
publicStringgetName(){
returnname;
}
publicvoidsetAge(intage){
this.age=age;
}
publicintgetAge(){
returnage;
}
}
创建远程接口PersonService,注意远程接口需要继承Remote
代码
packagermi.service;
importjava.rmi.Remote;
importjava.rmi.RemoteException;
importjava.util.List;
importrmi.model.*;
//此为远程对象调用的接口,必须继承Remote类
{
publicList<PersonEntity>GetList()throwsRemoteException;
}
建立PersonServiceImpl实现远程接口,注意此为远程对象实现类,需要继承UnicastRemoteObject
代码
packagermi.serviceImpl;
importjava.rmi.RemoteException;
importjava.rmi.server.UnicastRemoteObject;
importjava.util.LinkedList;
importjava.util.List;
importrmi.model.PersonEntity;
importrmi.service.*;
//此为远程对象的实现类,须继承UnicastRemoteObject
Service{
publicPersonServiceImpl()throwsRemoteException{
super();
//TODOAuto-generatedconstructorstub
}
@Override
publicList<PersonEntity>GetList()throwsRemoteException{
//TODOAuto-generatedmethodstub
System.out.println("GetPersonStart!");
List<PersonEntity>personList=newLinkedList<PersonEntity>();
PersonEntityperson1=newPersonEntity();
person1.setAge(25);
person1.setId(0);
person1.setName("Leslie");
personList.add(person1);
PersonEntityperson2=newPersonEntity();
person2.setAge(25);
person2.setId(1);
person2.setName("Rose");
personList.add(person2);
returnpersonList;
}
}
建立服务器端,在服务器端注册RMI通讯端口与通讯路径,然后通讯javac命令编译文件,通过java -server 命令注册服务。以下面代码为例,如果阁下将项目建立于D:\RMIRemotingService文件夹上时,则先输入D:\RMIRemotingServicesrc>javac rmi/remotingservice/Program.java获取Program.class(如何阁下使用的MyEclipse等开发工具,可跳过此步,直接在*/bin文件夹中直接调用已经生成的Program.class),然后输入D:\RMIRemotingServicesrc>java rmi/remotingservice/Program启动服务。
代码
packagermi.remotingservice;
importjava.rmi.Naming;
importjava.rmi.registry.LocateRegistry;
importrmi.service.*;
importrmi.serviceImpl.*;
publicclassProgram{
publicstaticvoidmain(String[]args){
try{
PersonServicepersonService=newPersonServiceImpl();
//注册通讯端口
LocateRegistry.createRegistry(6600);
//注册通讯路径
Naming.rebind("rmi://127.0.0.1:6600/PersonService",personService);
System.out.println("ServiceStart!");
}catch(Exceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
}
}
最后建立客户端进行测试,注意客户调用的RMI路径必须服务器配置一致
代码
packagermi.remotingclient;
importjava.rmi.Naming;
importjava.util.List;
importrmi.model.PersonEntity;
importrmi.service.*;
publicclassProgram{
publicstaticvoidmain(String[]args){
try{
//调用远程对象,注意RMI路径与接口必须与服务器配置一致
PersonServicepersonService=(PersonService)Naming.lookup("rmi://127.0.0.1:6600/PersonService");
List<PersonEntity>personList=personService.GetList();
for(PersonEntityperson:personList){
System.out.println("ID:"+person.getId()+"Age:"+person.getAge()+"Name:"+person.getName());
}
}catch(Exceptionex){
ex.printStackTrace();
}
}
}
常见错误
在命令提示符调用java命令时,显示并无此命令。这是因为未在“环境变量”中绑定JAVA的JDK命令造成的,你首先单击“计算机右键”->“属性”->“高级”->“环境变量”。在系统变量Path设置中加载为JDK的路径 .;D:Program FilesGenuitecCommoninarycom.sun.java.jdk.win32.x86_1.6.0.013in。然后在ClassPath加载服务器端的Program.class地址 .;D:\RMIRemotingServicein
在调用javac命令时出现“javac 找不到文件 ..... ”此错误,可能是因为阁下输入的文件路径出现错误造成,注意不要把D:\RMIRemotingServicesrc>javac rmi/remotingservice/Program.java写错为D:\RMIRemotingServicesrc>javac rmi.remotingservice.Program.java
在调用D:\RMIRemotingServicein>java rmi/remotingservice/Program命令时出现“Exception in thread 'main' java.lang.NoClassEdfoundError”错误,第一这可能是阁下把Program错写为Program.class,注意java命令不需要加后缀名。第二可能是阁下把“java rmi/remotingservice/Program”错写为“java rmi emotingserviceProgram"。
㈡ JavaRMI服务远程方法调用漏洞如何修复lin
Linux的Apache或WebLogic应用被检测出这个漏洞,NSFOCUS(绿盟)给出的解决办法是:
临时解决方法:【限制访问或删除类文件】
如果您不能立刻安装补丁或者升级,建议您采取以下措施以降低威胁:
* 使用防火墙规则及文件系统访问限制
* 使用 SerialKiller 替换进行序列化操作的 ObjectInputStream 类
* 删除掉项目里的“commons-collections-3.2.jar///org/apache/commons/collections/functors/InvokerTransformer.class” 文件,删除后项目可能会在某些功能下报错。
安装厂商补丁:【下载3.2.2以上版本commons-collections补丁】
目前厂商已经发布了升级补丁ACC 3.2.2 以修复这个安全问题,请到厂商的主页下载:
Download Commons Collections
http://svn.apache.org/viewvc?view=revision&revision=1713307
https://blogs.apache.org/foundation/entry/apache_commons_statement_to_widespread
㈢ RMI是干什么用的在JAVA里面
RMI是J2EE的网络机制,允许你编写分布式对象,使得对象的通信范围能够在内存中,跨Java虚拟机,跨物理设备
RMI-IIOP遵循了接口和实现的原则。你写的所有网络代码都是应用于接口,而不是实现。实际上,你必须使用RMI-IIOP中的范例,没有其它的选择。直接在你的对象实现上执行远程调用是不可能的,你只能在对象类的接口上单独进行这一操作。
所以我们在使用RMI-IIOP时,你必须建立一个客户接口,叫做remote interface。这个远程接口应该扩展java.rmi.Remote接口。
RMI应用程序通常包括两个独立的程序:服务器程序和客户机程序。典型的服务器应用程序将创建多个远程对象,使这些远程对象能够被引用,然后等待客户机调用这些远程对象的方法。而典型的客户机程序则从服务器中得到一个或多个远程对象的引用,然后调用远程对象的方法。RMI为服务器和客户机进行通信和信息传递提供了一种机制。
在与远程对象的通信过程中,RMI使用标准机制:stub和skeleton。远程对象的stub担当远程对象的客户本地代表或代理人角色。调用程序将调用本地stub的方法,而本地stub将负责执行对远程对象的方法调用。在RMI中,远程对象的stub与该远程对象所实现的远程接口集相同。调用stub的方法时将执行下列操作:(1) 初始化与包含远程对象的远程虚拟机的连接;(2) 对远程虚拟机的参数进行编组(写入并传输);(3) 等待方法调用结果;(4) 解编(读取)返回值或返回的异常;(5) 将值返回给调用程序。为了向调用程序展示比较简单的调用机制,stub将参数的序列化和网络级通信等细节隐藏了起来。在远程虚拟机中,每个远程对象都可以有相应的skeleton(在JDK1.2环境中无需使用skeleton)。Skeleton负责将调用分配给实际的远程对象实现。它在接收方法调用时执行下列操作:(1) 解编(读取)远程方法的参数;(2) 调用实际远程对象实现上的方法;(3) 将结果(返回值或异常)编组(写入并传输)给调用程序。stub和skeleton由rmic编译器生成。
㈣ java的远程调试是基于什么协议
RMI是java语言本身提供的远程通讯协议,稳定高效,是EJB的基础。但它只能用于JAVA程序之间的通讯。
Hessian和Burlap是caucho公司提供的开源协议,基于HTTP传输,服务端不用开防火墙端口。协议的规范公开,可以用于任意语言。
Httpinvoker是SpringFramework提供的远程通讯协议,只能用于JAVA程序间的通讯,且服务端和客户端必须使用SpringFramework。
Web service是连接异构系统或异构语言的首选协议,它使用SOAP形式通讯,可以用于任何语言,目前的许多开发工具对其的支持也很好。
RMI > Httpinvoker >= Hessian >> Burlap >> web service
RMI不愧是JAVA的首选远程调用协议,非常高效稳定,特别是在大数据量的情况下,与其他通讯协议的差距尤为明显。
HttpInvoker使用java的序列化技术传输对象,与RMI在本质上是一致的。从效率上看,两者也相差无几,HttpInvoker与RMI的传输时间基本持平。
Hessian在传输少量对象时,比RMI还要快速高效,但传输数据结构复杂的对象或大量数据对象时,较RMI要慢20%左右。
Burlap仅在传输1条数据时速度尚可,通常情况下,它的毫时是RMI的3倍。
Web Service的效率低下是众所周知的,平均来看,Web Service的通讯毫时是RMI的10倍。
二、结果分析
1、直接调用
直接调用的所有毫时都接近0,这说明程序处理几乎没有花费时间,记录的全部时间都是远程调用耗费的。
2、RMI调用
与设想的一样,RMI理所当然是最快的,在几乎所有的情况下,它的毫时都是最少的。特别是在数据结构复杂,数据量大的情况下,与其他协议的差距尤为明显。
为了充分发挥RMI的性能,另外做了测试类,不使用Spring,用原始的RMI形式 (继承UnicastRemoteObject对象)提供服务并远程调用,与Spring对POJO包装成的RMI进行效率比较。结果显示:两者基本持 平,Spring提供的服务还稍快些。
初步认为,这是因为Spring的代理和缓存机制比较强大,节省了对象重新获取的时间。
3、Hessian调用
caucho公司的resin服务器号称是最快的服务器,在java领域有一定的知名 度。Hessian做为resin的组成部分,其设计也非常精简高效,实际运行情况也证明了这一点。平均来看,Hessian较RMI要慢20%左右,但 这只是在数据量特别大,数据结构很复杂的情况下才能体现出来,中等或少量数据时,Hessian并不比RMI慢。
Hessian的好处是精简高效,可以跨语言使用,而且协议规范公开,我们可以针对任意语言开发对其协议的实现。目前已有实现的语言有:java, c++, .net, python, ruby。还没有delphi的实现。
另外,Hessian与WEB服务器结合非常好,借助WEB服务器的成熟功能,在处理大 量用户并发访问时会有很大优势,在资源分配,线程排队,异常处理等方面都可以由成熟的WEB服务器保证。而RMI本身并不提供多线程的服务器。而 且,RMI需要开防火墙端口,Hessian不用。
4、Burlap调用
Burlap与Hessian都是caucho公司的开源产品,只不过Hessian采用二进制的方式,而Burlap采用xml的格式。
测试结果显示,Burlap在数据结构不复杂,数据量中等的情况下,效率还是可以接受的,但如果数据量大,效率会急剧下降。平均计算,Burlap的调用毫时是RMI的3倍。
我认为,其效率低有两方面的原因,一个是XML数据描述内容太多,同样的数据结构,其传输量要大很多;另一方面,众所周知,对xml的解析是比较费资源的,特别对于大数据量情况下更是如此。
5、HttpInvoker调用
HttpInvoker是SpringFramework提供的JAVA远程调用方法,使用java的序列化机制处理对象的传输。从测试结果看,其效率还是可以的,与RMI基本持平。
不过,它只能用于JAVA语言之间的通讯,而且,要求客户端和服务端都使用SPRING框架。
另外,HttpInvoker 并没有经过实践的检验,目前还没有找到应用该协议的项目。
6、web service调用
本次测试选用了apache的AXIS组件作为WEB SERVICE的实现,AXIS在WEB SERVICE领域相对成熟老牌。
为了仅测试数据传输和编码、解码的时间,客户端和服务端都使用了缓存,对象只需实例化一次。但是,测试结果显示,web service的效率还是要比其他通讯协议慢10倍。
如果考虑到多个引用指向同一对象的传输情况,web service要落后更多。因为RMI,Hessian等协议都可以传递引用,而web service有多少个引用,就要复制多少份对象实体。
Web service传输的冗余信息过多是其速度慢的原因之一,监控发现,同样的访问请求,描述相同的数据,web service返回的数据量是hessian协议的6.5倍。另外,WEB SERVICE的处理也很毫时,目前的xml解析器效率普遍不高,处理xml <-> bean很毫资源。从测试结果看,异地调用比本地调用要快,也从侧面说明了其毫时主要用在编码和解码xml文件上。这比冗余信息更为严重,冗余信息占用的 只是网络带宽,而每次调用的资源耗费直接影响到服务器的负载能力。(MS的工程师曾说过,用WEB SERVICE不能负载100个以上的并发用户。)
测试过程中还发现,web service编码不甚方便,对非基本类型需要逐个注册序列化和反序列化类,很麻烦,生成stub更累,不如spring + RMI/hessian处理那么流畅简洁。而且,web service不支持集合类型,只能用数组,不方便。
ITjob学。到的
㈤ java 用rmi 远程连接access 数据库,但总报错,请高人指点。
java.lang.NoClassDefFoundError
未找到类
估计是Class.forName("org.objectweb.rmijdbc.Driver").newInstance();
找不到org.objectweb.rmijdbc.Driver
㈥ java RMI 如何返回远程对象的引用
服务器端
1.进入jdk的bin目录 :
cd ${JAVA_HOME}/bin
2.在该目录下新建文本jstatd.all.policy:
vim jstatd.all.policy
3.添加内容:
grant codebase "file:${java.home}/../lib/tools.jar" {
permission java.security.AllPermission;
};
4.在该目录启动jstatd服务:
./jstatd -J-Djava.security.policy=jstatd.all.policy -J-Djava.rmi.server.hostname=<你服务器的ip> -p 1099
本地
1.进入jdk的bin目录,打开jvisualvm.exe
2.界面左侧目录‘远程’点击右键添加主机,输入你的服务器ip,端口和jstatd服务的启动端口一致。
密码:380p以上都是小编收集了大神的灵药,喜欢的拿走吧!喜欢小编就轻轻关注一下哦!