javax.management.remote.rmi

描述 RMI 连接器是供 JMX Remote API 使用的一种连接器,后者使用 RMI 将客户端请求传输到远程 MBean 服务器。此包定义了 RMI 连接器的用户直接引用客户端和服务器方所需的类。

它还定义了某些类,用户虽然不经常直接引用这些类但还必须定义,主要是为 RMI 连接器的不同实现之间实现互操作。 RMI 连接器支持 RMI 的 JRMP 和 IIOP 传输方式。 与 JMX Remote API 中的多数连接器类似,RMI 连接器通常有一个地址,它是一个 JMXServiceURL。

在 JNDI 形式 中,URL 指示查找连接器的 RMI stub 的位置。此 RMI stub 是一个类型为 RMIServer 的 Java 对象,它提供了对连接器服务器的远程访问。使用这种地址形式,可从包含在 URL 中的外部目录条目获取 RMI stub。外部目录是指可由 JNDI 识别的任何目录,通常是 RMI 注册表、LDAP 或 CORBA 命名服务 (COS Naming)。

在编码形式 中,URL 直接包括了连接到连接器服务器所需的信息。使用 RMI/JRMP 时,编码形式是服务器对象的序列化 RMI stub,它采用 BASE64 编码,未嵌入换行。使用 RMI/IIOP 时,编码形式是服务器对象的 CORBA IOR。

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

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

在创建连接器服务器时,通过在 serviceURL 的 protocol 部分指定 rmi 或 iiop,您可以选择 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 为所生成对象的 stub 的序列化形式,其编码采用 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 stub。然后客户端和服务器都可以使用此目录地址。

这种情况下,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 均可忽略。

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

例如,假设 JMXServiceURL 为:

service:jmx:rmi://ignoredhost/jndi/rmi://myhost/myname

则连接器服务器将生成 RMIJRMPServerImpl 并使用该 JNDI 名称保存其 stub

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 名称保存其 stub

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 名称保存其 stub

cn=this,ou=that

要在这种情况下正常工作,JNDI API 必须经过适当配置,以提供有关要使用的目录的信息。

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

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

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

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

RMI 连接器客户端通常使用 JMXConnectorFactory 且具有协议 rmi 或 iiop 的 JMXServiceURL 进行构造。

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

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

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

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

使用 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 时,这里描述的机制将不适用。

JavaTM Remote Method Invocation (RMI), Java Naming and Directory InterfaceTM (JNDI), RFC 2045, section 6.8, "Base64 Content-Transfer-Encoding"

相关词汇