javax.management.remote.rmi

接口
RMI 连接器是供 JMX Remote API 使用的一种连接器,后者使用 RMI 将客户端请求传输到远程 MBean 服务器。

请参见:
          描述

接口摘要
RMIConnection RMI 对象,用于将 MBeanServer 请求从客户端转发到其位于服务器端的 MBeanServer 实现。
RMIServer 用于建立到 RMI 连接器的连接的 RMI 对象。
 

类摘要
RMIConnectionImpl RMIConnection 接口的实现。
RMIConnectionImpl_Stub  
RMIConnector 一个到远程 RMI 连接器的连接。
RMIConnectorServer JMX API 连接器服务器,用于从远程客户端创建基于 RMI 的连接。
RMIIIOPServerImpl 一个 RMIServerImpl,它通过 IIOP 导出,并可创建如同由 IIOP 导出的 RMI 对象的客户端连接。
RMIJRMPServerImpl 一个 RMIServer 对象,它通过 JRMP 导出,并可创建如同由 JRMP 导出的 RMI 对象的客户端连接。
RMIServerImpl 表示连接器服务器的 RMI 对象。
RMIServerImpl_Stub  
 

软件包 javax.management.remote.rmi 的描述

RMI 连接器是供 JMX Remote API 使用的一种连接器,后者使用 RMI 将客户端请求传输到远程 MBean 服务器。此包定义了 RMI 连接器的用户直接引用客户端和服务器方所需的类。它还定义了其他一些类,用户虽然不经常直接引用这些类,但还是必须定义它们,主要是为 RMI 连接器的不同实现之间实现互操作。

RMI 连接器支持 RMI 的 JRMP 和 IIOP 传输方式。

与 JMX Remote API 中的多数连接器类似,RMI 连接器通常有一个地址,它是一个 JMXServiceURL。对于使用默认 RMI 传输方式 (JRMP) 的连接器,此地址的协议部分为 rmi;对于使用 RMI/IIOP 的连接器,地址的协议部分为 iiop

RMI 连接器地址有两种形式:

  • JNDI 形式 中,URL 指示查找连接器的 RMI 桩模块 (stub) 的位置。此 RMI 桩模块是一个类型为 RMIServer 的 Java 对象,它提供了对连接器服务器的远程访问。使用这种地址形式,可从包含在 URL 中的外部目录条目获取 RMI 桩模块。外部目录是指可由 JNDI 识别的任何目录,通常是 RMI 注册表、LDAP 或 CORBA 命名服务 (COS Naming)。
  • 编码形式 中,URL 直接包括了连接到连接器服务器所需的信息。使用 RMI/JRMP 时,编码形式是服务器对象的序列化 RMI 桩模块,它采用 BASE64 编码,未嵌入换行。使用 RMI/IIOP 时,编码形式是服务器对象的 CORBA IOR。

以下内容更详细地介绍了地址。

创建 RMI 连接器服务器

创建 RMI 连接器服务器的一般方法是为方法 JMXConnectorServerFactory.newJMXConnectorServer 提供一个 RMI 连接器地址。将与连接器服务器连接的 MBean 服务器可作为该方法的一个参数指定。或者,也可以将连接器服务器注册为该 MBean 服务器中的 MBean。

还可以通过构造 RMIConnectorServer 的实例(显式或使用 MBean 服务器的 createMBean 方法)来创建 RMI 连接器服务器。

选择 RMI 传输方式

在创建连接器服务器时,通过在 serviceURLprotocol 部分指定 rmiiiop,您可以选择 RMI 传输方式(JRMP 或 IIOP)。通过实例化 RMIServerImpl 的一个适当的子类并将其提供给 RMIConnectorServer 构造方法,还可以创建特殊的连接器服务器。

服务器生成的连接器地址

如果您指定的 serviceURL 包含空 URL 路径(在可选的主机和端口后),或者未指定 serviceURL,则连接器服务器将创建一个可供客户端连接使用的新 JMXServiceURL

  • 如果 serviceURL 如下所示:

            service:jmx:rmi://host:port
            

    则连接器服务器将生成一个 RMIJRMPServerImpl,且返回如下所示的 JMXServiceURL

            service:jmx:rmi://host:port/stub/XXXX
            

    其中,XXXX 为所生成对象的桩模块的序列化形式,其编码采用 BASE64,不带换行。

  • 如果 serviceURL 如下所示:

            service:jmx:iiop://host:port
            

    则连接器服务器将生成一个 RMIIIOPServerImpl ,且返回如下所示的 JMXServiceURL

            service:jmx:iiop://host:port/ior/IOR:XXXX
            

    其中,IOR:XXXX 为所生成对象的互操作对象引用 (Interoperable Object Reference) 的标准 CORBA 编码。

  • 如果没有 serviceURL,则必须有一个用户提供的 RMIServerImpl。如果在此对象上调用 toStub 方法返回 Stub 的实例,则连接器服务器将用上述的 iiop 形式生成 JMXServiceURL。否则,它将用 rmi 形式生成 JMXServiceURL

用户提供的 serviceURL 中的 host 为可选项。如果有这一项,则将其复制到生成的 JMXServiceURL 中,但是其他方面会忽略此项。如果没有这一项,则生成的 JXMServiceURL 将包括本地主机名。

用户提供的 serviceURL 中的 port 也是一个可选项。如果有这一项,则同样将其复制到生成的 JMXServiceURL 中;否则,生成的 JMXServiceURL 不带端口。对于使用 rmi 协议的 serviceURL,如果有 port,则它指示生成的远程对象应在该端口上导出。它没有任何其他作用。

如果用户提供了 RMIServerImpl 而不是 JMXServiceURL,则生成的 JMXServiceURL 将在其 host 部分包含本地主机名并且不带 port

基于目录条目的连接器地址

作为刚才介绍的生成地址的另外一种情况,创建连接器服务器时提供的 serviceURL 地址指定的是目录地址,其中可存储提供的或生成的 RMIServer 桩模块。然后客户端和服务器都可以使用此目录地址。

这种情况下,serviceURL 具有如下两种形式之一:

    service:jmx:rmi://host:port/jndi/jndi-name
    service:jmx:iiop://host:port/jndi/jndi-name
    

其中 jndi-name 是一个可提供给 javax.naming.InitialContext.bind 的字符串。

同样,host:port 均可忽略。

连接器服务器将基于协议(rmiiiop),对于 rmi,还包括 port(如果有)生成 RMIServerImpl。连接器服务器启动后,它将从此对象使用其 toStub 方法派生一个桩模块并使用给定的 jndi-name 保存该对象。同样也要参考由 JNDI API 定义的属性。

例如,假设 JMXServiceURL 为:

      service:jmx:rmi://ignoredhost/jndi/rmi://myhost/myname
      
则连接器服务器将生成 RMIJRMPServerImpl 并使用该 JNDI 名称保存其桩模块
      rmi://myhost/myname
      
它表示运行在主机 myhost 的默认端口上 RMI 注册表中的 myname 项。注意,RMI 注册表只允许从本地主机注册。因此在这种情况下, myhost 必须是运行连接器服务器的主机名。

在此 JMXServiceURL 中,第一个 rmi: 指定 RMI 连接器,第二个 rmi: 指定 RMI 注册表。

另举一个例子,如果 JMXServiceURL 为:

      service:jmx:iiop://ignoredhost/jndi/ldap://dirhost:9999/cn=this,ou=that
      
则该连接器服务器将生成 RMIIIOPServerImpl 并使用该 JNDI 名称保存其桩模块
      ldap://dirhost:9999/cn=this,ou=that
      
它表示 LDAP 目录中的 cn=this,ou=that 条目,该目录在运行主机 dirhost 的端口 9999 上。

如果 JMXServiceURL 为:

      service:jmx:iiop://ignoredhost/jndi/cn=this,ou=that
      
则该连接器服务器将生成 RMIIIOPServerImpl 并使用该 JNDI 名称保存其桩模块
      cn=this,ou=that
      
要在这种情况下正常工作,JNDI API 必须经过适当配置,以提供有关要使用的目录的信息。

这些示例中,主机名 ignoredhost 未被连接器服务器或其客户端使用。可将其忽略,例如:

      service:jmx:iiop:///jndi/cn=this,ou=that
      

但是,在连接器服务器运行的主机上使用主机名是一个不错的做法。主机名通常不同于目录主机的名称。

连接器服务器的属性

使用默认的 JRMP 传输方式时,可使用为 RMIConnectorServer 构造方法给定的 environment 中的 jmx.remote.rmi.client.socket.factoryjmx.remote.rmi.server.socket.factory 属性指定 RMI 套接字工厂。这些属性的值的类型必须分别为 RMIClientSocketFactoryRMIServerSocketFactory。这些工厂在创建与连接器关联的 RMI 对象时使用。

创建 RMI 连接器客户端

RMI 连接器客户端通常使用 JMXConnectorFactory 且具有协议 rmiiiopJMXServiceURL 进行构造。

如果 JMXServiceURL 由服务器生成,如上文中的“服务器生成的连接器地址”所述,则客户端将需要直接或间接地从服务器获取该值。通常,服务器将 JMXServiceURL 存储在一个文件或查找服务中以便于使用。

如果 JMXServiceURL 使用目录语法,如上文中的“基于目录条目的连接器地址”所述,则客户端可用刚刚介绍的方法获取该值,或者客户端和服务器可能都知道要使用的适当目录条目。例如,如果 Whatsit 代理的连接器服务器使用主机 myhost 上 RMI 注册表中的 whatsit-agent-connector 条目,则客户端和服务器都知道适当的 JMXServiceURL 为:

    service:jmx:rmi:///jndi/rmi://myhost/whatsit-agent-connector
    

如果 RMI 桩模块的类型为 RMIServer,则可以使用 RMIConnector 的适当构造方法直接构造 RMI 连接。

为 RMI/IIOP 连接器指定一个 ORB

使用 IIOP 传输方式时,客户端和服务器可使用属性 java.naming.corba.orb 指定要使用的 ORB。连接器服务器连接到 ORB 的动作发生时间为 start,连接器客户端连接到 ORB 的动作发生时间为 connect。如果 java.naming.corba.orb 属性包含在环境 Map 中,则其值(一个 ORB)将用于连接 IIOP Stub。否则,将通过调用 org.omg.CORBA.ORB.init((String[])null,(Properties)null) 创建一个新的 org.omg.CORBA.ORB。位于同一 JVM 中的后续 RMI 连接器客户端或服务器可重用此 ORB,或者可用同样的方式创建另一个 ORB。

如果指定了 java.naming.corba.orb 属性但它并不指向一个 ORB,则将抛出 IllegalArgumentException

当 IIOP 远程对象(Stub 或 Server)在被传入到 RMIConnector 和 RMIConnectorServer 之前通过手动创建和连接到 ORB 时,这里描述的机制将不适用。

动态代码下载

如果 RMI 连接器客户端或服务器从其同级设备收到一个无法识别的类实例,并且动态代码下载此时可以进行 RMI 连接,则可以从同级设备指定的代码基下载类。文章 Dynamic code downloading using Java RMI 对此进行了详细解释。

从以下版本开始:
1.5
另请参见:
JavaTM Remote Method Invocation (RMI), Java Naming and Directory InterfaceTM (JNDI), RFC 2045, section 6.8, "Base64 Content-Transfer-Encoding"