- 浏览: 287339 次
- 性别:
- 来自: 荷兰
文章分类
最新评论
-
ice.k:
才发现,谢谢。
使用CXF框架提供Rest接口的一些设置 -
kucoll:
@Produces 是控制响应的content-type,如果 ...
使用CXF框架提供Rest接口的一些设置 -
SE_XiaoFeng:
写的好.讲出了原因,和解决办法,这才是锦囊妙计.
Android 中的ANR 问题,响应灵敏性 -
zhujinyuan:
怎么没有代码的额。
10个经典的Android开源项目 -
liuxuejin:
我回去试试好
ubuntu安装Mac OS X主题
http://dev.csdn.net/author/kmlgyhm/90279b1aae794acdade7ee40a8426e6c.html
Java远程方法调用(RMI)机制和公用对象请求代理体系(CORBA)是最重要 和使用最广泛的两种分布式对象系统。每个系统都有其特点和短处。它们在行 业中被用于从电子交易到保健医疗的各个领域。一个项目如果要从这两种分布式 机制中选用一个,往往难以抉择。本文概括地介绍了RMI和CORBA,更重要的是, 它将介绍如何开发一个有用的应用程序,用于从远程主机下载文件。然后它将:
Java远程方法调用(RMI)机制和公用对象请求代理体系(CORBA)是最重要 和使用最广泛的两种分布式对象系统。每个系统都有其特点和短处。它们在行 业中被用于从电子交易到保健医疗的各个领域。一个项目如果要从这两种分布式 机制中选用一个,往往难以抉择。本文概括地介绍了RMI和CORBA,更重要的是, 它将介绍如何开发一个有用的应用程序,用于从远程主机下载文件。然后它将:
简要介绍分布式对象系统
简要介绍RMI和CORBA
让你对在RMI和CORBA中开发应用程序所涉及的工作有个初步印象
演示如何使用RMI和CORBA,从远程主机传送文件
对RMI和CORBA进行简单比较
客户机/服务器模型
客户机/服务器模型是分布式计算的一种形式,在这种形式中,一个程序(客 户机)与另一个程序(服务器)通讯以便交换信息。在这种模型中,客户机和服 务器通常都说同样的语言--也就是说客户机和服务器能理解同一个协议--这 样它们才能通讯。
虽然客户机/服务器模型的实现方式多种多样,但典型做法是使用底层套接字。 使用套接字开发客户机/服务器系统意味着,我们必须设计一个协议,也就是客户 机和服务器都认识的一组命令集,通过这些命令它们就能通讯了。举例来说, HTTP协议中提供了一个名为GET的方法,所有Web服务器都必须实现这个方法,所 有Web客户机(浏览器)都必须使用这个方法,才能获取文档。
分布式对象模型
基于分布式对象的系统是一组对象的集合,这些对象以一种明确定义封装的接 口把服务的请求者(客户机)和服务的提供者(服务器)分隔开。换言之,客户 机从服务的实现中分离出来,变成数据的呈现和可执行代码。这就是基于分布式 对象的模型与纯粹的客户机/服务器模型的主要区别之一。
在基于分布式对象的模型中,客户机向对象发送消息,然后对象解释该消息以 便决定要执行什么服务。这项服务,也就是方法,可以选择是让对象还是让代理 来执行。Java远程方法调用(RMI)和公用对象请求代理体系(CORBA)就是这种 模型的例子。
RMI
RMI是一个分布式对象系统,它使你能够轻松地开发出分布式Java应用程序。 在RMI中开发分布式应用程序比用套接字开发要简单,因为不需要做设计协议这种 很容易出错的工作。在RMI中,开发者会有一种错觉,似乎是从本地类文件调用的 本地方法,其实参数传送给了远程目标,目标解释参数后再把结果发回给调用方。
RMI应用程序初步
使用RMI开发分布式应用程序包括以下步骤:
定义一个远程接口
实现这个远程接口
开发服务器
开发客户机
生成存根和基干,启动RMI注册表、服务器和客户机
下面我们将通过开发一个文件传输程序来实践这些步骤。
范例: 文件传输程序
这个应用程序允许客户机从远程主机上传送(即下载)任何类型的文件(纯 文本或二进制文件)。第一步是定义一个远程接口,这个接口规定了服务器所提 供方法的信号,客户机将调用这些方法。
定义一个远程接口
用于文件下载应用程序的远程接口如代码范例1所示。接口 FileInterface提供了一个方法downloadFile,这个 方法接受String参数(文件名),将文件的数据以字节数组的形式 返回。
代码范例1 1: FileInterface.java
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface FileInterface extends Remote {
public byte[] downloadFile(String fileName) throws
RemoteException;
}
请注意FileInterface的以下特征:
它必须声明为public,这样客户机才能加载实现远程接口 的远程对象。
它必须扩展为Remote接口,以满足使该对象成为远程对象的 要求。
这个接口中的每种方法都必须投出一个java.rmi.RemoteException。
实现远程接口
下一步是实现接口FileInterface。实现的范例见代码范例2。 请注意,除了实现FileInterface之外,还把FileImpl 类扩展为UnicastRemoteObject。这表示FileImpl类 将用于创建一个单独的、不可复制的远程对象,它使用RMI缺省的基于TCP的传送 通道进行通讯。
代码范例2: FileImpl.java
import java.io.*;
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
public class FileImpl extends UnicastRemoteObject
implements FileInterface {
private String name;
public FileImpl(String s) throws RemoteException{
super();
name = s;
}
public byte[] downloadFile(String fileName){
try {
File file = new File(fileName);
byte buffer[] = new byte[(int)file.length()];
BufferedInputStream input = new
BufferedInputStream(new FileInputStream(fileName));
input.read(buffer,0,buffer.length);
input.close();
return(buffer);
} catch(Exception e){
System.out.println("FileImpl: "+e.getMessage());
e.printStackTrace();
return(null);
}
}
}
开发服务器
第三个步骤是开发服务器。服务器需要做三件事:
创建RMISecurityManager的一个实例并安装它
创建远程对象(在本例中是FileImpl)的一个实例
在RMI注册表中登记这个创建的对象。实现的范例见代码范例3。
代码范例 3: FileServer.java
import java.io.*;
import java.rmi.*;
public class FileServer {
public static void main(String argv[]) {
if(System.getSecurityManager() == null) {
System.setSecurityManager(new RMISecurityManager());
}
try {
FileInterface fi = new FileImpl("FileServer");
Naming.rebind("//127.0.0.1/FileServer", fi);
} catch(Exception e) {
System.out.println("FileServer: "+e.getMessage());
e.printStackTrace();
}
}
}
语句Naming.rebind("//127.0.0.1/FileServer", fi)假定RMI 注册表在缺省的端口号1099上运行。
但是,如果RMI注册表在其他端口号上运行, 就必须在这一句中指定端口号。例如,如果RMI注册表在端口4500
上运行,那么 这一句就变成:
Naming.rebind("//127.0.0.1:4500/FileServer", fi)
另外,在这里要着重指出,我们假定rmi注册表和服务器是在同一台电脑上运 行。如果不是这样,只需修改rebind方法中的地址即可。
开发客户机
下一步是开发客户机。客户机可以远程调用远程接口 (FileInterface)中指定的任何方法。但是为了能这么做,客户 机首先必须从RMI注册表中获得指向该远程对象的引用。获得引用之后就可以调 用downloadFile方法了。客户机的实现请见代码范例4。在这个实 现中,客户机从命令行接收两个参数:
第一个参数是要下载文件的名称,第二个参数是要下载的文件所在主机的地 址,也就是运行文件服务器的那台电脑的地址。
代码范例4: FileClient.java
import java.io.*;
import java.rmi.*;
public class FileClient{
public static void main(String argv[]) {
if(argv.length != 2) {
System.out.println("Usage: java FileClient fileName machineName");
System.exit(0);
}
try {
String name = "//" + argv[1] + "/FileServer";
FileInterface fi = (FileInterface) Naming.lookup(name);
byte[] filedata = fi.downloadFile(argv[0]);
File file = new File(argv[0]);
BufferedOutputStream output = new
BufferedOutputStream(new FileOutputStream(file.getName()));
output.write(filedata,0,filedata.length);
output.flush();
output.close();
} catch(Exception e) {
System.err.println("FileServer exception: "+ e.getMessage());
e.printStackTrace();
}
}
}
运行应用程序
为了运行应用程序,我们需要生成存根和基干,编译服务器和客户机,启动 RMI注册表,最后是启动服务器和客户机。
为了生成存根和基干,请使用rmic编译器:
prompt> rmic FileImpl
这将生成两个文件:FileImpl_Stub.class和 FileImpl_Skel.class。存根是一个客户机代理,基干是一个服 务器基干。
下一步是编译服务器和客户机。用javac编译器来做这件事。但是请注意:如 果服务器和客户机是在两台不同的机器上开发的,为了编译客户机,需要把接口 (FileInterface)复制一份。
最后,启动RMI注册表并运行服务器和客户机。为了在缺省的端口号上启动 RMI注册表,请在Windows中使用命令rmiregistry或 start rmiregistry。为了在其他端口号上启动RMI注册表,可以 提供该端口号作为RMI注册表的一个参数:
prompt> rmiregistry portNumber
运行RMI注册表之后,就可以启动服务器FileServer了。但是, 因为在服务器应用程序中正在使用RMI安全管理员,所以需要一个安全方针来与之 相配。下面是一个安全方针范例:
grant {
permission java.security.AllPermission "", "";
};
注意: 这只是一个方针的例子。它允许任何人做任何事情。对于关键 性事务应用程序,你需要指定更严格的安全方针。
现在,为了启动服务器,需要把除了客户机类 (FileClient.class)之外的所有类(包括存根和基干)复制一 份。请使用以下命令启动服务器,假定安全方针位于文件policy.txt中:
prompt> java -Djava.security.policy=policy.txt FileServer
为了在另一台机器上启动客户机,需要复制远程接口 (FileInterface.class)和存根 (FileImpl_Stub.class)。请使用以下命令启动客户机:
prompt> java FileClient fileName machineName
其中fileNamefileName是要下载的文件,machineName 是该文件所在的机器(运行文件服务器的那台机器)。如果一切顺利,那么客户 机就存在了,下载完的文件保存在本地的机器上。
要运行前面介绍的客户机,需要复制接口和存根。更 适当的方法是使用RMI动态类加载。这种做法不需要复制接口和存根。取而代 之的做法是,可以把接口和存根放在共享的目录里供服务器和客户机使用,在 需要存根或者基干的时候,RMI类加载器就会自动下载它。举例来说,用以下命 令运行客户机: java -Djava.rmi.server.codebase=http://hostname/locationOfClasses FileClient fileName machineName。 有关这种方法的更多信息,请参见使用 RMI加载动态代码。
CORBA
公用对象请求代理体系(即CORBA)是由对象管理组织(OMG)开发的一项工 业标准,用于帮助分布式对象编程。要注意的重要一点是,CORBA只是一项规范。 CORBA的实现称为ORB(对象请求代理)。从市场上可以找到几个CORBA的实现, 比如VisiBroker、ORBIX,等等。JavaIDL是另一个实现,它是JDK1.3或更高版本 的核心软件包之一。
CORBA被设计成与平台和语言无关。因此,CORBA对象可以运行于任何平台之 上,位于网络的任何位置,还可以用任何语言编写,只要该语言具有Interface Definition Language(IDL,接口定义语言)的映射。
和RMI类似,CORBA对象是用接口规定的。但是CORBA中的接口在IDL中指定。 虽然IDL与C++相似,但请注意,IDL并不是一种编程语言。有关CORBA的详细介绍, 请参见用 Java进行分 布式编程: 第11章(CORBA概述)。
CORBA应用程序初步
开发CORBA应用程序包括许多步骤。它们是:
在IDL中定义一个接口
把IDL接口映射到Java中(自动完成)
实现这个接口
开发服务器
开发客户机
运行命名服务、服务器和客户机。
我们现在要开发一个基于CORBA的文件传送程序,以此来解释各个步骤,这个 程序类似于本文前面开发的那个RMI应用程序。在这里将使用JavaIDL,它是 JDK1.3+的核心软件包之一。
定义接口
在定义CORBA接口时,请考虑服务器将支持的操作类型。在文件传输应用程序 中,客户机将调用一个方法来下载文件。代码范例5显示了FileInterface 的接口。Data是使用typedef关键字引入的新类型。 IDL中的sequence类似于数组,区别在于序列没有固定的大小。 octet是一个8-bit数,等价于Java中的类型byte。
请注意,downloadFile方法接收一个类型为string ,声明为in的参数。IDL定义了三种参数传送模式:in (从客户机输入到服务器),out(从服务器输出到客户机), inout(输入输出都可用)。
代码范例 5: FileInterface.idl
interface FileInterface {
typedef sequence<octet> Data;
Data downloadFile(in string fileName);
};
定义好IDL接口之后,就可以编译它了。JDK 1.3+附带了idlj 编译器,用于把IDL定义映射为Java的声明和语句。
idlj编译器可以通过选项来指定是生成客户机存根、服务器基 干,还是二者都生成。-f选项用于指定要生成什么。 side可以是client, server或者 all,用于指定客户机存根和服务器基干。在这个例子中,因为应 用程序将在两台单独的机器上运行,所以在服务器端使用-fserver 选项,而在客户机端使用-fclient选项。
现在编译FileInterface.idl,生成服务器端基干。请使用命令:
prompt> idlj -fserver FileInterface.idl
这条命令将产生几个文件,比如基干,持有者和辅助器类,等等。其中生成 的一个重要文件是_FileInterfaceImplBase,它是实现接口的类的 子类。
实现接口
下面我们提供了downloadFile方法的一个实现。这个实现称为 仆人,正如你从代码范例6中看到的那样,类FileServant扩展了 _FileInterfaceImplBase类,以便把这个仆人指定为一个CORBA 对象。
代码范例 6: FileServant.java
import java.io.*;
public class FileServant extends _FileInterfaceImplBase {
public byte[] downloadFile(String fileName){
File file = new File(fileName);
byte buffer[] = new byte[(int)file.length()];
try {
BufferedInputStream input = new
BufferedInputStream(new FileInputStream(fileName));
input.read(buffer,0,buffer.length);
input.close();
} catch(Exception e) {
System.out.println("FileServant Error: "+e.getMessage());
e.printStackTrace();
}
return(buffer);
}
}
开发服务器
下一步是开发CORBA服务器。代码范例7中的FileServer类实现 了一个CORBA服务器,它做了这么一些事情:
初始化ORB
创建一个FileServant对象
在CORBA命名服务(COS命名)中登记该对象
输出一条状态消息
等待客户机的请求到来
代码范例 7: FileServer.java
import java.io.*;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
import org.omg.CORBA.*;
public class FileServer {
public static void main(String args[]) {
try{
// create and initialize the ORB
ORB orb = ORB.init(args, null);
// create the servant and register it with the ORB
FileServant fileRef = new FileServant();
orb.connect(fileRef);
// get the root naming context
org.omg.CORBA.Object objRef =
orb.resolve_initial_references("NameService");
NamingContext ncRef = NamingContextHelper.narrow(objRef);
// Bind the object reference in naming
NameComponent nc = new NameComponent("FileTransfer", " ");
NameComponent path[] = {nc};
ncRef.rebind(path, fileRef);
System.out.println("Server started....");
// Wait for invocations from clients
java.lang.Object sync = new java.lang.Object();
synchronized(sync){
sync.wait();
}
} catch(Exception e) {
System.err.println("ERROR: " + e.getMessage());
e.printStackTrace(System.out);
}
}
}
FileServer有了一个ORB之后,就可以注册CORBA服务。它使用 COS命名服务进行注册,该服务由OMG制订,
用Java IDL实现。从获取指向命名服 务根的引用开始。这将返回一个普通CORBA对象。为了把这个对象用作一个
NamingContext对象,必须把它缩短(也就是强制转换)为适当类 型,用下列语句实现:
NamingContext ncRef = NamingContextHelper.narrow(objRef);
ncRef对象现在变成了 org.omg.CosNaming.NamingContext。 你可以使用rebind 方法,用这个对象在命名服务中注册一项CORBA服务。
开发客户机
下一步是开发客户机。代码范例8中演示了一个实现。获得指向命名服务的引 用之后,就可以用它来访问命名服务和查找其他服务(例如FileTransferFileTransfer服务时,将调用downloadFile 方法。
代码范例 8: FileClient
import java.io.*;
import java.util.*;
import org.omg.CosNaming.*;
import org.omg.CORBA.*;
public class FileClient {
public static void main(String argv[]) {
try {
// create and initialize the ORB
ORB orb = ORB.init(argv, null);
// get the root naming context
org.omg.CORBA.Object objRef =
orb.resolve_initial_references("NameService");
NamingContext ncRef = NamingContextHelper.narrow(objRef);
NameComponent nc = new NameComponent("FileTransfer", " ");
// Resolve the object reference in naming
NameComponent path[] = {nc};
FileInterfaceOperations fileRef =
FileInterfaceHelper.narrow(ncRef.resolve(path));
if(argv.length < 1) {
System.out.println("Usage: java FileClient filename");
}
// save the file
File file = new File(argv[0]);
byte data[] = fileRef.downloadFile(argv[0]);
BufferedOutputStream output = new
BufferedOutputStream(new FileOutputStream(argv[0]));
output.write(data, 0, data.length);
output.flush();
output.close();
} catch(Exception e) {
System.out.println("FileClient Error: " + e.getMessage());
e.printStackTrace();
}
}
}
运行应用程序
最后一步是运行应用程序。这其中包括几个子步骤:
运行CORBA命名服务。这可以使用命令tnameserv。 缺省情况下,该服务在端口900上运行。如果不能在这个端口运行命名服务, 你可以在其他端口上启动它。例如,要在端口2500上启动命名服务,请使用以 下命令:
prompt> tnameserv -ORBinitialPort 2500
启动服务器。如下所示,假定命名服务是在缺省的端口号上运行:
prompt> java FileServer
如果命名服务运行于其他端口之上,比如2500,则需要使用 ORBInitialPort选项来指定端口,如下所示:
prompt> java FileServer -ORBInitialPort 2500
生成用于客户机的存根。在可以运行客户机之前,先要生成客户机 的存根。为此需要复制FileInterface.idl文件,并使用idlj编 译器来编译它,在编译前指定希望生成的结果是客户机端存根,如下所示:
prompt> idlj -fclient FileInterface.idl
运行客户机假定命名服务在端口2500上运行,那么现在就可以使用 以下命令来运行客户机了。
prompt> java FileClient hello.txt -ORBInitialPort 2500
其中hello.txt是我们要从服务器下载的文件。
注意: 如果要在另一台主机上运行命名服务,请使用 -ORBInitialHost/CODE>选项,指定它在哪台主机上运行。例如,如果 要在名为gosling的主机的端口号4500上运行命名服务,则使用 以下命令启动客户机:
prompt> java FileClient hello.txt -ORBInitialHost gosling -ORBInitialPort 4500
另一种做法是,在代码级使用属性指定这些选项。所以除了像下面这样初始化 ORB:
ORB orb = ORB.init(argv, null);
还可以通过指定CORBA服务器所在机器(名为gosling)和命名服务的端口号( 2500)来进行初始化,如下所示:
Properties props = new Properties();
props.put("org.omg.CORBA.ORBInitialHost", "gosling");
props.put("orb.omg.CORBA.ORBInitialPort", "2500");
ORB orb = ORB.init(args, props);
练习
在文件传输应用程序中,客户机必须预先知道要下载的文件的名称(RMI和 CORBA中都是如此)。可是并未提供列出服务器上可用文件的方法。作为练习, 你也许希望改进这个应用程序,添加一个列出服务器上可用文件的方法。另外, 你可能不想使用命令行客户机,而开发一个基于GUI的客户机。在客户机启动时, 它调用服务器上的一个方法,获得文件列表,然后弹出一个菜单,显示可用的文 件,用户可以从中选择一个或多个要下载的文件,如图1所示。
CORBA与RMI的比较
从编码的角度看,很明显RMI更易于使用,因为Java开发者不需要熟悉接口定 义语言(IDL)。但是总的说来,CORBA在以下方面与RMI有所不同:
CORBA接口用IDL定义,RMI接口用Java定义。RMI-IIOP允许你用Java定义 所有接口(请参见 RMI-IIOP)。
CORBA支持in和out参数,而RMI不支持,因为 本地对象是通过复制传送的,远程对象是通过引用传送的。
CORBA被特意设计成与语言不相关。举例来说,这意味着可以用Java编写一 些对象,用C++编写其他对象,而它们仍然可以协同工作。所以,作为不同编程 语言间的桥梁,CORBA是一种理想机制。与此不同,RMI为一种单独的语言设计, 所有对象都可用Java编写。但是请注意,用RMI-IIOP有可能达到协同工作的能 力。
CORBA对象不能进行碎片收集。正如我们前面说的,CORBA与语言无关,某 些语言(比如C++)不支持碎片收集。可以认为这是项缺点,因为CORBA对象一 旦创建,就一直存在,直至被除去为止,而决定何时除去一个对象的工作量可 不小。与此相反,RMI对象会自动收集碎片。
结论
开发基于分布式对象的应用程序可以在Java中用RMI或JavaIDL(CORBA的一个 实现)完成。这两种技术的用法类似,第一步都是定义对象的接口。但是与RMI 用Java定义接口不同,CORBA接口是用接口定义语言(IDL)定义的。可是这就多 了一层复杂度,开发者需要熟悉IDL,同样重要的是,还要熟悉它到Java的映射。
在这两种分布式机制中如何选择,取决于当前项目及其需求。我希望此文能为 你开发基于分布式对象的应用程序提供足够的信息,为帮助你选择分布式机制提 供足够的指导。
更多信息
- RMI
- CORBA规范(OMG)
- JavaIDL
- 《用Java进行分布式编程》一书(第11章: CORBA概述)
- CORBA服务器和客户机服务小程序
- RMI-IIOP
Java远程方法调用(RMI)机制和公用对象请求代理体系(CORBA)是最重要 和使用最广泛的两种分布式对象系统。每个系统都有其特点和短处。它们在行 业中被用于从电子交易到保健医疗的各个领域。一个项目如果要从这两种分布式 机制中选用一个,往往难以抉择。本文概括地介绍了RMI和CORBA,更重要的是, 它将介绍如何开发一个有用的应用程序,用于从远程主机下载文件。然后它将:
Java远程方法调用(RMI)机制和公用对象请求代理体系(CORBA)是最重要 和使用最广泛的两种分布式对象系统。每个系统都有其特点和短处。它们在行 业中被用于从电子交易到保健医疗的各个领域。一个项目如果要从这两种分布式 机制中选用一个,往往难以抉择。本文概括地介绍了RMI和CORBA,更重要的是, 它将介绍如何开发一个有用的应用程序,用于从远程主机下载文件。然后它将:
简要介绍分布式对象系统
简要介绍RMI和CORBA
让你对在RMI和CORBA中开发应用程序所涉及的工作有个初步印象
演示如何使用RMI和CORBA,从远程主机传送文件
对RMI和CORBA进行简单比较
客户机/服务器模型
客户机/服务器模型是分布式计算的一种形式,在这种形式中,一个程序(客 户机)与另一个程序(服务器)通讯以便交换信息。在这种模型中,客户机和服 务器通常都说同样的语言--也就是说客户机和服务器能理解同一个协议--这 样它们才能通讯。
虽然客户机/服务器模型的实现方式多种多样,但典型做法是使用底层套接字。 使用套接字开发客户机/服务器系统意味着,我们必须设计一个协议,也就是客户 机和服务器都认识的一组命令集,通过这些命令它们就能通讯了。举例来说, HTTP协议中提供了一个名为GET的方法,所有Web服务器都必须实现这个方法,所 有Web客户机(浏览器)都必须使用这个方法,才能获取文档。
分布式对象模型
基于分布式对象的系统是一组对象的集合,这些对象以一种明确定义封装的接 口把服务的请求者(客户机)和服务的提供者(服务器)分隔开。换言之,客户 机从服务的实现中分离出来,变成数据的呈现和可执行代码。这就是基于分布式 对象的模型与纯粹的客户机/服务器模型的主要区别之一。
在基于分布式对象的模型中,客户机向对象发送消息,然后对象解释该消息以 便决定要执行什么服务。这项服务,也就是方法,可以选择是让对象还是让代理 来执行。Java远程方法调用(RMI)和公用对象请求代理体系(CORBA)就是这种 模型的例子。
RMI
RMI是一个分布式对象系统,它使你能够轻松地开发出分布式Java应用程序。 在RMI中开发分布式应用程序比用套接字开发要简单,因为不需要做设计协议这种 很容易出错的工作。在RMI中,开发者会有一种错觉,似乎是从本地类文件调用的 本地方法,其实参数传送给了远程目标,目标解释参数后再把结果发回给调用方。
RMI应用程序初步
使用RMI开发分布式应用程序包括以下步骤:
定义一个远程接口
实现这个远程接口
开发服务器
开发客户机
生成存根和基干,启动RMI注册表、服务器和客户机
下面我们将通过开发一个文件传输程序来实践这些步骤。
范例: 文件传输程序
这个应用程序允许客户机从远程主机上传送(即下载)任何类型的文件(纯 文本或二进制文件)。第一步是定义一个远程接口,这个接口规定了服务器所提 供方法的信号,客户机将调用这些方法。
定义一个远程接口
用于文件下载应用程序的远程接口如代码范例1所示。接口 FileInterface提供了一个方法downloadFile,这个 方法接受String参数(文件名),将文件的数据以字节数组的形式 返回。
代码范例1 1: FileInterface.java
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface FileInterface extends Remote {
public byte[] downloadFile(String fileName) throws
RemoteException;
}
请注意FileInterface的以下特征:
它必须声明为public,这样客户机才能加载实现远程接口 的远程对象。
它必须扩展为Remote接口,以满足使该对象成为远程对象的 要求。
这个接口中的每种方法都必须投出一个java.rmi.RemoteException。
实现远程接口
下一步是实现接口FileInterface。实现的范例见代码范例2。 请注意,除了实现FileInterface之外,还把FileImpl 类扩展为UnicastRemoteObject。这表示FileImpl类 将用于创建一个单独的、不可复制的远程对象,它使用RMI缺省的基于TCP的传送 通道进行通讯。
代码范例2: FileImpl.java
import java.io.*;
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
public class FileImpl extends UnicastRemoteObject
implements FileInterface {
private String name;
public FileImpl(String s) throws RemoteException{
super();
name = s;
}
public byte[] downloadFile(String fileName){
try {
File file = new File(fileName);
byte buffer[] = new byte[(int)file.length()];
BufferedInputStream input = new
BufferedInputStream(new FileInputStream(fileName));
input.read(buffer,0,buffer.length);
input.close();
return(buffer);
} catch(Exception e){
System.out.println("FileImpl: "+e.getMessage());
e.printStackTrace();
return(null);
}
}
}
开发服务器
第三个步骤是开发服务器。服务器需要做三件事:
创建RMISecurityManager的一个实例并安装它
创建远程对象(在本例中是FileImpl)的一个实例
在RMI注册表中登记这个创建的对象。实现的范例见代码范例3。
代码范例 3: FileServer.java
import java.io.*;
import java.rmi.*;
public class FileServer {
public static void main(String argv[]) {
if(System.getSecurityManager() == null) {
System.setSecurityManager(new RMISecurityManager());
}
try {
FileInterface fi = new FileImpl("FileServer");
Naming.rebind("//127.0.0.1/FileServer", fi);
} catch(Exception e) {
System.out.println("FileServer: "+e.getMessage());
e.printStackTrace();
}
}
}
语句Naming.rebind("//127.0.0.1/FileServer", fi)假定RMI 注册表在缺省的端口号1099上运行。
但是,如果RMI注册表在其他端口号上运行, 就必须在这一句中指定端口号。例如,如果RMI注册表在端口4500
上运行,那么 这一句就变成:
Naming.rebind("//127.0.0.1:4500/FileServer", fi)
另外,在这里要着重指出,我们假定rmi注册表和服务器是在同一台电脑上运 行。如果不是这样,只需修改rebind方法中的地址即可。
开发客户机
下一步是开发客户机。客户机可以远程调用远程接口 (FileInterface)中指定的任何方法。但是为了能这么做,客户 机首先必须从RMI注册表中获得指向该远程对象的引用。获得引用之后就可以调 用downloadFile方法了。客户机的实现请见代码范例4。在这个实 现中,客户机从命令行接收两个参数:
第一个参数是要下载文件的名称,第二个参数是要下载的文件所在主机的地 址,也就是运行文件服务器的那台电脑的地址。
代码范例4: FileClient.java
import java.io.*;
import java.rmi.*;
public class FileClient{
public static void main(String argv[]) {
if(argv.length != 2) {
System.out.println("Usage: java FileClient fileName machineName");
System.exit(0);
}
try {
String name = "//" + argv[1] + "/FileServer";
FileInterface fi = (FileInterface) Naming.lookup(name);
byte[] filedata = fi.downloadFile(argv[0]);
File file = new File(argv[0]);
BufferedOutputStream output = new
BufferedOutputStream(new FileOutputStream(file.getName()));
output.write(filedata,0,filedata.length);
output.flush();
output.close();
} catch(Exception e) {
System.err.println("FileServer exception: "+ e.getMessage());
e.printStackTrace();
}
}
}
运行应用程序
为了运行应用程序,我们需要生成存根和基干,编译服务器和客户机,启动 RMI注册表,最后是启动服务器和客户机。
为了生成存根和基干,请使用rmic编译器:
prompt> rmic FileImpl
这将生成两个文件:FileImpl_Stub.class和 FileImpl_Skel.class。存根是一个客户机代理,基干是一个服 务器基干。
下一步是编译服务器和客户机。用javac编译器来做这件事。但是请注意:如 果服务器和客户机是在两台不同的机器上开发的,为了编译客户机,需要把接口 (FileInterface)复制一份。
最后,启动RMI注册表并运行服务器和客户机。为了在缺省的端口号上启动 RMI注册表,请在Windows中使用命令rmiregistry或 start rmiregistry。为了在其他端口号上启动RMI注册表,可以 提供该端口号作为RMI注册表的一个参数:
prompt> rmiregistry portNumber
运行RMI注册表之后,就可以启动服务器FileServer了。但是, 因为在服务器应用程序中正在使用RMI安全管理员,所以需要一个安全方针来与之 相配。下面是一个安全方针范例:
grant {
permission java.security.AllPermission "", "";
};
注意: 这只是一个方针的例子。它允许任何人做任何事情。对于关键 性事务应用程序,你需要指定更严格的安全方针。
现在,为了启动服务器,需要把除了客户机类 (FileClient.class)之外的所有类(包括存根和基干)复制一 份。请使用以下命令启动服务器,假定安全方针位于文件policy.txt中:
prompt> java -Djava.security.policy=policy.txt FileServer
为了在另一台机器上启动客户机,需要复制远程接口 (FileInterface.class)和存根 (FileImpl_Stub.class)。请使用以下命令启动客户机:
prompt> java FileClient fileName machineName
其中fileNamefileName是要下载的文件,machineName 是该文件所在的机器(运行文件服务器的那台机器)。如果一切顺利,那么客户 机就存在了,下载完的文件保存在本地的机器上。
要运行前面介绍的客户机,需要复制接口和存根。更 适当的方法是使用RMI动态类加载。这种做法不需要复制接口和存根。取而代 之的做法是,可以把接口和存根放在共享的目录里供服务器和客户机使用,在 需要存根或者基干的时候,RMI类加载器就会自动下载它。举例来说,用以下命 令运行客户机: java -Djava.rmi.server.codebase=http://hostname/locationOfClasses FileClient fileName machineName。 有关这种方法的更多信息,请参见使用 RMI加载动态代码。
CORBA
公用对象请求代理体系(即CORBA)是由对象管理组织(OMG)开发的一项工 业标准,用于帮助分布式对象编程。要注意的重要一点是,CORBA只是一项规范。 CORBA的实现称为ORB(对象请求代理)。从市场上可以找到几个CORBA的实现, 比如VisiBroker、ORBIX,等等。JavaIDL是另一个实现,它是JDK1.3或更高版本 的核心软件包之一。
CORBA被设计成与平台和语言无关。因此,CORBA对象可以运行于任何平台之 上,位于网络的任何位置,还可以用任何语言编写,只要该语言具有Interface Definition Language(IDL,接口定义语言)的映射。
和RMI类似,CORBA对象是用接口规定的。但是CORBA中的接口在IDL中指定。 虽然IDL与C++相似,但请注意,IDL并不是一种编程语言。有关CORBA的详细介绍, 请参见用 Java进行分 布式编程: 第11章(CORBA概述)。
CORBA应用程序初步
开发CORBA应用程序包括许多步骤。它们是:
在IDL中定义一个接口
把IDL接口映射到Java中(自动完成)
实现这个接口
开发服务器
开发客户机
运行命名服务、服务器和客户机。
我们现在要开发一个基于CORBA的文件传送程序,以此来解释各个步骤,这个 程序类似于本文前面开发的那个RMI应用程序。在这里将使用JavaIDL,它是 JDK1.3+的核心软件包之一。
定义接口
在定义CORBA接口时,请考虑服务器将支持的操作类型。在文件传输应用程序 中,客户机将调用一个方法来下载文件。代码范例5显示了FileInterface 的接口。Data是使用typedef关键字引入的新类型。 IDL中的sequence类似于数组,区别在于序列没有固定的大小。 octet是一个8-bit数,等价于Java中的类型byte。
请注意,downloadFile方法接收一个类型为string ,声明为in的参数。IDL定义了三种参数传送模式:in (从客户机输入到服务器),out(从服务器输出到客户机), inout(输入输出都可用)。
代码范例 5: FileInterface.idl
interface FileInterface {
typedef sequence<octet> Data;
Data downloadFile(in string fileName);
};
定义好IDL接口之后,就可以编译它了。JDK 1.3+附带了idlj 编译器,用于把IDL定义映射为Java的声明和语句。
idlj编译器可以通过选项来指定是生成客户机存根、服务器基 干,还是二者都生成。-f选项用于指定要生成什么。 side可以是client, server或者 all,用于指定客户机存根和服务器基干。在这个例子中,因为应 用程序将在两台单独的机器上运行,所以在服务器端使用-fserver 选项,而在客户机端使用-fclient选项。
现在编译FileInterface.idl,生成服务器端基干。请使用命令:
prompt> idlj -fserver FileInterface.idl
这条命令将产生几个文件,比如基干,持有者和辅助器类,等等。其中生成 的一个重要文件是_FileInterfaceImplBase,它是实现接口的类的 子类。
实现接口
下面我们提供了downloadFile方法的一个实现。这个实现称为 仆人,正如你从代码范例6中看到的那样,类FileServant扩展了 _FileInterfaceImplBase类,以便把这个仆人指定为一个CORBA 对象。
代码范例 6: FileServant.java
import java.io.*;
public class FileServant extends _FileInterfaceImplBase {
public byte[] downloadFile(String fileName){
File file = new File(fileName);
byte buffer[] = new byte[(int)file.length()];
try {
BufferedInputStream input = new
BufferedInputStream(new FileInputStream(fileName));
input.read(buffer,0,buffer.length);
input.close();
} catch(Exception e) {
System.out.println("FileServant Error: "+e.getMessage());
e.printStackTrace();
}
return(buffer);
}
}
开发服务器
下一步是开发CORBA服务器。代码范例7中的FileServer类实现 了一个CORBA服务器,它做了这么一些事情:
初始化ORB
创建一个FileServant对象
在CORBA命名服务(COS命名)中登记该对象
输出一条状态消息
等待客户机的请求到来
代码范例 7: FileServer.java
import java.io.*;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
import org.omg.CORBA.*;
public class FileServer {
public static void main(String args[]) {
try{
// create and initialize the ORB
ORB orb = ORB.init(args, null);
// create the servant and register it with the ORB
FileServant fileRef = new FileServant();
orb.connect(fileRef);
// get the root naming context
org.omg.CORBA.Object objRef =
orb.resolve_initial_references("NameService");
NamingContext ncRef = NamingContextHelper.narrow(objRef);
// Bind the object reference in naming
NameComponent nc = new NameComponent("FileTransfer", " ");
NameComponent path[] = {nc};
ncRef.rebind(path, fileRef);
System.out.println("Server started....");
// Wait for invocations from clients
java.lang.Object sync = new java.lang.Object();
synchronized(sync){
sync.wait();
}
} catch(Exception e) {
System.err.println("ERROR: " + e.getMessage());
e.printStackTrace(System.out);
}
}
}
FileServer有了一个ORB之后,就可以注册CORBA服务。它使用 COS命名服务进行注册,该服务由OMG制订,
用Java IDL实现。从获取指向命名服 务根的引用开始。这将返回一个普通CORBA对象。为了把这个对象用作一个
NamingContext对象,必须把它缩短(也就是强制转换)为适当类 型,用下列语句实现:
NamingContext ncRef = NamingContextHelper.narrow(objRef);
ncRef对象现在变成了 org.omg.CosNaming.NamingContext。 你可以使用rebind 方法,用这个对象在命名服务中注册一项CORBA服务。
开发客户机
下一步是开发客户机。代码范例8中演示了一个实现。获得指向命名服务的引 用之后,就可以用它来访问命名服务和查找其他服务(例如FileTransferFileTransfer服务时,将调用downloadFile 方法。
代码范例 8: FileClient
import java.io.*;
import java.util.*;
import org.omg.CosNaming.*;
import org.omg.CORBA.*;
public class FileClient {
public static void main(String argv[]) {
try {
// create and initialize the ORB
ORB orb = ORB.init(argv, null);
// get the root naming context
org.omg.CORBA.Object objRef =
orb.resolve_initial_references("NameService");
NamingContext ncRef = NamingContextHelper.narrow(objRef);
NameComponent nc = new NameComponent("FileTransfer", " ");
// Resolve the object reference in naming
NameComponent path[] = {nc};
FileInterfaceOperations fileRef =
FileInterfaceHelper.narrow(ncRef.resolve(path));
if(argv.length < 1) {
System.out.println("Usage: java FileClient filename");
}
// save the file
File file = new File(argv[0]);
byte data[] = fileRef.downloadFile(argv[0]);
BufferedOutputStream output = new
BufferedOutputStream(new FileOutputStream(argv[0]));
output.write(data, 0, data.length);
output.flush();
output.close();
} catch(Exception e) {
System.out.println("FileClient Error: " + e.getMessage());
e.printStackTrace();
}
}
}
运行应用程序
最后一步是运行应用程序。这其中包括几个子步骤:
运行CORBA命名服务。这可以使用命令tnameserv。 缺省情况下,该服务在端口900上运行。如果不能在这个端口运行命名服务, 你可以在其他端口上启动它。例如,要在端口2500上启动命名服务,请使用以 下命令:
prompt> tnameserv -ORBinitialPort 2500
启动服务器。如下所示,假定命名服务是在缺省的端口号上运行:
prompt> java FileServer
如果命名服务运行于其他端口之上,比如2500,则需要使用 ORBInitialPort选项来指定端口,如下所示:
prompt> java FileServer -ORBInitialPort 2500
生成用于客户机的存根。在可以运行客户机之前,先要生成客户机 的存根。为此需要复制FileInterface.idl文件,并使用idlj编 译器来编译它,在编译前指定希望生成的结果是客户机端存根,如下所示:
prompt> idlj -fclient FileInterface.idl
运行客户机假定命名服务在端口2500上运行,那么现在就可以使用 以下命令来运行客户机了。
prompt> java FileClient hello.txt -ORBInitialPort 2500
其中hello.txt是我们要从服务器下载的文件。
注意: 如果要在另一台主机上运行命名服务,请使用 -ORBInitialHost/CODE>选项,指定它在哪台主机上运行。例如,如果 要在名为gosling的主机的端口号4500上运行命名服务,则使用 以下命令启动客户机:
prompt> java FileClient hello.txt -ORBInitialHost gosling -ORBInitialPort 4500
另一种做法是,在代码级使用属性指定这些选项。所以除了像下面这样初始化 ORB:
ORB orb = ORB.init(argv, null);
还可以通过指定CORBA服务器所在机器(名为gosling)和命名服务的端口号( 2500)来进行初始化,如下所示:
Properties props = new Properties();
props.put("org.omg.CORBA.ORBInitialHost", "gosling");
props.put("orb.omg.CORBA.ORBInitialPort", "2500");
ORB orb = ORB.init(args, props);
练习
在文件传输应用程序中,客户机必须预先知道要下载的文件的名称(RMI和 CORBA中都是如此)。可是并未提供列出服务器上可用文件的方法。作为练习, 你也许希望改进这个应用程序,添加一个列出服务器上可用文件的方法。另外, 你可能不想使用命令行客户机,而开发一个基于GUI的客户机。在客户机启动时, 它调用服务器上的一个方法,获得文件列表,然后弹出一个菜单,显示可用的文 件,用户可以从中选择一个或多个要下载的文件,如图1所示。
CORBA与RMI的比较
从编码的角度看,很明显RMI更易于使用,因为Java开发者不需要熟悉接口定 义语言(IDL)。但是总的说来,CORBA在以下方面与RMI有所不同:
CORBA接口用IDL定义,RMI接口用Java定义。RMI-IIOP允许你用Java定义 所有接口(请参见 RMI-IIOP)。
CORBA支持in和out参数,而RMI不支持,因为 本地对象是通过复制传送的,远程对象是通过引用传送的。
CORBA被特意设计成与语言不相关。举例来说,这意味着可以用Java编写一 些对象,用C++编写其他对象,而它们仍然可以协同工作。所以,作为不同编程 语言间的桥梁,CORBA是一种理想机制。与此不同,RMI为一种单独的语言设计, 所有对象都可用Java编写。但是请注意,用RMI-IIOP有可能达到协同工作的能 力。
CORBA对象不能进行碎片收集。正如我们前面说的,CORBA与语言无关,某 些语言(比如C++)不支持碎片收集。可以认为这是项缺点,因为CORBA对象一 旦创建,就一直存在,直至被除去为止,而决定何时除去一个对象的工作量可 不小。与此相反,RMI对象会自动收集碎片。
结论
开发基于分布式对象的应用程序可以在Java中用RMI或JavaIDL(CORBA的一个 实现)完成。这两种技术的用法类似,第一步都是定义对象的接口。但是与RMI 用Java定义接口不同,CORBA接口是用接口定义语言(IDL)定义的。可是这就多 了一层复杂度,开发者需要熟悉IDL,同样重要的是,还要熟悉它到Java的映射。
在这两种分布式机制中如何选择,取决于当前项目及其需求。我希望此文能为 你开发基于分布式对象的应用程序提供足够的信息,为帮助你选择分布式机制提 供足够的指导。
更多信息
- RMI
- CORBA规范(OMG)
- JavaIDL
- 《用Java进行分布式编程》一书(第11章: CORBA概述)
- CORBA服务器和客户机服务小程序
- RMI-IIOP
发表评论
-
Java代码混淆
2011-11-09 16:22 1851从事Java编程的人都知 ... -
HTTP认证方式
2011-06-29 13:40 1944HTTP请求报头: Authorization HTTP响应报 ... -
Eclipse Plugin
2011-06-09 16:14 880android - http://dl-ssl.google. ... -
RED HAT Linux 9下面搭建FTP环境 - VSFTPD安装
2011-05-14 15:26 10520、关于本文档 本文档是个人的学习整理。允许大家翻阅, ... -
软件版本常识和软件版本号命名规则
2011-05-12 13:21 808OEM:是给计算机厂商随 ... -
soap格式
2011-05-03 16:22 1292http://www.intertwingly.net/sto ... -
二进制,八进制,十六进制,十进制间进行相互转换
2010-12-30 16:30 870十进制转成十六进制: Integer.toHexStrin ... -
理解Spring的事务管理
2010-12-16 16:41 881什么是事务 为了完成对数据的操作,企业应用经常要求并发访问在多 ... -
理解ThreadLocal
2010-12-16 14:28 968概述 我们知道Spring通过 ... -
Spring AOP的实现
2010-12-16 13:38 1075AOP有三种织入切面的方法:其一是编译期织入,这要求使用特殊的 ... -
关注一
2010-12-15 11:19 885Spring事务的实现和优缺点,如何实现自己的事务管理 分布式 ... -
关于session的详细解释
2010-12-15 10:33 957一、术语session 在我的经验里,session这 ... -
理解JNDI和Java反射
2010-11-29 14:07 1133来自IBM社区 走出 JNDI 迷宫 JNDI 在 J2EE ... -
Java SE 6 新特性系列
2010-11-29 10:37 779http://www.ibm.com/developerwor ... -
JDK里的设计模式
2010-11-29 09:48 864下面是JDK中有关23个经典设计模式的示例,在stakeove ... -
XML中需要转义的字符
2010-10-15 15:23 1665XML转义符 转义序列各字符间不能有空格; 转义序列必须以 ... -
使用CXF框架提供Rest接口的一些设置
2010-10-15 13:56 2216由于开发中使用的数据库为utf-8编码,在使用get方法调用r ... -
HTTP Request fields
2010-09-30 14:07 1157From Accept Accept-Encoding Acc ... -
XStream别名指南
2010-09-27 14:49 9791,存在的问题 设想我们的客户端定义了一个用于XStream读 ... -
数据库索引的作用
2010-08-25 16:46 918http://baike.baidu.com/view/207 ...
相关推荐
【分布式Java程序设计:RMI与CORBA】 分布式程序设计是一种技术,允许不同计算机上的程序协同工作,仿佛它们都在同一台机器上运行。在Java世界中,RMI(Remote Method Invocation,远程方法调用)和CORBA(Common ...
本文主要介绍了两种实现分布式计算的方法:Java RMI(Remote Method Invocation)和CORBA(Common Object Request Broker Architecture)。 Java RMI是Java的核心API库,它允许Java程序在不同的虚拟机之间通信,...
本项目“java rmi+corba实现的军舰游戏(battleships)”就是这样一个典型的分布式系统应用实例,旨在帮助新手理解和掌握远程方法调用(RMI)与公共对象请求代理架构(CORBA)这两项核心技术。 首先,我们要了解Java ...
本课程旨在介绍如何使用Java Remote Method Invocation (RMI) 和 Common Object Request Broker Architecture (CORBA) 进行分布式对象编程。对于希望深入了解Java分布式环境并能够利用这两种技术进行开发的专业...
基于CORBA和JAVA RMI的分布式系统应用研究 CORBA(Common Object Request Broker Architecture)是一种公共对象请求代理体系结构,主要分为三个部分:接口定义语言(IDL)、对象请求代理(ORB)和ORB之间的互操作...
### Java RMI 用于远程调用 进行分布式开发 #### 概述 Java RMI(Remote Method Invocation)是Java平台提供的一种实现分布式计算的技术,它允许开发者在不同JVM间进行方法调用,如同调用本地对象一样简单。通过...
Java RMI(Remote Method Invocation)和CORBA(Common Object Request Broker Architecture)是两种在分布式环境中实现对象间通信的重要技术。本教程将详细讲解这两个概念及其应用。 首先,让我们了解一下RMI。RMI...
### Java RMI 分布式编程心得详解 #### 一、Java RMI 分布式编程概述 Java远程方法调用(Remote Method Invocation, RMI)是一种让位于不同Java虚拟机(Java Virtual Machine, JVM)上的对象能够互相调用彼此方法...
描述中的"远程方法调用实现的小程序",意味着这个压缩包可能包含了一个简单的Java应用,该应用演示了如何使用CORBA进行远程方法调用(Remote Method Invocation, RMI)。RMI是Java语言的一个特性,用于实现Java对象...
Java分布式应用是指利用Java编程语言构建的、运行在多台计算机上的应用程序。这些应用程序能够跨网络进行通信和数据交换,实现资源共享和协同工作。Java的平台独立性和丰富的库支持使得它成为开发分布式应用的理想...
RMI 使得 Java 远程服务程序和访问这些服务程序的 Java 客户程序的编写工作变得轻松、简单,而 CORBA 则提供了一个更为复杂的分布式对象系统。 在 Java 分布式计算解决方案中,RMI 和 CORBA 均扮演着重要的角色。...
Java编程与CORBA结合,使得Java开发者可以利用CORBA的跨平台特性,构建分布式Java应用。Java RMI(Remote Method Invocation)是Java平台内置的远程方法调用机制,而CORBA提供了更高级的、与语言无关的分布式计算...
### 分布式环境下Java RMI与RPC,JMS,CORBA,DCOM的比较 在分布式计算领域,各种远程通信协议和技术被广泛采用以实现不同系统间的交互与数据共享。本文将详细介绍Java RMI(Remote Method Invocation)、RPC...
然而,对于更复杂的跨平台、跨语言的分布式应用,CORBA可能是一个更好的选择,因为它提供了一套标准的接口和服务,可以在不同的操作系统和编程语言之间进行无缝交互。 总的来说,Java的RMI和CORBA都是解决分布式...
Java Remote Method Invocation (RMI) 是Java平台中用于构建分布式应用程序的一种重要技术。RMI允许Java对象在不同的Java虚拟机(JVM)之间调用方法,从而实现了远程对象的透明访问。这个RAR文件"JAVA RMI.rar"包含...
标题 "CORBA与RMI的比较及实例" 涉及到的是两种分布式计算技术——Common Object Request Broker Architecture (CORBA) 和 Remote Method Invocation (RMI) 的对比以及实际应用的示例。这两种技术都是为了让运行在...
本书覆盖了使用Java开发分布式应用程序的所有方面,包括Socket,RMI,CORBA,以及移动代理和Voyager。本书四部分之间相对独立,便于读者迅速掌握相关内容。另外,本书中包含了大量分布式程序的范例,这些范例将为...
综上所述,论文提出了在保留原有系统功能的前提下,通过结合CORBA和Java RMI进行二次开发的策略。这种方式既保留了旧系统的价值,又利用了Java的强大分布式网络应用能力,解决了非互联网时代系统升级面临的挑战,为...