基本介紹
- 中文名:RMI 遠程方法調用
- 外文名:Remote Method Invocation
RMI 連線器地址兩種形式,JNDI 形式,編碼形式,使用,創建 RMI 連線器伺服器,選擇 RMI 傳輸方式,伺服器生成的連線器地址,基於目錄條目的連線器地址,連線器伺服器的屬性,創建 RMI 連線器客戶端,為 RMI/IIOP 連線器指定一個 ORB,另請參見,
RMI 連線器地址兩種形式
JNDI 形式
在 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 連線器伺服器
創建 RMI 連線器伺服器的一般方法是為方法 JMXConnectorServerFactory.newJMXConnectorServer 提供一個 RMI 連線器地址。連線器伺服器要連線到的 MBean 伺服器可作為該方法的一個參數指定。或者,也可以將連線器伺服器註冊為該 MBean 伺服器中的 MBean。
還可以通過構造 RMIConnectorServer 的實例(顯式或使用 MBean 伺服器的 createMBean 方法)來創建 RMI 連線器伺服器。
選擇 RMI 傳輸方式
在創建連線器伺服器時,通過在 serviceURL 的 protocol 部分指定 rmi 或 iiop,您可以選擇 RMI 傳輸方式(JRMP 或 IIOP)。通過實例化 RMIServerImpl 的一個適當的子類並將其提供給 RMIConnectorServer 構造方法,您還可以創建特殊的連線器伺服器。
伺服器生成的連線器地址
如果 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
在此 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 必須經過適當配置,以提供有關要使用的目錄的信息。
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 連線器客戶端
RMI 連線器客戶端通常使用 JMXConnectorFactory 且具有協定 rmi 或 iiop 的 JMXServiceURL 進行構造。
如果 JMXServiceURL 由伺服器生成,如上文中的“伺服器生成的連線器地址”所述,則客戶端將需要直接或間接地從伺服器獲取該值。通常情況下,伺服器將 JMXServiceURL 存儲在一個檔案或查找服務中以便使用。
service:jmx:rmi:///jndi/rmi://myhost/whatsit-agent-connector
如果 RMI stub 的類型為 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 時,這裡描述的機制將不適用。
另請參見
JavaTM Remote Method Invocation (RMI), Java Naming and Directory InterfaceTM (JNDI), RFC 2045, section 6.8, "Base64 Content-Transfer-Encoding"