無(wú)為

          無(wú)為則可為,無(wú)為則至深!

            BlogJava :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
            190 Posts :: 291 Stories :: 258 Comments :: 0 Trackbacks
          第 7 章   

          主題:  
          概述  
          激活協(xié)議  
          “可激活”遠(yuǎn)程對(duì)象的實(shí)現(xiàn)模型  
          激活接口  

          .1 概述 
          分布式對(duì)象系統(tǒng)被設(shè)計(jì)為支持長(zhǎng)期存在的持久對(duì)象。假設(shè)這些系統(tǒng)將由成千(也 
          許成萬(wàn))個(gè)這樣的對(duì)象組成,則對(duì)象的實(shí)現(xiàn)在無(wú)限期的時(shí)間段內(nèi)被激活并保持活 
          動(dòng)狀態(tài)是不合理的。這將占用寶貴的系統(tǒng)資源。另外,客戶(hù)機(jī)需要保存對(duì)對(duì)象的 
          持久引用的能力,這樣在一個(gè)系統(tǒng)崩潰后可以重新建立對(duì)象之間的通訊,因?yàn)橥?nbsp;
          常對(duì)一個(gè)分布對(duì)象的引用只有當(dāng)對(duì)象處于活動(dòng)狀態(tài)時(shí)才有效。 

          對(duì)象激活是一種用來(lái)提供對(duì)對(duì)象持久引用和管理對(duì)象實(shí)現(xiàn)的執(zhí)行的機(jī)制。在 RMI 
           中,激活允許對(duì)象根據(jù)需要開(kāi)始執(zhí)行。當(dāng)訪問(wèn)(通過(guò)方法調(diào)用)“可激活”遠(yuǎn)程 
          對(duì)象時(shí),如果該遠(yuǎn)程對(duì)象當(dāng)前尚未執(zhí)行,則系統(tǒng)將在適當(dāng)?shù)?nbsp;Java 虛擬機(jī)中開(kāi)始 
          該對(duì)象的執(zhí)行。 

          7.1.1 術(shù)語(yǔ)  
          活動(dòng) (active) 對(duì)象是在某些系統(tǒng)的 Java 虛擬機(jī)中被實(shí)例化并被導(dǎo)出的遠(yuǎn)程對(duì) 
          象。非活動(dòng)對(duì)象在虛擬機(jī)中尚未被實(shí)例化(或?qū)С觯?,但能變成活?dòng)狀態(tài)的遠(yuǎn)程 
          對(duì)象。激活就是將非活動(dòng)對(duì)象轉(zhuǎn)化為活動(dòng)對(duì)象的過(guò)程。激活要求對(duì)象與一臺(tái)虛擬 
          機(jī)相關(guān)聯(lián),而這將可能需要將該對(duì)象的類(lèi)加載到虛擬機(jī)中,同時(shí)該對(duì)象也恢復(fù)其 
          持久狀態(tài)(如果有)。 

          在 RMI 系統(tǒng)中,我們使用了惰性激活。惰性激活就是將一個(gè)對(duì)象的激活延遲到客 
          戶(hù)機(jī)第一次使用該對(duì)象時(shí)(即第一次方法調(diào)用時(shí))。 

          7.1.2 惰性激活  
          遠(yuǎn)程對(duì)象的惰性激活是用不完善遠(yuǎn)程引用(有時(shí)稱(chēng)為不完善塊)實(shí)現(xiàn)的。對(duì)遠(yuǎn)程 
          對(duì)象的不完善遠(yuǎn)程引用在第一次調(diào)用對(duì)象的方法時(shí),“完善”為活動(dòng)對(duì)象的引用 
          。每個(gè)不完善引用均保持一個(gè)持久句柄(激活標(biāo)識(shí)符)和對(duì)目標(biāo)遠(yuǎn)程對(duì)象的瞬態(tài) 
          遠(yuǎn)程引用。遠(yuǎn)程對(duì)象的激活標(biāo)識(shí)符包含足夠的信息來(lái)使第三方激活該對(duì)象。瞬態(tài) 
          引用是對(duì)可用來(lái)聯(lián)系執(zhí)行對(duì)象的主動(dòng)遠(yuǎn)程對(duì)象的“活動(dòng)”引用。 

          在不完善引用中,如果對(duì)遠(yuǎn)程對(duì)象的活引用為空,則不認(rèn)為目標(biāo)對(duì)象是主動(dòng)的。 
          在方法調(diào)用中,不完善引用(對(duì)該對(duì)象)將加入激活協(xié)議以獲得“活”引用,該 
          引用是對(duì)新激活的對(duì)象的遠(yuǎn)程引用(例如單路傳送 (unicast) 的遠(yuǎn)程引用)。一 
          旦不完善引用得到活引用,則不完善引用將把方法調(diào)用傳給底層的遠(yuǎn)程引用,而 
          該遠(yuǎn)程引用又將方法調(diào)用傳給遠(yuǎn)程對(duì)象。 

          具體的說(shuō),遠(yuǎn)程對(duì)象的 stub 包含一個(gè)“不完善”遠(yuǎn)程引用類(lèi)型,該類(lèi)型既包括: 

          遠(yuǎn)程對(duì)象的激活標(biāo)識(shí)符,又包括  
          “活”引用(可能為空),其中包含遠(yuǎn)程對(duì)象的“活動(dòng)”遠(yuǎn)程引用類(lèi)型(例如, 
          帶有單路傳送語(yǔ)義的遠(yuǎn)程引用類(lèi)型)。  

          ---------------------------------------------------------------------- 
          ---------- 

          注意 - RMI 系統(tǒng)對(duì)遠(yuǎn)程調(diào)用保留“至多一次”語(yǔ)義。換句話說(shuō),對(duì)可激活或單路 
          傳送遠(yuǎn)程對(duì)象的調(diào)用將至多發(fā)送一次。因此,如果對(duì)遠(yuǎn)程對(duì)象的調(diào)用失?。ㄓ蓲?nbsp;
          出的 RemoteException 異常表示),則客戶(hù)機(jī)將得到如下保證:遠(yuǎn)程方法的執(zhí)行 
          不會(huì)超過(guò)一次,甚至根本就不執(zhí)行。 

          7.2 激活協(xié)議 
          在遠(yuǎn)程方法調(diào)用期間,如果目標(biāo)對(duì)象的“活”(live) 引用是未知的,則不完善引 
          用將褂眉せ钚欏<せ钚榘ㄏ鋁屑父鍪堤澹翰煌晟埔謾⒓せ釔鰲ava 虛 
          擬機(jī)中的激活組和被激活的遠(yuǎn)程對(duì)象。 

          激活器(通常每個(gè)主機(jī)有一個(gè))是一個(gè)實(shí)體,負(fù)責(zé)激活,它是: 

          將激活標(biāo)識(shí)符映射到激活對(duì)象所需信息(對(duì)象的類(lèi)、位置 -- URL 路徑 -- 從該 
          處可加載類(lèi)、對(duì)象可能需要用于自舉 (bootstrap) 的特定數(shù)據(jù)等)的信息數(shù)據(jù)庫(kù),及  
          Java 虛擬機(jī)的管理器,它啟動(dòng)虛擬機(jī)(必要時(shí))并將對(duì)象激活請(qǐng)求(和必要的信 
          息一起)傳送到遠(yuǎn)程虛擬機(jī)中正確的激活組。  
          注意:激活器始終將激活標(biāo)識(shí)符到活動(dòng)對(duì)象的當(dāng)前映射保存在緩存中,這樣就無(wú) 
          需為每個(gè)激活請(qǐng)求而查詢(xún)?cè)摻M。 

          激活組(每個(gè) Java 虛擬機(jī)中一個(gè))是這樣的實(shí)體,它接收對(duì)激活 Java 虛擬機(jī) 
          中對(duì)象的請(qǐng)求并將激活的對(duì)象返給激活器。 

          激活協(xié)議如下所示。不完善引用使用一個(gè)激活標(biāo)識(shí)符并調(diào)用激活器(內(nèi)部 RMI 接 
          口)來(lái)激活與該標(biāo)識(shí)符關(guān)聯(lián)的對(duì)象。激活器查找對(duì)象的激活描述符(先前已注冊(cè) 
          )。對(duì)象的描述符包括: 

          對(duì)象的組標(biāo)識(shí)符(指定對(duì)象激活時(shí)所處的虛擬機(jī)),  
          對(duì)象的類(lèi)名,  
          URL 路徑,從該處加載對(duì)象的類(lèi)代碼,  
          特定于對(duì)象的已編組的初始化數(shù)據(jù)(例如,初始化數(shù)據(jù)可能是包含對(duì)象持久狀態(tài) 
          的文件的名稱(chēng))。  
          如果應(yīng)容納該對(duì)象的激活組存在,則激活器將激活請(qǐng)求傳送到該組。如果激活組 
          不存在,則激活器將啟動(dòng)虛擬機(jī)以執(zhí)行激活組,然后將激活請(qǐng)求傳送到該組。 

          激活組將加載對(duì)象的類(lèi)并用特定的構(gòu)造函數(shù)來(lái)實(shí)例化該對(duì)象。此構(gòu)造函數(shù)帶多個(gè) 
          參數(shù),包括先前注冊(cè)的激活描述符。 

          對(duì)象完成激活時(shí),激活組將把已編組對(duì)象引用傳回激活器,然后該激活器記錄激 
          活標(biāo)識(shí)符和激活引用對(duì),并將活動(dòng)(活)引用返給不完善引用。隨后,不完善引 
          用(在 stub 內(nèi))通過(guò)活動(dòng)引用將方法調(diào)用直接傳給遠(yuǎn)程對(duì)象。 


          ---------------------------------------------------------------------- 
          ---------- 
          注意 - 在 JDK 中,RMI 提供激活系統(tǒng)接口的實(shí)現(xiàn)。要使用激活,必須首先運(yùn)行 
          激活系統(tǒng)守護(hù)進(jìn)程 (daemon) rmid。 

          7.3 “可激活”遠(yuǎn)程對(duì)象的實(shí)現(xiàn)模型 
          為了使可通過(guò)激活標(biāo)識(shí)符訪問(wèn)的遠(yuǎn)程對(duì)象不受時(shí)間影響,開(kāi)發(fā)人員必須做到: 

          為該遠(yuǎn)程對(duì)象注冊(cè)一個(gè)激活描述符  
          在對(duì)象的類(lèi)中包含一個(gè)專(zhuān)用構(gòu)造函數(shù),當(dāng) RMI 系統(tǒng)激活可激活對(duì)象時(shí)將調(diào)用它。 

          可用以下幾種方法來(lái)注冊(cè)激活描述符 (ActivationDesc): 

          調(diào)用類(lèi) Activatable 的靜態(tài) register 方法  
          用 Activatable 類(lèi)的第一個(gè)或第二個(gè)構(gòu)造函數(shù)創(chuàng)建“可激活”對(duì)象  
          顯式地導(dǎo)出“可激活”對(duì)象。該過(guò)程可用 Activatable 的第一個(gè)或第二個(gè) expo 
          rtObject 方法實(shí)現(xiàn),其參數(shù)為 ActivationDesc、Remote 對(duì)象的實(shí)現(xiàn)和端口號(hào)。 
            
          對(duì)于特定對(duì)象,只可用上述三種方法之一來(lái)注冊(cè)激活對(duì)象。有關(guān)如何實(shí)現(xiàn)可激活 
          對(duì)象的示例,請(qǐng)參閱后面的“構(gòu)造可激活遠(yuǎn)程對(duì)象”。 

          7.3.1 ActivationDesc 類(lèi)  
          ActivationDesc 含有激活對(duì)象所需的信息。它包含對(duì)象的激活組標(biāo)識(shí)符、對(duì)象的 
          類(lèi)名、加載對(duì)象代碼的 codebase 路徑(或 URL)及 MarshalledObject(可包含 
          每次激活期間所用的對(duì)象特定初始化數(shù)據(jù))。  

          激活過(guò)程中將查詢(xún)?cè)诩せ钕到y(tǒng)中注冊(cè)的描述符以獲取有關(guān)的信息,從而用于重新 
          創(chuàng)建或激活對(duì)象。對(duì)象的描述符中的 MarshalledObject 將作為第二個(gè)參數(shù)傳給 
          遠(yuǎn)程對(duì)象的構(gòu)造函數(shù),以供激活過(guò)程使用。 

          package java.rmi.activation; 

          public final class ActivationDesc implements java.io.Serializable 

              public ActivationDesc(String className, String codebase, 
                                    java.rmi.MarshalledObject data) 
                  throws ActivationException; 
              public ActivationDesc(String className, String codebase, 
                                    java.rmi.MarshalledObject data, 
                                    boolean restart) 
                  throws ActivationException; 
              public ActivationDesc(ActivationGroupID groupID, 
                                    String className, 
                                    String codebase, 
                                    java.rmi.MarshalledObject data, 
                                    boolean restart); 
              public ActivationDesc(ActivationGroupID groupID, 
                                    String className, 
                                    String codebase, 
                                    java.rmi.MarshalledObject data); 
              public ActivationGroupID getGroupID(); 
              public String getClassName(); 
              public String getLocation(); 
              public java.rmi.MarshalledObject getData() 
              public boolean getRestartMode(); 
          }

          ActivationDesc 的第一個(gè)構(gòu)造函數(shù)構(gòu)造一個(gè)對(duì)象的對(duì)象描述符,這個(gè)對(duì)象的類(lèi)是 
           className(可從 codebase 路徑加載),它的初始化信息(已編組形式)為 d 
          ata。如果使用這種形式的構(gòu)造函數(shù),則對(duì)象的組標(biāo)識(shí)符缺省為該虛擬機(jī) Activa 
          tionGroup 的當(dāng)前標(biāo)識(shí)符。具有相同 ActivationGroupID 的所有對(duì)象都將在同一 
          虛擬機(jī)中被激活。如果當(dāng)前組是非活動(dòng)的或無(wú)法創(chuàng)建缺省組,則將拋出 Activat 
          ionException。如果 groupID 為 null,則將拋出 IllegalArgumentException。 
           


          ---------------------------------------------------------------------- 
          ---------- 

          注意 - 作為創(chuàng)建 ActivationDesc 的副效應(yīng),如果該虛擬機(jī)的 ActivationGrou 
          p 當(dāng)前不是活動(dòng)的,則將創(chuàng)建缺省 ActivationGroup。缺省激活組將 java.rmi. 
          RMISecurityManager 作為安全管理器,并在重新激活時(shí)將激活組虛擬機(jī)中的屬性 
          設(shè)置為該虛擬機(jī)中的當(dāng)前屬性。如果應(yīng)用程序需用不同的安全管理器,則在創(chuàng)建 
          缺省 ActivationDesc 之前必須設(shè)置該虛擬機(jī)的組。有關(guān)如何為虛擬機(jī)創(chuàng)建 Act 
          ivationGroup 的詳細(xì)信息,參見(jiàn)方法 ActivationGroup.createGroup。  


          ---------------------------------------------------------------------- 
          ---------- 

          ActivationDesc 第二個(gè)構(gòu)造函數(shù)構(gòu)造對(duì)象描述符的方式與第一個(gè)構(gòu)造函數(shù)相同, 
          但必須提供附加的參數(shù) restart。如果對(duì)象要求重啟服務(wù),這意味著當(dāng)激活器重 
          新啟動(dòng)時(shí),對(duì)象也會(huì)自動(dòng)重新啟動(dòng)(與根據(jù)需要激活的惰性激活相反)。此時(shí), 
          restart 應(yīng)為 true。如果 restart 為 false,則對(duì)象將只是在需要時(shí)激活(通 
          過(guò)遠(yuǎn)程方法調(diào)用)。 

          ActivationDesc 的第三個(gè)構(gòu)造函數(shù)構(gòu)造一個(gè)對(duì)象的對(duì)象描述符。這個(gè)對(duì)象的組標(biāo) 
          識(shí)符為 groupID,它的類(lèi)名為 className(可從 codebase 路徑加載),它的初 
          始化信息為 data。所有具有相同 groupID 的對(duì)象都將在同一 Java 虛擬機(jī)中被 
          激活。 

          ActivationDesc 第四個(gè)構(gòu)造函數(shù)構(gòu)造對(duì)象描述符的方式與第三個(gè)構(gòu)造函數(shù)相同, 
          但它允許指定重啟模式。如果對(duì)象需要重新啟動(dòng)(定義如上),則 restart 應(yīng)為 
           true。 

          getGroupID 方法返回該描述符所指定對(duì)象的組標(biāo)識(shí)符。組可以提供一種將對(duì)象聚 
          合到單一 Java 虛擬機(jī)中的方法。 

          getClassName 方法返回該激活描述符所指定對(duì)象的類(lèi)名。 

          getLocation 方法返回用于下載該對(duì)象的類(lèi)的 codebase 路徑。 

          getData 方法返回一個(gè)“已編組對(duì)象”,該編組對(duì)象包含用于初始化(激活)描 
          述符指定的對(duì)象的數(shù)據(jù)。 

          getRestartMode 方法在該對(duì)象的重啟模式啟用時(shí)返回 true,否則返回 false。 

          7.3.2 ActivationID 類(lèi)  
          激活協(xié)議利用激活標(biāo)識(shí)符來(lái)表示不受時(shí)間影響的可激活遠(yuǎn)程對(duì)象。激活標(biāo)識(shí)符( 
          類(lèi) ActivationID 的實(shí)例)含有激活對(duì)象所需的若干信息: 

          對(duì)象激活器的遠(yuǎn)程引用  
          對(duì)象的唯一標(biāo)識(shí)符。  
          對(duì)象的激活標(biāo)識(shí)符可通過(guò)向激活系統(tǒng)注冊(cè)對(duì)象來(lái)得到??捎孟率鰩追N方法之一來(lái) 
          完成注冊(cè)(如上所述): 

          通過(guò) Activatable.register 方法  
          通過(guò)第一個(gè)或第二個(gè) Activatable 構(gòu)造函數(shù)(都有三個(gè)參數(shù)而且注冊(cè)并導(dǎo)出對(duì)象 
          )  
          通過(guò)第一個(gè)或第二個(gè) Activatable.exportObject 方法(它們以激活描述符、對(duì) 
          象實(shí)現(xiàn)及端口為參數(shù),且都注冊(cè)并導(dǎo)出對(duì)象)。  

          package java.rmi.activation; 

          public class ActivationID implements java.io.Serializable 

              public ActivationID(Activator activator); 
              public Remote activate(boolean force) 
                  throws ActivationException, UnknownObjectException, java.rmi.RemoteException; 
              public boolean equals(Object obj); 
              public int hashCode(); 


          ActivationID 的構(gòu)造函數(shù)接受參數(shù) activator,該參數(shù)指定對(duì)激活器(負(fù)責(zé)激活 
          與該激活標(biāo)識(shí)符關(guān)聯(lián)的對(duì)象)的遠(yuǎn)程引用。ActivationID 的實(shí)例是全局唯一的。 
          activate 方法將激活與該激活標(biāo)識(shí)符關(guān)聯(lián)的對(duì)象。如果 force 參數(shù)為 true,激 
          活器將把遠(yuǎn)程對(duì)象的任何高速緩存引用視為已過(guò)時(shí),從而迫使激活器在激活對(duì)象 
          時(shí)與組聯(lián)系。如果 force 為 false,則返回可接受的高速緩存值。如果激活失敗 
          ,則拋出 ActivationException。如果激活器不能識(shí)別該對(duì)象標(biāo)識(shí)符,則該方法 
          將拋出 UnknownObjectException。如果對(duì)激活器的遠(yuǎn)程調(diào)用失敗,則拋出
          RemoteException。 
          equals 方法可實(shí)現(xiàn)基于內(nèi)容的相等比較。如果所有的域都相等(完全相同或從各 
          域的 Object.equals 語(yǔ)義上等價(jià)),它將返回 true。如果 p1 和 p2 是類(lèi) Act 
          ivationID 的實(shí)例,則在 p1.equals(p2) 返回 true 時(shí) hashCode 方法返回相同 
          的值。 

          7.3.3 Activatable 類(lèi)  
          Activatable 類(lèi)提供對(duì)需要持久訪問(wèn)而不受時(shí)間影響,同時(shí)又被系統(tǒng)激活的遠(yuǎn)程 
          對(duì)象的支持。類(lèi) Activatable 是開(kāi)發(fā)人員用來(lái)實(shí)現(xiàn)和管理可激活對(duì)象的主要應(yīng)用 
          程序接口。注意,必須先運(yùn)行激活系統(tǒng)守護(hù)進(jìn)程 rmid,然后才能注冊(cè)和/或激活 
          對(duì)象。 


          package java.rmi.activation; 
          public abstract class Activatable 
          extends java.rmi.server.RemoteServer 

              protected Activatable(String codebase, 
                                    java.rmi.MarshalledObject data, 
                                    boolean restart, 
                                    int port) 
              throws ActivationException, java.rmi.RemoteException; 

              protected Activatable(String codebase, 
                                    java.rmi.MarshalledObject data, 
                                    boolean restart, 
                                    int port, 
                                    RMIClientSocketFactory csf, 
                                    RMIServerSocketFactory ssf) 
                  throws ActivationException, java.rmi.RemoteException; 

              protected Activatable(ActivationID id, int port) 
                  throws java.rmi.RemoteException; 

              protected Activatable(ActivationID id, int port, 
                                    RMIClientSocketFactory csf, 
                                    RMIServerSocketFactory ssf) 
                  throws java.rmi.RemoteException; 

              protected ActivationID getID(); 

              public static Remote register(ActivationDesc desc) 
                  throws UnknownGroupException, ActivationException,
                      java.rmi.RemoteException; 

              public static boolean inactive(ActivationID id) 
                  throws UnknownObjectException, ActivationException,
                      java.rmi.RemoteException; 

              public static void unregister(ActivationID id) 
                  throws UnknownObjectException, ActivationException, 
                      java.rmi.RemoteException; 

              public static ActivationID exportObject(Remote obj, 
                                                      String codebase, 
                                                      MarshalledObject data, 
                                                      boolean restart, 
                                                      int port) 
                  throws ActivationException, java.rmi.RemoteException; 

              public static ActivationID exportObject(Remote obj, 
                                                      String codebase, 
                                                      MarshalledObject data, 
                                                      boolean restart, 
                                                      int port, 
                                                      RMIClientSocketFactory csf,
                                                      RMIServerSocketFactory ssf) 
                  throws ActivationException, java.rmi.RemoteException; 

              public static Remote exportObject(Remote obj, 
                                                ActivationID id, 
                                                int port) 
                  throws java.rmi.RemoteException; 

              public static Remote exportObject(Remote obj, 
                                                ActivationID id, 
                                                int port, 
                                                RMIClientSocketFactory csf, 
                                                RMIServerSocketFactory ssf) 
                  throws java.rmi.RemoteException; 

              public static boolean unexportObject(Remote obj, boolean force) 
                  throws java.rmi.NoSuchObjectException; 
          }

          可激活遠(yuǎn)程對(duì)象的實(shí)現(xiàn)可能擴(kuò)展或不擴(kuò)展類(lèi) Activatable。確實(shí)擴(kuò)展 Activatab 
          le 類(lèi)的遠(yuǎn)程對(duì)象實(shí)現(xiàn)將從超類(lèi) java.rmi.server.RemoteObject 中繼承 hashCo 
          de 和 equals 方法中的相應(yīng)定義。因此,引用同一 Activatable 遠(yuǎn)程對(duì)象的兩 
          個(gè)遠(yuǎn)程引用是相等的(equals 方法將返回 true)。同樣,類(lèi) Activatable 的實(shí) 
          例將“等于”該實(shí)例的相應(yīng) stub 對(duì)象(即如果 Object.equals 方法用與該實(shí)現(xiàn) 
          匹配的 stub 對(duì)象作為參數(shù)進(jìn)行調(diào)用,它將返回 true。反之亦然)。 

          Activatable 類(lèi)方法  
          Activatable 類(lèi)的第一個(gè)構(gòu)造函數(shù)用于在指定 port 上注冊(cè)和導(dǎo)出對(duì)象(如果 p 
          ort 為零,則選用某個(gè)匿名端口)。下載的類(lèi)代碼對(duì)象的 URL 路徑是 codbase, 
          其初始化數(shù)據(jù)是 data。如果 restart 為 true,則對(duì)象將在激活器重新啟動(dòng)或組 
          失效時(shí)自動(dòng)重新啟動(dòng)。如果 restart 為 false,則對(duì)象將根據(jù)需要而激活(通過(guò) 
          對(duì)對(duì)象的遠(yuǎn)程方法調(diào)用)。 

          Activatable 類(lèi)的具體子類(lèi)必須調(diào)用該構(gòu)造函數(shù)才能在初始構(gòu)造期間注冊(cè)和導(dǎo)出 
          該對(duì)象。作為構(gòu)造可激活對(duì)象時(shí)的副效應(yīng),遠(yuǎn)程對(duì)象將被“注冊(cè)”到激活系統(tǒng)上 
          并“導(dǎo)出”(如果 port 為零,則在匿名端口導(dǎo)出)到 RMI 運(yùn)行時(shí),從而使之可 
          接受來(lái)自客戶(hù)機(jī)的到來(lái)調(diào)用。 

          如果向激活系統(tǒng)注冊(cè)對(duì)象失敗,則該構(gòu)造函數(shù)將拋出 ActivationException。如 
          果將對(duì)象導(dǎo)出到 RMI 運(yùn)行時(shí)失敗,則將拋出 RemoteException。 

          第二個(gè)構(gòu)造函數(shù)與第一個(gè) Activatable 構(gòu)造函數(shù)相同,但它允許將客戶(hù)機(jī)和服務(wù) 
          器套接字工廠規(guī)范用于與該可激活對(duì)象進(jìn)行通訊。詳細(xì)信息,參見(jiàn)“RMI 套接字 
          工廠”。 

          第三個(gè)構(gòu)造函數(shù)用于激活對(duì)象并從指定的 port 將其(用 ActivationID,id)導(dǎo) 
          出。當(dāng)對(duì)象本身被其專(zhuān)用的“激活”構(gòu)造函數(shù)激活時(shí),Activatable 類(lèi)的具體子 
          類(lèi)必須調(diào)用該構(gòu)造函數(shù)。該“激活”構(gòu)造函數(shù)的參數(shù)必須是: 

          對(duì)象的激活標(biāo)識(shí)符 (ActivationID) 及  
          對(duì)象的初始化/自舉數(shù)據(jù) (MarshalledObject)。  
          作為構(gòu)造的副效應(yīng),遠(yuǎn)程對(duì)象將被“導(dǎo)出”到 RMI 運(yùn)行時(shí)中(從指定 port)并 
          可接受來(lái)自客戶(hù)機(jī)的調(diào)用。如果將對(duì)象導(dǎo)出到 RMI 運(yùn)行時(shí)失敗,則該構(gòu)造函數(shù)將 
          拋出 RemoteException。 

          第四個(gè)構(gòu)造函數(shù)與第三個(gè)構(gòu)造函數(shù)相同,但它允許將客戶(hù)機(jī)和服務(wù)器套接字工廠 
          規(guī)范用于與該可激活對(duì)象進(jìn)行通訊。 

          getID 方法返回對(duì)象的激活標(biāo)識(shí)符。該方法是受保護(hù)的,因而只有子類(lèi)才能獲取 
          對(duì)象的標(biāo)識(shí)符。 對(duì)象的標(biāo)識(shí)符用于報(bào)告對(duì)象的非活動(dòng)狀態(tài)或注銷(xiāo)對(duì)象的激活描述 
          符。 

          register 方法為可激活的遠(yuǎn)程對(duì)象向激活系統(tǒng)注冊(cè)對(duì)象描述符 desc,從而使該 
          對(duì)象能在需要時(shí)被激活。該方法可用于注冊(cè)可激活對(duì)象而無(wú)需先創(chuàng)建該對(duì)象。它 
          返回可激活對(duì)象的 Remote stub,因此可加以保存并在今后調(diào)用,從而強(qiáng)制首次 
          創(chuàng)建/激活該對(duì)象。如果沒(méi)有向激活系統(tǒng)注冊(cè) desc 中的組標(biāo)識(shí)符,該方法將拋出 
           UnknownGroupException。如果激活系統(tǒng)未運(yùn)行,則拋出 ActivationException 
          。最后,如果對(duì)激活系統(tǒng)的遠(yuǎn)程調(diào)用失敗,則拋出 RemoteException。 

          inactive 方法用于通知系統(tǒng)具有相應(yīng)激活 id 的對(duì)象當(dāng)前是非活動(dòng)的。如果已知 
          該對(duì)象當(dāng)前是活動(dòng)的,則該對(duì)象將不從 RMI 運(yùn)行時(shí)環(huán)境中導(dǎo)出(僅在沒(méi)有待定的 
          或執(zhí)行的調(diào)用時(shí)),從而可不再接收到來(lái)的調(diào)用。該調(diào)用還將通知該虛擬機(jī)的 A 
          ctivationGroup 該對(duì)象處于非活動(dòng)狀態(tài);而該組又將通知其 ActivationMonito 
          r。如果該調(diào)用成功,則此后對(duì)激活器的激活請(qǐng)求將導(dǎo)致重新激活該對(duì)象。如果成 
          功地阻止該對(duì)象被導(dǎo)出(意味著此時(shí)它沒(méi)有待定或執(zhí)行調(diào)用),則 inactive 方 
          法返回 true;如果由于待定或進(jìn)程內(nèi)調(diào)用而不能阻止該對(duì)象被導(dǎo)出,則返回 fa 
          lse。如果對(duì)象是未知的(它可能是非活動(dòng)的),則該方法將拋出 UnknownObjec 
          tException;如果組是非活動(dòng)的,則拋出 ActivationException;如果通知顯示 
          器的調(diào)用失敗,則拋出 RemoteException。如果該對(duì)象被認(rèn)為是活動(dòng)的但已自己 
          阻止導(dǎo)出,則該操作仍將成功進(jìn)行。 

          unregister 方法用于撤消與 id 關(guān)聯(lián)的激活描述符的先前注冊(cè)。對(duì)象不能再用這 
          個(gè) id 來(lái)激活。如果該對(duì)象 id 對(duì)激活系統(tǒng)來(lái)說(shuō)是未知的,則拋出 UnknownObje 
          ctException。如果激活系統(tǒng)未處于運(yùn)行狀態(tài),則拋出 ActivationException。如 
          果對(duì)激活系統(tǒng)的遠(yuǎn)程調(diào)用失敗,則拋出 RemoteException。 

          第一個(gè) exportObject 方法可被“可激活”但不擴(kuò)展 Activatable 類(lèi)的對(duì)象顯式 
          調(diào)用,其目的是:a) 向激活系統(tǒng)注冊(cè)對(duì)象的激活描述符 desc,由所提供的 cod 
          ebase 和 data 構(gòu)造(因此可激活該對(duì)象);b) 從指定 port 導(dǎo)出遠(yuǎn)程對(duì)象 ob 
          j(如果該 port 為零,則將選擇匿名端口)。對(duì)象一旦被導(dǎo)出,即可接收到來(lái)的 
          調(diào)用。  

          該 exportObject 方法返回向激活系統(tǒng)注冊(cè)描述符 desc 時(shí)所獲得的激活標(biāo)識(shí)符 
          。如果在虛擬機(jī)中激活組不是活動(dòng)的,則拋出 ActivationException。如果對(duì)象 
          注冊(cè)或?qū)С鍪?,則拋出 RemoteException。 

          如果 obj 擴(kuò)展 Activatable,則不必調(diào)用該方法,因?yàn)榈谝粋€(gè) Activatable 構(gòu) 
          造函數(shù)將調(diào)用該方法。 

          第二個(gè) exportObject 方法與第一個(gè)相同,但它允許將客戶(hù)機(jī)和服務(wù)器套接字工 
          廠規(guī)范用于與該可激活對(duì)象進(jìn)行通訊。 

          第三個(gè) exportObject 方法將帶標(biāo)識(shí)符 id 的“可激活”遠(yuǎn)程對(duì)象(不一定是 A 
          ctivatable 類(lèi)型的)導(dǎo)出到 RMI 運(yùn)行時(shí),以使對(duì)象 obj 能夠接收到來(lái)的調(diào)用。 
          如果 port 為零,則將在某個(gè)匿名端口導(dǎo)出該對(duì)象。 

          激活時(shí),不擴(kuò)展 Activatable 類(lèi)的“可激活”對(duì)象應(yīng)顯式地調(diào)用此 exportObje 
          ct 方法。確實(shí)擴(kuò)展 Activatable 類(lèi)的對(duì)象不必直接調(diào)用該方法;它將被上面的 
          第三個(gè)構(gòu)造函數(shù)所調(diào)用(應(yīng)從其專(zhuān)用的激活構(gòu)造函數(shù)中調(diào)用子類(lèi))。 

          該 exportObject 方法將返回可激活對(duì)象的 Remote stub。如果該對(duì)象的導(dǎo)出失 
          敗,則該方法將拋出 RemoteException。 

          第四個(gè) exportObject 方法與第三個(gè)相同,但它允許將客戶(hù)機(jī)和服務(wù)器套接字工 
          廠規(guī)范用于與該可激活對(duì)象進(jìn)行通訊。 

          unexportObject 方法使遠(yuǎn)程對(duì)象 obj 不能接收到來(lái)的調(diào)用。如果參數(shù) force 為 
           true,則即使有對(duì)遠(yuǎn)程對(duì)象的待定調(diào)用或遠(yuǎn)程對(duì)象在進(jìn)程內(nèi)仍有調(diào)用,對(duì)象也將 
          被強(qiáng)制阻止導(dǎo)出。如果參數(shù) force 為 false,則只在沒(méi)有對(duì)對(duì)象的待定調(diào)用或進(jìn) 
          程內(nèi)沒(méi)有調(diào)用時(shí)它才被阻止導(dǎo)出。如果成功地阻止了該對(duì)象的導(dǎo)出,則 RMI 運(yùn)行 
          時(shí)將從其內(nèi)部表中刪掉它。使用這種強(qiáng)制方式從 RMI 刪除對(duì)象可能會(huì)使客戶(hù)機(jī)持 
          有遠(yuǎn)程對(duì)象的過(guò)時(shí)遠(yuǎn)程引用。如果此前沒(méi)有將對(duì)象導(dǎo)出到 RMI 運(yùn)行時(shí),則該方法 
          將拋出 java.rmi.NoSuchObjectException。 

          構(gòu)造可激活的遠(yuǎn)程對(duì)象  
          為了使對(duì)象可激活,“可激活”對(duì)象實(shí)現(xiàn)類(lèi)不管是否擴(kuò)展 Activatable 類(lèi),都必 
          須定義一個(gè)特殊的公共構(gòu)造函數(shù)。該公共構(gòu)造函數(shù)帶有兩個(gè)參數(shù):激活標(biāo)識(shí)符( 
          類(lèi)型為 ActivationID)及激活數(shù)據(jù) java.rmi.MarshalledObject(在注冊(cè)時(shí)所用 
          的激活描述符中提供)。當(dāng)激活組在其虛擬機(jī)內(nèi)激活某個(gè)遠(yuǎn)程對(duì)象時(shí),它將利用 
          此特殊構(gòu)造函數(shù)來(lái)構(gòu)造對(duì)象(后面將作詳細(xì)說(shuō)明)。遠(yuǎn)程對(duì)象實(shí)現(xiàn)可適當(dāng)用激活 
          數(shù)據(jù)來(lái)初始化自己。遠(yuǎn)程對(duì)象也可能想保留其激活標(biāo)識(shí)符,這樣就可以在它變?yōu)?nbsp;
          非活動(dòng)狀態(tài)(通過(guò)對(duì) Activatable. inactive 方法的調(diào)用)時(shí)通知激活組。 

          Activatable 構(gòu)造函數(shù)的第一種和第二種形式用于從指定的 port 注冊(cè)并導(dǎo)出可 
          激活對(duì)象。最初構(gòu)造對(duì)象時(shí)應(yīng)使用該構(gòu)造函數(shù);該構(gòu)造函數(shù)的第三種形式將在重 
          新激活對(duì)象時(shí)使用。 

          Activatable 的具體子類(lèi)必須在最初構(gòu)造期間調(diào)用第一種或第二種構(gòu)造函數(shù)以注 
          冊(cè)并導(dǎo)出對(duì)象。 構(gòu)造函數(shù)首先用對(duì)象的類(lèi)名創(chuàng)建一個(gè)激活描述符 (ActivationD 
          esc)、對(duì)象所提供的 codebase 和 data(其激活組為虛擬機(jī)的缺省激活組)。然 
          后,構(gòu)造函數(shù)將向缺省的 ActivationSystem 注冊(cè)該描述符。最后,構(gòu)造函數(shù)在 
          特定 port 上(如果 port 為零,則選擇匿名端口)將可激活對(duì)象導(dǎo)出到 RMI 運(yùn) 
          行時(shí)中,并將該對(duì)象作為 activeObject 報(bào)告給本地 ActivationGroup。如果在 
          注冊(cè)或?qū)С龅倪^(guò)程中出錯(cuò),則構(gòu)造函數(shù)拋出 RemoteException。注意,構(gòu)造函數(shù) 
          也初始化它的 ActivationID(通過(guò)注冊(cè)獲得),因此接下來(lái)對(duì) protected 方法 
           getID 的調(diào)用將返回對(duì)象的激活標(biāo)識(shí)符。 

          Activatable 構(gòu)造函數(shù)的第三種形式用于從指定的端口導(dǎo)出對(duì)象。當(dāng) Activatab 
          le 的具體子類(lèi)被對(duì)象自己的“激活”構(gòu)造函數(shù)激活時(shí),必須調(diào)用第三種構(gòu)造函數(shù) 
          。該“激活”構(gòu)造函數(shù)帶兩個(gè)參數(shù): 

          對(duì)象的 ActivationID  
          對(duì)象的初始化數(shù)據(jù),一個(gè) MarshalledObject 對(duì)象  
          該構(gòu)造函數(shù)只將可激活對(duì)象從特定 port(如果 port 為零,則選擇匿名端口)導(dǎo) 
          出到 RMI 運(yùn)行時(shí)中,而并不通知 ActivationGroup 該對(duì)象已是活動(dòng)對(duì)象。因?yàn)?nbsp;
          正是 ActivationGroup 激活該對(duì)象的,因而它自然知道對(duì)象已處活動(dòng)狀態(tài)。 

          下面是遠(yuǎn)程對(duì)象接口 Server 和擴(kuò)展 Activatable 類(lèi)的實(shí)現(xiàn) ServerImpl 的示例: 

          package examples; 

          public interface Server extends java.rmi.Remote

              public void doImportantStuff() 
                  throws java.rmi.RemoteException; 




          public class ServerImpl extends Activatable implements Server 

              // 初始構(gòu)造、注冊(cè)及導(dǎo)出時(shí)的構(gòu)造函數(shù) 
              public ServerImpl(String codebase, MarshalledObject data) 
                  throws ActivationException, java.rmi.RemoteException 
              { 
                  // 向激活系統(tǒng)注冊(cè)對(duì)象,然后 
                  // 在匿名端口上導(dǎo)出 
                  super(codebase, data, false, 0); 
              } 

              // 激活及導(dǎo)出的構(gòu)造函數(shù)。該構(gòu)造函數(shù)由 
              // ActivationInstantiator.newInstance 
              // 方法在激活過(guò)程中所調(diào)用,以構(gòu)造對(duì)象 
              public ServerImpl(ActivationID id, MarshalledObject data) 
                  throws java.rmi.RemoteException 
              { 
                  // 調(diào)用父類(lèi)的構(gòu)造函數(shù)以 
                  // 將對(duì)象導(dǎo)出到 RMI 運(yùn)行時(shí)。 
                  super(id, 0); 
                  // 初始化對(duì)象(例如利用數(shù)據(jù)) 
              } 

              public void doImportantStuff() { ... } 



          對(duì)象將負(fù)責(zé)導(dǎo)出自己。Activatable 的構(gòu)造函數(shù)負(fù)責(zé)將對(duì)象導(dǎo)出到具有活動(dòng)引用 
          類(lèi)型 UnicastRemoteObject 的 RMI 運(yùn)行時(shí)中,因此,擴(kuò)展 Activatable 的對(duì)象 
          實(shí)現(xiàn)不必關(guān)心顯式導(dǎo)出對(duì)象(不是調(diào)用相應(yīng)的超類(lèi)構(gòu)造函數(shù))的具體細(xì)節(jié)。如果 
          對(duì)象實(shí)現(xiàn)不擴(kuò)展類(lèi) Activatable,則該對(duì)象必須通過(guò)調(diào)用某個(gè) Activatable.exp 
          ortObject 靜態(tài)方法來(lái)顯式導(dǎo)出該對(duì)象。 

          下例中,ServerImpl 不擴(kuò)展 Activatable,而是擴(kuò)展另一個(gè)類(lèi)。因此,ServerI 
          mpl 負(fù)責(zé)在初始構(gòu)造和激活過(guò)程中導(dǎo)出自己。下述的類(lèi)定義給出了 ServerImpl  
          的初始化構(gòu)造函數(shù)及其特殊“激活”構(gòu)造函數(shù),以及每個(gè)構(gòu)造函數(shù)內(nèi)用于導(dǎo)出對(duì) 
          象的相應(yīng)調(diào)用: 

          package examples; 

          public class ServerImpl extends SomeClass implements Server 

              // 初始創(chuàng)建時(shí)的構(gòu)造函數(shù) 
              public ServerImpl(String codebase, MarshalledObject data) 
                  throws ActivationException, java.rmi.RemoteException 
              { 
                  // 注冊(cè)并導(dǎo)出對(duì)象 
                  Activatable.exportObject(this, codebase, data, false, 0); 
              } 
              
              // 激活的構(gòu)造函數(shù) 
              public ServerImpl(ActivationID id, MarshalledObject data) 
                  throws java.rmi.RemoteException 
              { 
                  // 導(dǎo)出對(duì)象 
                  Activatable.exportObject(this, id, 0); 
              } 
              
              public void doImportantStuff() { ... } 


          在不創(chuàng)建對(duì)象的情況下注冊(cè)激活描述符  
          要在不創(chuàng)建對(duì)象的情況下向激活系統(tǒng)注冊(cè)可激活遠(yuǎn)程對(duì)象,程序員只需為對(duì)象注 
          冊(cè)激活描述符(類(lèi) ActivationDesc 的實(shí)例)。激活描述符含有一切所需的信息 
          ,因此必要時(shí)激活系統(tǒng)就可以激活該對(duì)象。可用以下方法來(lái)注冊(cè)類(lèi) examples.Se 
          rverImpl 實(shí)例的激活描述符(忽略異常處理): 

          Server server;ActivationDesc desc;String codebase = "http://zaphod/cod 
          ebase/"; 

          MarshalledObject data = new MarshalledObject("some data");desc = new A 
          ctivationDesc( "examples.ServerImpl", codebase, data);server = (Server 
          )Activatable.register(desc); 

          register 調(diào)用將返回一個(gè) Remote stub(它是 examples.ServerImpl 對(duì)象的 s 
          tub),并實(shí)現(xiàn)一組與 examples.ServerImpl 所實(shí)現(xiàn)的遠(yuǎn)程接口相同的遠(yuǎn)程接口 
          (即 stub 實(shí)現(xiàn)遠(yuǎn)程接口 Server)。該 stub 對(duì)象(上述被強(qiáng)制類(lèi)型轉(zhuǎn)換并指派 
          給 server 的對(duì)象)可作為參數(shù)傳給期望實(shí)現(xiàn) examples.Server 遠(yuǎn)程接口的對(duì)象 
          的任何方法調(diào)用。  


          7.4 激活接口 
          在 RMI 激活協(xié)議中,為使系統(tǒng)運(yùn)轉(zhuǎn)正常,激活器必須保證以下兩點(diǎn): 

          象所有的系統(tǒng)守護(hù)進(jìn)程一樣,計(jì)算機(jī)處于打開(kāi)狀態(tài)時(shí)激活器必須保持運(yùn)行狀態(tài)  
          激活器不能重新激活已處在活動(dòng)狀態(tài)的遠(yuǎn)程對(duì)象。  
          激活器將為它所要激活的組和對(duì)象維護(hù)一個(gè)相應(yīng)的信息數(shù)據(jù)庫(kù)。 

          7.4.1 激活器接口  
          激活器是參與激活進(jìn)程的實(shí)體之一。如前所述,stub 內(nèi)的不完善引用將通過(guò)調(diào)用 
          激活器的 activate 方法來(lái)獲得對(duì)可激活遠(yuǎn)程對(duì)象的“活”引用。激活器接到激 
          活請(qǐng)求后,就開(kāi)始查找該激活標(biāo)識(shí)符 id 的激活描述符,以決定要在哪個(gè)組中激 
          活對(duì)象,然后調(diào)用激活組的實(shí)例化器的newInstance 方法(ActivationGroup 的 
          遠(yuǎn)程接口將在后面說(shuō)明)。激活器將根據(jù)需要啟動(dòng)激活組的執(zhí)行過(guò)程。例如,如 
          果給定的組描述符的激活組還未運(yùn)行,則激活器將為該激活組生成一個(gè)子虛擬機(jī) 
          ,以便在該新虛擬機(jī)中建立該組。 

          激活器將負(fù)責(zé)監(jiān)控和檢測(cè)激活組何時(shí)失敗,以便將過(guò)時(shí)的遠(yuǎn)程引用從其內(nèi)部表中 
          刪去。 

          package java.rmi.activation; 

          public interface Activator extends java.rmi.Remote 

              java.rmi.MarshalledObject activate(ActivationID id, boolean force) 
                  throws UnknownObjectException, ActivationException, 
                      java.rmi.RemoteException; 



          activate 方法激活與激活標(biāo)識(shí)符 id 所關(guān)聯(lián)的對(duì)象。如果激活器知道對(duì)象已經(jīng)為 
          活動(dòng)對(duì)象,且 force 參數(shù)為 false,就會(huì)立即將含有“活”引用的 stub 返給調(diào) 
          用程序;如果激活器不知道相應(yīng)的遠(yuǎn)程對(duì)象是活動(dòng)的或 force 參數(shù)為 true,則 
          激活器將利用激活描述符信息(先前已為獲得 id 而注冊(cè)過(guò))來(lái)決定對(duì)象應(yīng)該在 
          哪個(gè)組(虛擬機(jī))中被激活。如果對(duì)象組的相應(yīng)激活 Instantiator 已經(jīng)存在, 
          則激活器將通過(guò)傳遞 id 和對(duì)象的激活描述符來(lái)調(diào)用該激活實(shí)例化器的newInsta 
          nce 方法。 

          如果對(duì)象組描述符的激活實(shí)例化器(組)還不存在,則激活器將啟動(dòng)新的 Activ 
          ationInstantiator 化身執(zhí)行進(jìn)程(例如通過(guò)生成子進(jìn)程)。當(dāng)激活器為某一組 
          重建 ActivationInstantiator 時(shí),它必須將該組的化身數(shù)增一。注意,化身數(shù) 
          從 0 開(kāi)始。激活系統(tǒng)用化身數(shù)來(lái)檢測(cè)后來(lái)的 ActivationSystem.activeGroup 和 
           ActivationMonitor.inactiveGroup 調(diào)用。激活系統(tǒng)將棄去那些化身數(shù)小于組的 
          當(dāng)前數(shù)的調(diào)用。 
          ---------------------------------------------------------------------- 
          ---------- 

          注意 - 激活器在啟動(dòng)新的激活組時(shí)必須與激活組的標(biāo)識(shí)符、描述符及化身數(shù)進(jìn)行 
          通訊。激活器將在一個(gè)獨(dú)立的虛擬機(jī)中(例如作為一個(gè)獨(dú)立的進(jìn)程或子進(jìn)程)生 
          成激活組。因此,它必須將信息傳遞過(guò)去,以指定用 ActivationGroup.createG 
          roup 方法來(lái)創(chuàng)建該組時(shí)所需的信息。激活器并未指定如何將此信息傳給所生成的 
          進(jìn)程??捎靡丫幗M對(duì)象的形式將此信息送到子進(jìn)程的標(biāo)準(zhǔn)輸入中。  


          ---------------------------------------------------------------------- 
          ---------- 
          當(dāng)激活器接收到激活組的回調(diào)(通過(guò) ActivationSystem.activeGroup 方法,該 
          回調(diào)可指明激活組的引用和化身數(shù))時(shí),激活器就可以調(diào)用該激活實(shí)例化器的 n 
          ewInstance 方法,從而將每個(gè)待定的激活請(qǐng)求轉(zhuǎn)發(fā)給該激活實(shí)例化器,同時(shí)將結(jié) 
          果(一個(gè)已編組遠(yuǎn)程對(duì)象引用、一個(gè) stub)返給每個(gè)調(diào)用程序。 

          注意,激活器接收的是 MarshalledObject 對(duì)象而不是 Remote 對(duì)象。因此,激 
          活器不需要加載該對(duì)象的代碼,也不需要參與該對(duì)象的分布式垃圾收集。如果激 
          活器保留了對(duì)遠(yuǎn)程對(duì)象的強(qiáng)引用,則該激活器將防止該對(duì)象在正常的分布式垃圾 
          收集機(jī)制下被當(dāng)作垃圾而收集。 

          如果激活失敗,activate 方法將拋出 ActivationException。激活可能會(huì)因以下 
          各種原因而失?。赫也坏筋?lèi)、無(wú)法與激活組取得聯(lián)系等。如果先前沒(méi)有為激活標(biāo) 
          識(shí)符 id 向該激活器注冊(cè)激活描述符,則 activate 方法將拋出 UnknownObject 
          Exception。如果對(duì)該激活器的遠(yuǎn)程調(diào)用失敗,則拋出 RemoteException。 

          7.4.2 ActivationSystem 接口  
          ActivationSystem 提供了一種為組和可激活對(duì)象(這些對(duì)象將在這些組中被激活 
          )注冊(cè)的方法。 ActivationSystem 與 Activator 和 ActivationMonitor 都能 
          密切合作。前者負(fù)責(zé)激活通過(guò) ActivationSystem 所注冊(cè)的對(duì)象;后者負(fù)責(zé)獲取 
          活動(dòng)對(duì)象、非活動(dòng)對(duì)象及非活動(dòng)組的有關(guān)信息。 

          package java.rmi.activation; 

          public interface ActivationSystem extends java.rmi.Remote 

              public static final int SYSTEM_PORT = 1098; 
              
              ActivationGroupID registerGroup(ActivationGroupDesc desc) 
                  throws ActivationException, java.rmi.RemoteException; 
              
              ActivationMonitor activeGroup(ActivationGroupID id, 
                                            ActivationInstantiator group, 
                                            long incarnation) 
                  throws UnknownGroupException, ActivationException, 
                      java.rmi.RemoteException; 
              
              void unregisterGroup(ActivationGroupID id) 
                  throws ActivationException, UnknownGroupException, 
                      java.rmi.RemoteException; 
              
              ActivationID registerObject(ActivationDesc desc) 
                  throws ActivationException, UnknownGroupException, 
                      java.rmi.RemoteException; 
              
              void unregisterObject(ActivationID id) 
                  throws ActivationException, UnknownObjectException, 
                      java.rmi.RemoteException; 
              
              void shutdown() throws java.rmi.RemoteException; 




          ---------------------------------------------------------------------- 
          ---------- 

          注意 - 作為一種安全措施,以上所有方法(registerGroup、activeGroup、unr 
          egisterGroup、registerObject、unregisterObject 和 shutdown)如果被客戶(hù) 
          機(jī)所調(diào)用,且該客戶(hù)機(jī)所處主機(jī)與激活系統(tǒng)不同,則將拋出 java.rmi.AccessEx 
          ception。該異常是 java.rmi.RemoteException 的子類(lèi)。 


          ---------------------------------------------------------------------- 
          ---------- 

          registerObject 方法用來(lái)注冊(cè)激活描述符 desc,同時(shí)也為可激活遠(yuǎn)程對(duì)象獲取 
          激活標(biāo)識(shí)符。 ActivationSystem 為描述符 desc 所指定的對(duì)象創(chuàng)建 Activatio 
          nID(激活標(biāo)識(shí)符),并將激活描述符及其關(guān)聯(lián)的標(biāo)識(shí)符記錄在穩(wěn)定的存儲(chǔ)庫(kù)中以 
          備將來(lái)使用。當(dāng) Activator 接到某個(gè)特定標(biāo)識(shí)符的 activate 請(qǐng)求時(shí),它就查找 
          該指定標(biāo)識(shí)符的激活描述符(先前已注冊(cè)),并用此信息來(lái)激活該對(duì)象。如果 d 
          esc 中所引用的組并沒(méi)有向該系統(tǒng)注冊(cè),則該方法將拋出 UnknownGroupExcepti 
          on。如果注冊(cè)失?。ɡ?,數(shù)據(jù)庫(kù)更新失敗等),則拋出 ActivationException 
          。如果遠(yuǎn)程調(diào)用失敗, 則拋出 RemoteException。 

          unregisterObject 方法用于刪除激活標(biāo)識(shí)符 id 及以前向 ActivationSystem 注 
          冊(cè)過(guò)的相關(guān)描述符。該調(diào)用完成后,就不能再用對(duì)象的激活 id 來(lái)激活該對(duì)象。 
          如果對(duì)象的 id 是未知的(沒(méi)有被注冊(cè)),則該方法將拋出 UnknownObjectExce 
          ption。如果注銷(xiāo)失?。ɡ?,數(shù)據(jù)庫(kù)的更新失敗等),則該方法將拋出 Activa 
          tionException。如果遠(yuǎn)程調(diào)用失敗,則拋出 RemoteException。 

          registerGroup 方法用于向激活系統(tǒng)注冊(cè)組描述符 desc 所指定的激活組,并返 
          回指派給該組的 ActivationGroupID。必須先向 ActivationSystem 注冊(cè)激活組 
          ,然后才能在該組中注冊(cè)對(duì)象。 如果組的注冊(cè)失敗,則該方法將拋出 Activati 
          onException。如果遠(yuǎn)程調(diào)用失敗,則拋出 RemoteException。 

          activeGroup 方法是來(lái)自 ActivationGroup(具有標(biāo)識(shí)符 id)的回調(diào),用以通知 
          激活系統(tǒng)下列信息:組現(xiàn)在是活動(dòng)的,而且也是該虛擬機(jī)的 ActivationInstant 
          iator。此回調(diào)是在 ActivationGroup.createGroup 方法內(nèi)部進(jìn)行的,可以獲取 
           ActivationMonitor。組將用該 ActivationMonitor 就對(duì)象和組的狀態(tài)(即該組 
          內(nèi)的組和對(duì)象已變?yōu)榉腔顒?dòng)的)對(duì)系統(tǒng)進(jìn)行更新。 如果該組沒(méi)有被注冊(cè),則拋出 
           UnknownGroupException。如果該組已是活動(dòng)的,則拋出 ActivationException 
          。如果對(duì)激活系統(tǒng)的遠(yuǎn)程調(diào)用失敗,則拋出 RemoteException。 

          unregisterGroup 方法將具有標(biāo)識(shí)符 id 的激活組從激活系統(tǒng)中刪掉。激活組將 
          進(jìn)行此回調(diào),以通知激活器應(yīng)該將該組銷(xiāo)毀。如果此調(diào)用順利完成,就將無(wú)法再 
          在該組內(nèi)注冊(cè)和激活對(duì)象。有關(guān)該組及其相關(guān)對(duì)象的所有信息都將從系統(tǒng)中刪掉 
          。如果該組是未經(jīng)注冊(cè)的,則該方法將拋出 UnknownGroupException。如果遠(yuǎn)程 
          調(diào)用失敗,則拋出 RemoteException。如果注銷(xiāo)失?。ㄈ鐢?shù)據(jù)庫(kù)更新失敗等), 
          則拋出 ActivationException。 

          shutdown 方法將以適當(dāng)?shù)漠惒椒绞浇K止激活系統(tǒng)和所有有關(guān)的激活進(jìn)程(激活器 
          、監(jiān)控器及組)。由激活守護(hù)進(jìn)程所生成的所有組都將被銷(xiāo)毀,激活守護(hù)進(jìn)程也 
          將退出。要關(guān)閉激活系統(tǒng)守護(hù)進(jìn)程 rmid,請(qǐng)執(zhí)行命令: 

          rmid -stop [-端口號(hào)] 

          該命令將關(guān)閉指定端口上的激活守護(hù)進(jìn)程(如果沒(méi)有指定端口,則將關(guān)閉缺省端 
          口上的守護(hù)進(jìn)程)。 
            

          7.4.3 ActivationMonitor 類(lèi)  
          ActivationMonitor 是 ActivationGroup 特有的,它可通過(guò)調(diào)用 ActivationSy 
          stem.activeGroup 以報(bào)告某個(gè)組時(shí)獲得(這種調(diào)用是在 ActivationGroup.crea 
          teGroup 方法內(nèi)部進(jìn)行的)。激活組在出現(xiàn)以下情況時(shí)負(fù)責(zé)通知 ActivationMon 
          itor:它的對(duì)象已變成活動(dòng)對(duì)象、非活動(dòng)對(duì)象或該組已整個(gè)變成非活動(dòng)。 

          package java.rmi.activation; 
          public interface ActivationMonitor extends java.rmi.Remote 


              public abstract void inactiveObject(ActivationID id) 
                  throws UnknownObjectException, RemoteException; 
              
              public void activeObject(ActivationID id, 
                                       java.rmi.MarshalledObject mobj) 
                  throws UnknownObjectException, java.rmi.RemoteException; 
              
              public void inactiveGroup(ActivationGroupID id, long incarnation) 
                  throws UnknownGroupException, java.rmi.RemoteException; 



          當(dāng)激活組中的某個(gè)對(duì)象變成非活動(dòng)(停用)時(shí),該激活組將調(diào)用其監(jiān)控器的 ina 
          ctiveObject 方法。激活組通過(guò)調(diào)用它的 inactiveObject 方法來(lái)發(fā)現(xiàn)其虛擬機(jī) 
          中的對(duì)象(該對(duì)象參與了激活)是否已為非活動(dòng)狀態(tài)。 

          inactiveObject 調(diào)用將通知 ActivationMonitor 其所保留的、具有激活標(biāo)識(shí)符 
           id 的對(duì)象的遠(yuǎn)程對(duì)象引用已不再有效。監(jiān)控器將把與 id 關(guān)聯(lián)的引用視為已過(guò) 
          時(shí)。由于該引用被當(dāng)成過(guò)時(shí)引用,因此后面為同一激活標(biāo)識(shí)符所進(jìn)行的 activat 
          e 調(diào)用將導(dǎo)致遠(yuǎn)程對(duì)象被重新激活。如果該對(duì)象對(duì) ActivationMonitor 未知,該 
          方法將拋出 UnknownObjectException。如果遠(yuǎn)程調(diào)用失敗,則拋出 RemoteExce 
          ption。 

          activeObject 調(diào)用通知 ActivationMonitor 與 id 相關(guān)聯(lián)的對(duì)象現(xiàn)在是活動(dòng)的 
          。參數(shù) obj 是該對(duì)象的 stub 的編組表述。 如果組中的某個(gè)對(duì)象是通過(guò)其它方 
          法被激活的,而不是由系統(tǒng)直接激活的(也就是說(shuō),對(duì)象被注冊(cè)并自己“激活” 
          自己),則 ActivationGroup 必須通知其監(jiān)控器。如果該對(duì)象的標(biāo)識(shí)符先前沒(méi)有 
          被注冊(cè),則該方法將拋出 UnknownObjectException。如果遠(yuǎn)程調(diào)用失敗,則拋出 
           RemoteException。 

          inactiveGroup 調(diào)用通知監(jiān)控器由 id 和 incarnation 所指定的組現(xiàn)在已非活動(dòng) 
          。一旦下一個(gè)要求在該組內(nèi)激活對(duì)象的請(qǐng)求出現(xiàn)時(shí),將用一個(gè)更大的化身數(shù)來(lái)重 
          新創(chuàng)建該組。當(dāng)組中所有對(duì)象都報(bào)告說(shuō)它們已非活動(dòng)對(duì)象時(shí),該組即變成非活動(dòng) 
          組。如果該組的 id 沒(méi)有被注冊(cè),或者化身數(shù)比該組當(dāng)前的化身數(shù)更小,則該方 
          法將拋出 UnknownGroupException。如果遠(yuǎn)程調(diào)用失敗,則拋出 RemoteExcepti 
          on。 

            
          7.4.4 ActivationInstantiator 類(lèi)  
          ActivationInstantiator 負(fù)責(zé)創(chuàng)建可激活對(duì)象的實(shí)例。ActivationGroup 的具體 
          子類(lèi)實(shí)現(xiàn) newInstance 方法,以便對(duì)在組內(nèi)創(chuàng)建對(duì)象的過(guò)程進(jìn)行控制。 


          package java.rmi.activation; 

          public interface ActivationInstantiator extends java.rmi.Remote 

              public MarshalledObject newInstance(ActivationID id, 
                                                  ActivationDesc desc) 
                  throws ActivationException, java.rmi.RemoteException; 



          為了在該組內(nèi)重新創(chuàng)建具有激活標(biāo)識(shí)符 id、描述符 desc 的對(duì)象,激活器需要調(diào) 
          用實(shí)例化器的 newInstance 方法。實(shí)例化器負(fù)責(zé): 

          用描述符的 getClassName 方法來(lái)決定對(duì)象的類(lèi);  
          從由描述符中所獲得的 cadebase 路徑中加載對(duì)象的類(lèi)(用 getLocation 方法) 
          ;  
          通過(guò)調(diào)用對(duì)象的類(lèi)的特殊“激活”構(gòu)造函數(shù)創(chuàng)建該類(lèi)的實(shí)例。這種特殊構(gòu)造函數(shù) 
          帶有兩個(gè)參數(shù):一個(gè)是對(duì)象的 ActivationID,另一個(gè)是含有對(duì)象特有的初始化數(shù) 
          據(jù)的 MarshalledObject;  
          返回一個(gè)含有它所創(chuàng)建的遠(yuǎn)程對(duì)象的 MarshalledObject。  
          實(shí)例化器還負(fù)責(zé)在它所創(chuàng)建或激活的對(duì)象不再是活動(dòng)對(duì)象時(shí)進(jìn)行報(bào)告,因此可以 
          對(duì)其 ActivationMonitor 執(zhí)行相應(yīng)的 inactiveObject 調(diào)用(詳細(xì)信息,參見(jiàn)  
          ActivationGroup 類(lèi))。 

          如果對(duì)象的激活失敗, newInstance 方法將拋出 ActivationException。如果遠(yuǎn) 
          程調(diào)用失敗,則該方法將拋出 RemoteException。 

          7.4.5 ActivationGroupDesc 類(lèi)  
          激活組描述符 ActivationGroupDesc 含有創(chuàng)建或重新創(chuàng)建激活組(將在該激活組 
          中激活相同 Java 虛擬機(jī)上的對(duì)象)所需的信息。 

          這種描述符含有: 

          組的類(lèi)名,  
          組的 cadebase 路徑(組的類(lèi)所在位置),  
          “已編組”對(duì)象,它可包含對(duì)象特定的初始化數(shù)據(jù)。  
          對(duì)象的類(lèi)必須是 ActivationGroup 的具體子類(lèi)。ActivationGroup 的子類(lèi)是用  
          ActivationGroup.createGroup 靜態(tài)方法來(lái)創(chuàng)建或重新創(chuàng)建的,該靜態(tài)方法將調(diào) 
          用含有以下兩個(gè)參數(shù)的特殊構(gòu)造函數(shù):  

          該組的 ActivationGroupID,  
          該組的初始化數(shù)據(jù)(在 java.rmi.MarshalledObject 中)  

          package java.rmi.activation; 

          public final class ActivationGroupDesc implements java.io.Serializable 


              public ActivationGroupDesc(java.util.Properties props, 
                                         CommandEnvironment env);; 
              
              public ActivationGroupDesc(String className, 
                                         String codebase, 
                                         java.rmi.MarshalledObject data, 
                                         java.util.Properties props, 
                                         CommandEnvironment env); 
                                      
              public String getClassName(); 
              
              public String getLocation(); 
              
              public java.rmi.MarshalledObject getData(); 
              
              public CommandEnvironment getCommandEnvironment(); 
              
              public java.util.Properties getPropertiesOverrides(); 


          第一個(gè)構(gòu)造函數(shù)將創(chuàng)建一個(gè)組描述符,它用系統(tǒng)的缺省值來(lái)作為組的實(shí)現(xiàn)和代碼 
          位置。各屬性指定了 Java 環(huán)境覆蓋(它將覆蓋組實(shí)現(xiàn)虛擬機(jī)中的系統(tǒng)屬性)。 
          命令環(huán)境可控制啟動(dòng)子虛擬機(jī)時(shí)所用的確切命令/選項(xiàng),也可為 null 以接受 rm 
          id 的缺省值。 

          第二個(gè)構(gòu)造函數(shù)和第一個(gè)相同,但它允許指定 Properties 和 CommandEnvironm 
          ent。 

          getClassName 方法返回組的類(lèi)名。 

          getLocation 方法返回 cadebase 路徑,從中可加載該組的類(lèi)。 

          getData 方法以編組形式返回組的初始化數(shù)據(jù)。 

          getCommandEnvironment 方法返回命令環(huán)境(可能為 null)。 

          getPropertiesOverrides 方法返回該描述符的屬性覆蓋(可能為 null)。 

            

          7.4.6 ActivationGroupDesc.CommandEnvironment 類(lèi)  
          CommandEnvironment 類(lèi)允許對(duì)缺省系統(tǒng)屬性進(jìn)行覆蓋,并可為 ActivationGrou 
          p 指定由實(shí)現(xiàn)所定義的選項(xiàng)。 

          public static class CommandEnvironment 

          implements java.io.Serializable 

              public CommandEnvironment(String cmdpath, String[] args); 
              public boolean equals(java.lang.Object); 
              public String[] getCommandOptions(); 
              public String getCommandPath(); 
              public int hashCode(); 

            

          構(gòu)造函數(shù)將用所給的命令 cmdpath 和另一個(gè)命令行選項(xiàng) args 創(chuàng)建 CommandEnv 
          ironment。 

          equals 實(shí)現(xiàn)對(duì)命令環(huán)境對(duì)象的內(nèi)容等效操作。對(duì) hashCode 方法進(jìn)行適當(dāng)?shù)膶?shí)現(xiàn) 
          可在必要時(shí)將 CommandEnvironment 對(duì)象儲(chǔ)存在散列表中。 

          getCommandOptions 方法返回環(huán)境對(duì)象的命令行選項(xiàng)。 

          getCommandPath 方法返回環(huán)境對(duì)象的命令字符串。 

          7.4.7 ActivationGroupID 類(lèi)  
          注冊(cè)過(guò)的激活組的標(biāo)識(shí)符可有以下幾個(gè)用途: 

          在激活系統(tǒng)中對(duì)該組進(jìn)行唯一標(biāo)識(shí)  
          含有對(duì)該組的激活系統(tǒng)的引用,因而必要時(shí)該組能與其激活系統(tǒng)聯(lián)系。  
          ActivationGroupID 將在調(diào)用 ActivationSystem.registerGroup 時(shí)被返回,并 
          用來(lái)在該激活系統(tǒng)內(nèi)標(biāo)識(shí)該組。當(dāng)創(chuàng)建或重新創(chuàng)建激活組時(shí),該組標(biāo)識(shí)符將被作 
          為參數(shù)傳給激活組的特殊構(gòu)造函數(shù)。 


          package java.rmi.activation; 

          public class ActivationGroupID implements java.io.Serializable 

              public ActivationGroupID(ActivationSystem system); 
              
              public ActivationSystem getSystem(); 
              
              public boolean equals(Object obj); 
              
              public int hashCode(); 


          ActivationGroupID 構(gòu)造函數(shù)創(chuàng)建唯一的組標(biāo)識(shí)符。該標(biāo)識(shí)符的 ActivationSys 
          tem 是 system。 

          getSystem 方法返回組的激活系統(tǒng)。 

          hashCode 方法返回組標(biāo)識(shí)符的散列碼。兩個(gè)指向同一遠(yuǎn)程組的組標(biāo)識(shí)符將具有相 
          同的散列碼。 

          equals 方法比較兩個(gè)組標(biāo)識(shí)符內(nèi)容的等效性。如果以下兩個(gè)條件均成立,該方法 
          將返回 true: 1) 兩個(gè)唯一標(biāo)識(shí)符在內(nèi)容上等價(jià)。2) 各標(biāo)識(shí)符中指定的激活系 
          統(tǒng)都引用同一遠(yuǎn)程對(duì)象。 

            

          7.4.8 ActivationGroup 類(lèi)  
          ActivationGroup 負(fù)責(zé)在其組中創(chuàng)建“可激活”對(duì)象的新實(shí)例,并在出現(xiàn)下列情 
          況時(shí)通知其 ActivationMonitor: 其對(duì)象變成活動(dòng)或非活動(dòng),或者該組整體變成 
          非活動(dòng)。 

          ActivationGroup 最初是由以下方法之一創(chuàng)建的:  

          作為創(chuàng)建對(duì)象的“缺省” ActivationDesc 的副效應(yīng)而創(chuàng)建  
          通過(guò)對(duì) ActivationGroup.createGroup 方法的顯式調(diào)用而創(chuàng)建  
          作為在組(該組中僅 ActivationGroupDesc 被注冊(cè)過(guò))中激活第一個(gè)對(duì)象時(shí)的副 
          效應(yīng)而創(chuàng)建。  
          只有激活器才能重新創(chuàng)建 ActivationGroup。必要時(shí),激活器將為每個(gè)已注冊(cè)的 
          激活組生成一個(gè)獨(dú)立的虛擬機(jī)(例如作為子進(jìn)程)并將激活請(qǐng)求定向到相應(yīng)的組 
          。生成虛擬機(jī)的方式與實(shí)現(xiàn)有關(guān)。激活組是通過(guò) ActivationGroup.createGroup 
           靜態(tài)方法來(lái)創(chuàng)建的。createGroup 方法對(duì)即將創(chuàng)建的組有兩個(gè)要求: 1) 該組必 
          須是 ActivationGroup 的具體子類(lèi);2) 該組必須有一個(gè)取以下兩個(gè)參數(shù)的構(gòu)造 
          函數(shù):  

          該組的 ActivationGroupID,  
          該組的初始化數(shù)據(jù)(包含在 MarshalledObject中)  
          創(chuàng)建完畢,ActivationGroup 的缺省實(shí)現(xiàn)將在創(chuàng)建該組的 ActivationGroupDesc 
           時(shí)把系統(tǒng)屬性設(shè)置為強(qiáng)制系統(tǒng)屬性,并將安全管理器設(shè)置為 java.rmi.RMISecu 
          rityManager。如果應(yīng)用程序要求當(dāng)對(duì)象在組中被激活時(shí)設(shè)置某些特定的屬性,則 
          該應(yīng)用程序應(yīng)在創(chuàng)建 ActivationDesc 之前(缺省 ActivationGroupDesc 創(chuàng)建前 
          )設(shè)置這些屬性。 

          package java.rmi.activation;

          public abstract class ActivationGroup
              extends UnicastRemoteObject 
              implements ActivationInstantiator 

              protected ActivationGroup(ActivationGroupID groupID) 
                  throws java.rmi.RemoteException; 
              
              public abstract MarshalledObject newInstance(ActivationID id, 
                                                           ActivationDesc desc) 
                  throws ActivationException, java.rmi.RemoteException; 
              
              public abstract boolean inactiveObject(ActivationID id) 
                  throws ActivationException, UnknownObjectException, 
                      java.rmi.RemoteException; 
              
              public static ActivationGroup createGroup(ActivationGroupID id, 
                                                        ActivationGroupDesc desc, 
                                                        long incarnation) 
                  throws ActivationException; 
              
              public static ActivationGroupID currentGroupID(); 
              
              public static void setSystem(ActivationSystem system) 
                  throws ActivationException; 
              
              public static ActivationSystem getSystem() 
                  throws ActivationException; 
              
              protected void activeObject(ActivationID id, 
                                          java.rmi.MarshalledObject mobj) 
                  throws ActivationException, UnknownObjectException, 
                      java.rmi.RemoteException; 
              
              protected void inactiveGroup() 
                  throws UnknownGroupException, java.rmi.RemoteException;



          激活器通過(guò)調(diào)用激活組的 newInstance 方法來(lái)激活具有激活描述符 desc 的對(duì)象 
          。激活組負(fù)責(zé): 

          利用描述符的 getClassName 方法來(lái)確定該對(duì)象的類(lèi);  
          通過(guò) getLocation 方法從由描述符中所得到的 URL 路徑中加載該類(lèi);  
          通過(guò)調(diào)用該對(duì)象類(lèi)的特殊構(gòu)造函數(shù)來(lái)創(chuàng)建該類(lèi)的實(shí)例。該構(gòu)造函數(shù)取以下兩個(gè)變 
          量:對(duì)象的 ActivationID 和含有對(duì)象初始化數(shù)據(jù)的 MarshalledObject;  
          將剛創(chuàng)建的遠(yuǎn)程對(duì)象的序列化版本返給激活器。  
          如果無(wú)法創(chuàng)建所給描述符的實(shí)例,該方法將拋出 ActivationException。 

          對(duì)該組的 inactiveObject 方法的調(diào)用是通過(guò)調(diào)用 Activatable.inactive 方法 
          來(lái)間接進(jìn)行的。當(dāng)遠(yuǎn)程對(duì)象停用時(shí)(該對(duì)象被認(rèn)為非活動(dòng)的),該對(duì)象的實(shí)現(xiàn)必 
          須調(diào)用 Activatable 的 inactive。如果對(duì)象在非活動(dòng)時(shí)不調(diào)用 Activatable.i 
          nactive,則該對(duì)象將永遠(yuǎn)不會(huì)被作為垃圾收集,因?yàn)榻M將對(duì)其所創(chuàng)建的對(duì)象保留 
          強(qiáng)引用。  

          組的 inactiveObject 方法可阻止從 RMI 運(yùn)行時(shí)中導(dǎo)出與 id 關(guān)聯(lián)的遠(yuǎn)程對(duì)象( 
          僅當(dāng)沒(méi)有對(duì)該對(duì)象的待定或正在執(zhí)行的調(diào)用時(shí))。使該對(duì)象將無(wú)法再接收到來(lái)的 
           RMI 調(diào)用。如果該對(duì)象當(dāng)前還有待定或正在執(zhí)行的調(diào)用,inactiveObject 將返 
          回 false 且不采取任何動(dòng)作。 

          如果 unexportObject 操作成功,意味著該對(duì)象沒(méi)有待定或正在執(zhí)行的調(diào)用。此 
          時(shí)組將通過(guò)監(jiān)控器的 inactiveObject 方法通知它的 ActivationMonitor 該遠(yuǎn)程 
          對(duì)象當(dāng)前是非活動(dòng)的,以便激活器在接到下一激活請(qǐng)求時(shí)即重新將該遠(yuǎn)程對(duì)象激 
          活。如果操作成功,inactiveObject 將返回 true。如果該對(duì)象被 ActivationG 
          roup 認(rèn)為是活動(dòng)的但已被阻止導(dǎo)出,操作將仍有可能成功。 

          如果激活組不知道該對(duì)象(例如該對(duì)象先前已被報(bào)告為是非活動(dòng)的,或者從未通 
          過(guò)該激活組來(lái)激活該對(duì)象),則 inactiveObject 方法將拋出 UnknownObjectEx 
          ception。如果非活動(dòng)操作失?。ɡ?,對(duì)激活器或激活組的遠(yuǎn)程調(diào)用失?。瑒t 
          將拋出 RemoteException。 

          createGroup 方法將為當(dāng)前虛擬機(jī)創(chuàng)建和設(shè)置激活組。只有在激活組是當(dāng)前未設(shè) 
          定的情況下才能對(duì)它進(jìn)行設(shè)置。當(dāng) Activator 為了執(zhí)行到來(lái)的 activate 請(qǐng)求而 
          啟動(dòng)某一激活組的重新創(chuàng)建過(guò)程時(shí),該激活組即通過(guò) createGroup 方法進(jìn)行設(shè)置 
          。組必須先向 ActivationSystem 注冊(cè)一個(gè)描述符,然后才能用該方法(將注冊(cè) 
          中得到的 ActivationID 傳給它)來(lái)創(chuàng)建該組。 

          由 ActivationGroupDesc(即 desc)指定的組必須是 ActivationGroup 的具體 
          子類(lèi)并具有公共構(gòu)造函數(shù)。該公共構(gòu)造函數(shù)取兩個(gè)參數(shù):一個(gè)是組的 Activatio 
          nGroupID;另一個(gè)是 MarshalledObject,它含有組的初始化數(shù)據(jù)(從組的Activ 
          ationGroupDesc 中獲得的)。注意: 如果應(yīng)用程序要?jiǎng)?chuàng)建自己的自定義激活組 
          ,該組必須在構(gòu)造函數(shù)中設(shè)置安全管理器。否則將不能在該組中激活對(duì)象。 

          創(chuàng)建完組后,即通知 ActivationSystem 該組已通過(guò)調(diào)用 activeGroup 方法(該 
          方法將返回組的 ActivationMonitor)而被激活。應(yīng)用程序不必單獨(dú)調(diào)用 activ 
          eGroup,因?yàn)?nbsp;createGroup 方法將負(fù)責(zé)這一回調(diào)。 

          一旦組被創(chuàng)建,對(duì) currentGroupID 方法的后續(xù)調(diào)用都將返回該組的標(biāo)識(shí)符,直 
          到該組變成非活動(dòng)組為止。那時(shí),currentGroupID 方法將返回 null。 

          參數(shù) incarnation 表示當(dāng)前的組化身數(shù),也就是該組被激活的次數(shù)。一旦組被成 
          功創(chuàng)建,化身數(shù)就被用作 activeGroup 方法的參數(shù)。化身數(shù)從 0 開(kāi)始。如果該 
          組已經(jīng)存在,或在組的創(chuàng)建過(guò)程中出錯(cuò),createGroup 方法將拋出 ActivationE 
          xception。 

          setSystem 方法用于設(shè)置虛擬機(jī)的 ActivationSystem (system)。只有當(dāng)前沒(méi)有 
          組為活動(dòng)組時(shí)才能對(duì)激活系統(tǒng)進(jìn)行設(shè)置。如果沒(méi)有通過(guò)顯式調(diào)用 setSystem 來(lái)設(shè) 
          置激活系統(tǒng),則 getSystem 方法將嘗試通過(guò)在 Activator 的注冊(cè)服務(wù)程序中查 
          找名稱(chēng) java.rmi.activation.ActivationSystem 來(lái)獲得對(duì) ActivationSystem  
          的引用。缺省情況下,查找激活系統(tǒng)所用的端口號(hào)將由 ActivationSystem.SYST 
          EM_PORT 定義。通過(guò)設(shè)置屬性 java.rmi.activation.port 可將該端口覆蓋掉。 
          如果調(diào)用 setSystem 時(shí)激活系統(tǒng)已經(jīng)設(shè)置好,則該方法將拋出 ActivationExce 
          ption。 

          getSystem 方法返回該虛擬機(jī)的激活系統(tǒng)。激活系統(tǒng)可由 setSystem 方法(前述 
          )設(shè)置。 

          activeObject 方法是一個(gè)受保護(hù)的方法。子類(lèi)將用它來(lái)對(duì)組監(jiān)控器進(jìn)行 active 
          Object 回調(diào),以通知監(jiān)控器具有指定激活 id 且其 stub 包含在 mobj 中的遠(yuǎn)程 
          對(duì)象現(xiàn)在是活動(dòng)的。這一調(diào)用只是轉(zhuǎn)發(fā)給組的 ActivationMonitor。 

          inactiveGroup 方法是一個(gè)受保護(hù)的方法。子類(lèi)用它來(lái)通知組監(jiān)控器該組已變成 
          非活動(dòng)的。當(dāng)組中每個(gè)參與虛擬機(jī)中激活活動(dòng)的對(duì)象都變成非活動(dòng)時(shí),子類(lèi)就進(jìn) 
          行此調(diào)用。  

          7.4.9 MarshalledObject 類(lèi)  
          MarshalledObject 是某個(gè)對(duì)象的容器,它允許在進(jìn)行 RMI 調(diào)用時(shí)將該對(duì)象當(dāng)作 
          一個(gè)參數(shù)來(lái)傳遞,但它延遲該對(duì)象在接收端上的序列化恢復(fù),直到應(yīng)用程序明確 
          地請(qǐng)求該對(duì)象(通過(guò)調(diào)用該容器對(duì)象)。包含在該 MarshalledObject 中的可序 
          列化對(duì)象是用相同的語(yǔ)義(該語(yǔ)義作為 RMI 調(diào)用中的參數(shù)來(lái)傳遞)來(lái)序列化和序 
          列化恢復(fù)的(請(qǐng)求時(shí))。也就是說(shuō),MarshalledObject 中的任一遠(yuǎn)程對(duì)象都可表 
          示為其 stub 的序列化實(shí)例。MarshalledObject 所包含的對(duì)象可以是遠(yuǎn)程對(duì)象、 
          非遠(yuǎn)程對(duì)象或遠(yuǎn)程對(duì)象和非遠(yuǎn)程對(duì)象的完整圖形。 

          當(dāng)對(duì)象被放入 MarshalledObject 的 wrapper 中時(shí),該對(duì)象的序列化形式將被注 
          釋為 cadebase  URL(可從中加載類(lèi));同樣,當(dāng)從對(duì)象的 MarshalledObject  
          的 wrapper 中取回該對(duì)象時(shí),如果本地沒(méi)有該對(duì)象的代碼,則使用該 URL(序列 
          化時(shí)所注解的)來(lái)定位和加載該對(duì)象類(lèi)的字節(jié)代碼。 

          package java.rmi; 

          public final class MarshalledObject implements java.io.Serializable 

              public MarshalledObject(Object obj) throws java.io.IOException; 

              public Object get() 
                  throws java.io.IOException, ClassNotFoundException; 

              public int hashCode(); 

              public boolean equals(); 
          }


          MarshalledObject 的構(gòu)造函數(shù)將可序列化的對(duì)象 obj 作為單一參數(shù),并將對(duì)象 
          的編組表示存放在字節(jié)流中。對(duì)象的編組表示保存了對(duì)象在 RMI 調(diào)用時(shí)所傳遞的 
          語(yǔ)義: 

          流中的每個(gè)類(lèi)都被注解為其 cadebase URL,以便在重構(gòu)該對(duì)象(通過(guò)調(diào)用 get  
          方法)時(shí)可以找到各個(gè)類(lèi)的字節(jié)代碼并進(jìn)行加載;  
          遠(yuǎn)程對(duì)象由它們的代理服務(wù)器 stub 所代替。  
          當(dāng)把類(lèi) MarshalledObject 的實(shí)例寫(xiě)到 java.io.ObjectOutputStream 中時(shí),所 
          含對(duì)象的編組形式(在構(gòu)造中創(chuàng)建)亦被寫(xiě)到流中。因此,只有字節(jié)流才被序列 
          化。 

          當(dāng)從 java.io.ObjectInputStream 中讀取 MarshalledObject 時(shí),并不把所包含 
          的對(duì)象序列化恢復(fù)為一個(gè)具體對(duì)象;該對(duì)象將一直保持其編組表示,直到該已編 
          組對(duì)象的 get 方法被調(diào)用為止。 

          get 方法總是要用所含對(duì)象的編組形式來(lái)重新構(gòu)造該對(duì)象。內(nèi)部表示將用解編參 
          數(shù)(用于 RMI 調(diào)用)所用的語(yǔ)義來(lái)進(jìn)行序列化恢復(fù)。因此,對(duì)象表示的序列化恢 
          復(fù)將用嵌入對(duì)象序列化流中的 URL 注解來(lái)加載類(lèi)的代碼(如果本地沒(méi)有該代碼) 
          。 

          對(duì)象編組表示的 hashCode 與傳遞給構(gòu)造函數(shù)的對(duì)象相同。如果進(jìn)行比較的對(duì)象 
          的編組表示是等價(jià)的,則 equals 方法將返回 true。該 equals 方法所采用的比 
          較將忽略類(lèi)的 cadebase 注解,即除了序列化表示中各個(gè)類(lèi)的 cadebase 外,只 
          要兩個(gè)對(duì)象具有相同的序列化表示,則這兩個(gè)對(duì)象就是等價(jià)的。

          凡是有該標(biāo)志的文章,都是該blog博主Caoer(草兒)原創(chuàng),凡是索引、收藏
          、轉(zhuǎn)載請(qǐng)注明來(lái)處和原文作者。非常感謝。

          posted on 2005-12-14 13:15 草兒 閱讀(150) 評(píng)論(0)  編輯  收藏 所屬分類(lèi): Java編程經(jīng)驗(yàn)談
          主站蜘蛛池模板: 临朐县| 中方县| 明星| 名山县| 隆子县| 姜堰市| 灌南县| 民县| 红原县| 富川| 顺昌县| 宜昌市| 新田县| 达州市| 盐亭县| 郁南县| 嘉鱼县| 温州市| 红桥区| 福贡县| 合江县| 辽阳市| 涿鹿县| 白水县| 南雄市| 诸暨市| 屏南县| 永胜县| 桑植县| 日照市| 上栗县| 共和县| 桐城市| 铜梁县| 青冈县| 四会市| 亚东县| 兴和县| 常德市| 大新县| 凤山县|