Java RMI 之 Introduction


    注:主要内容参考官方文档。同时已经有人把翻译过Sun上RMI的lesson,如果想学习技术实例,可以查看,参考资源给出了链接。

Overview

Java Remote Method Invocation (Java RMI) enables the programmer to create distributed Java technology-based
 to Java technology-based applications, in which the methods of remote Java objects can be invoked from
other Java virtual machines, possibly on different hosts. RMI uses object serialization to marshal and
unmarshal parameters and does not truncate types, supporting true object-oriented polymorphism.

使用Java RMI,可以创建分布式的Java应用程序,远程的Java对象的方法可以被不同的主机中不同的Java虚拟机调用。RMI使用对象序列化传递参数,并且不会丢失类型,支持面向对象的多态性。




Introduction

1.1 Background(背景)

Distributed systems require that computations running in different address spaces, potentially on different
 hosts, be able to communicate. For a basic communication mechanism, the JavaTM programming language
supports sockets, which are flexible and sufficient for general communication. However, sockets require the
client and server to engage in applications-level protocols to encode and decode messages for exchange, and the design of such protocols is cumbersome and can be error-prone.

An alternative to sockets is Remote Procedure Call (RPC), which abstracts the communication interface to the
 level of a procedure call. Instead of working directly with sockets, the programmer has the illusion of
calling a local procedure, when in fact the arguments of the call are packaged up and shipped off to the
remote target of the call. RPC systems encode arguments and return values using an external data
representation, such as XDR.

RPC, however, does not translate well into distributed object systems, where communication between
program-level objects residing in different address spaces is needed. In order to match the semantics of
object invocation, distributed object systems require remote method invocation or RMI. In such systems, a
local surrogate (stub) object manages the invocation on a remote object.

The Java platform's remote method invocation system described in this specification has been specifically
designed to operate in the Java application environment. The Java programming language's RMI system assumes the homogeneous environment of the Java virtual machine (JVM), and the system can therefore take advantage
of the Java platform's object model whenever possible.

分布式系统要求计算能不同的地址空间上,也就是说在不同的主机上,要能进行通讯,对于基本的Java通讯机制,Java支持Sokets,对于一般的通讯来说Sockets足够了,但是Sockets要求客户端和服务器端使用应用级别的协议交换消息,并且这个协议比较笨重。

另外一个选择就是RCP,RCP就是针对远程调用级别抽象出一个通讯接口。而不是直接的使用sockets,参数的调用被包装起来,使用时看起来就像本地调用过程,RCP系统编码参数和返回值使用的是外部数据请求,比如XDR

在分布式系统中,程序级别的对象必须存在不同的地址空间中,然而RCP不能很好的支持。为了匹配语法上的对象调用,分布式系统要求使用RMI,在这样一个系统中,一个代理(存根)对象管理一个远程对象的调用。

规范中描述Java平台RMI系统被是为Java应用环境特别设计。Java RMI系统假定其拥有相似的JVM环境



1.2 System Goals(系统目标)

The goals for supporting distributed objects in the Java programming language are:

    * Support seamless remote invocation on objects in different virtual machines
    * Support callbacks from servers to applets
    * Integrate the distributed object model into the Java programming language in a natural way while
      retaining most of the Java programming language's object semantics
    * Make differences between the distributed object model and local Java platform's object model apparent
    * Make writing reliable distributed applications as simple as possible
    * Preserve the type-safety provided by the Java platform's runtime environment
    * Support various reference semantics for remote objects; for example live (nonpersistent) references,
      persistent references, and lazy activation
    * Maintain the safe environment of the Java platform provided by security managers and class loaders


在Java中支持分布式对象的目标如下:

    * 支持不同的虚拟机之间无缝的调用远程对象。
    * 支持从服务器端回执给applets
    * 保持大部分java对象原有的语义,以一种很自然的方式把分布式对象模型整合于Java语言
    * 区分分布式对象模型和本地平台的对象模型
    * 尽可能简单的构建可靠的分布式应用
    * 有Java运行环境保护类型(Type)安全
    * 远程对象支持各种语义上的引用(reference),比如:live references,持久引用和延迟激活。
      使用安全管理器(security managers)和类加载器(class loaders)保护java平台的环境安全。




Java Distributed Object Model

2.1 Distributed Object Applications

RMI applications are often comprised of two separate programs: a server and a client. A typical server
application creates a number of remote objects, makes references to those remote objects accessible, and
waits for clients to invoke methods on those remote objects. A typical client application gets a remote
reference to one or more remote objects in the server and then invokes methods on them. RMI provides the
mechanism by which the server and the client communicate and pass information back and forth. Such an
application is sometimes referred to as a distributed object application.

Distributed object applications need to:
    * Locate remote objects
Applications can use one of two mechanisms to obtain references to remote objects. An application can   
register its remote objects with RMI's simple naming facility, the rmiregistry, or the application can pass
and return remote object references as part of its normal operation.
    * Communicate with remote objects
Details of communication between remote objects are handled by RMI; to the programmer, remote communication
looks like a standard method invocation. 
    * Load class bytecodes for objects that are passed as parameters or return values
Because RMI allows a caller to pass objects to remote objects, RMI provides the necessary mechanisms for
loading an object's code as well as transmitting its data.


RMI应用程序经常是由两个单独的程序组成:服务器端和客户端,
一个典型的服务器端应用创建一系列远程对象,并使其对象的引用可访问,等客户端来调用远程对象的方法。一个典型的客户端获取一个服务器端远程对象(一个或多个)的远程引用,然后调用他们的方法。RMI提供机制让服务器端和客户端进行通讯和来回传递信息。像这样一个应用就是分布式应用。



分布式应用必须:

   * 查找远程对象
    应用程序下面两者之一的机制来获得远程对象的引用。一个应用程序可以使用RMI的简单命名在注册处注册它的远程对象,或者应用程序可以像普通操作一样传递和返回远程对象的引用。

   *与远程对象进行通讯、
    远程对象之间的通讯具体操作有RMI来提供,使用时只要当作正常的方法调用即可。

   * 加载对象的字节码使其可以作为参数或返回值传递。
     因为RMI允许调用者传递对象到远程对象,RMI提供必要的机制加载对象的代码和传输它数据。


The illustration below depicts an RMI distributed application that uses the registry to obtain references to
 a remote object. The server calls the registry to associate a name with a remote object. The client looks
up the remote object by its name in the server's registry and then invokes a method on it. The illustration also shows that the RMI system uses an existing web server to load bytecodes of classes written in the Java programming language, from server to client and from client to server, for objects when needed. RMI can load
 class bytecodes using any URL protocol (e.g., HTTP, FTP, file, etc.) that is supported by the Java platform.

下 面这幅图描述了一个RMI分布式应用程序,用户使用registry获得一个远程对象的引用,Server端调用registry使用名字和一个远程对象 关联。客户端在Server的registry中查找远程对象的引用并调用其方法。同时这个图也描述了,在需要时,RMI系统使用已经存在的 web server在client端和Server端之间加载Java Class的字节码。RMI可以使用URL协议(如e.g., HTTP,  FTP, file, etc),这些Java平台都支持






2.3 The Distributed and Nondistributed Models Contrasted

The Java SE platform's distributed object model differs from the Java SE platform's object model in these
ways:
*    Clients of remote objects interact with remote interfaces, never with the implementation classes of
those interfaces.
*    Non-remote arguments to, and results from, a remote method invocation are passed by copy rather than by
 reference. This is because references to objects are only useful within a single virtual machine.
*    A remote object is passed by reference, not by copying the actual remote implementation.
*    The semantics of some of the methods defined by class java.lang.Object are specialized for remote
objects.
*    Since the failure modes of invoking remote objects are inherently more complicated than the failure
modes of invoking local objects, clients must deal with additional exceptions that can occur during a remote
 method invocation.

Java SE平台的分布式对象模型普通对象模型的区别:

* 远程对象的Client端只与远程接口进行交互,不触及接口的实现。
* 不管是参数传递还是值返回,远程方法调用时传递的都是值的Copy而不是引用,因为一个对象的引用只有在单个虚拟机中有用。
* 远程对象传递的是引用,而不是copy实际的远程实现。
* Java.lang.Object为远程对象定义了一些专门的方法
* 调用远程对象天生就比调用本地方法,在失败mode上要复杂。所以客户端要处理远程调用中出现的额外的异常



参考资源:

     RMI lesson翻译: http://www.blogjava.net/jht/archive/2007/05/09/116216.html
     官方文档:http://java.sun.com/javase/6/docs/technotes/guides/rmi/index.html