<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    無為

    無為則可為,無為則至深!

      BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
      190 Posts :: 291 Stories :: 258 Comments :: 0 Trackbacks
    服務器接口  
    java.rmi.server 包包含通常用于實現遠程對象的接口與類。 

    主題:  
    RemoteObject 類  
    RemoteServer 類  
    UnicastRemoteObject 類  
    Unreferenced 接口  
    RMISecurityManager 類  
    RMIClassLoader 類  
    LoaderHandler 接口  
    RMI 套接字工廠  
    RMIFailureHandler 接口  
    LogStream 類  
    stub 和 skeleton 編譯器  

    5.1 RemoteObject 類  
    類 java.rmi.server.RemoteObject 將 java.lang.Object 行為實現于遠程 
    對象。實現方法 hashCode 和 equals 將允許將遠程對象引用存儲在散列表中 
    進行比較。如果兩個 Remote 對象引用同一個遠程對象,則方法 equals 的返 
    回值為 true。它負責比較遠程對象的遠程對象引用。 

    方法 toString 返回一個說明遠程對象的字符串。該字符串的內容和語法與實 
    現有關且可變。 

    java.lang.Object 中的其它方法保留了它們的原始實現。 

    package java.rmi.server; 
    public abstract class RemoteObject 
    implements java.rmi.Remote, java.io.Serializable 

        protected transient RemoteRef ref; 
        protected RemoteObject(); 
        protected RemoteObject(RemoteRef ref); 
        public RemoteRef getRef(); 
        public static Remote toStub(java.rmi.Remote obj) 
        throws java.rmi.NoSuchObjectException; 
        public int hashCode(); 
        public boolean equals(Object obj); 
        public String toString(); 


    因為 RemoteObject 是抽象類,所以無法實例化。因此,RemoteObject 的構 
    造函數必須從子類實現中調用。第一個 RemoteObject 構造函數將創建帶空的 
    遠程引用的 RemoteObject。第二個 RemoteObject 構造函數將創建帶給定遠 
    程引用 ref 的 RemoteObject。 

    方法 getRef 返回該遠程對象的遠程引用。 

    方法 toStub 返回一個遠程對象 obj 的 stub 并作為參數傳送。該操作僅在 
    已經導出遠程對象實現后才有效。如果找不到遠程對象的 stub,該方法就拋出 
     NoSuchObjectException。 

    5.1.1 RemoteObject 類覆蓋的對象方法  
    java.lang.Object 類中用于方法 equals、hashCode 和 toString 的缺省實 
    現不適用于遠程對象。因此,RemoteObject 類提供了這些方法在語義上更合適 
    于遠程對象的實現。 

    equals 和 hashCode 方法  
    為凍潭韻笥米魃⒘斜碇械鬧骷頤潛匭朐讜凍潭韻笫迪種懈哺?nbsp;equals 和 
     hashCode 方法,這些方法是由類 java.rmi.server.RemoteObject 覆蓋的: 

    java.rmi.server.RemoteObject 類實現 equals 方法決定了兩個對象的引用 
    是否相等,而不是兩個對象的內容是否相等。這是因為決定內容是否相等時需要 

    遠程方法調用,而 equals 的簽名不允許拋出遠程異常。  
    對于所有引用同一底層遠程對象的遠程引用,java.rmi.server.RemoteObject 
    類實現的 hashCode 方法返回同一個值(因為對相同對象的引用被認為是相等 

    的)。  

    toString 方法  
    toString 方法被定義為返回表示對象的遠程引用的字符串。字符串的內容視引 
    用的類型而定。單體(單路傳送)對象的當前實現一個對象標識符以及與傳輸層 
    有關的該對象的其他信息(例如主機名和端口號)。 

    clone 方法 
    只有在對象支持 java.lang.Cloneable 接口時才能用 Java 語言的缺省機制 
    來復制。由 rmic 編譯器生成的遠程對象的 stub 將被聲明為終態,且不實現  
    Cloneable 接口,因此無法復制 stub。 

    5.1.2 序列化形式  
    RemoteObject 類實現專門的(私用)方法 writeObject 和方法 readObject, 
    它們由對象序列化機制調用來處理向 java.io.ObjectOutputStream 中序列化 
    數據。RemoteObject 的序列化形式由下列方法寫入: 
    private void writeObject(java.io.ObjectOutputStream out) 
    throws java.io.IOException, java.lang.ClassNotFoundException; 
    如果 RemoteObject 的遠程引用域 ref 為空,則該方法拋出  
    java.rmi.MarshalException。  
    如果遠程引用 ref 為非空:  
    ref 的類通過調用其 getRefClass 方法來獲得,該方法通常返回遠程引用類的 
    非打包全名。如果返回的類名為非空:  
    ref 的類名將以 UTF 格式寫到流 out 中。 

    調用 ref 的方法 writeExternal,傳遞的參數為流 out,從而使 ref 可以將 
    其外部表示法寫到流中。 

    如果 ref.getRefClass 返回的類名為空:  
    則將一個 UTF 格式的空字符串寫到流 out 中。 

    ref 被序列化到流 out(即利用 writeObject)。  
    序列化恢復時,RemoteObject 的狀態將由 ObjectInputStream 調用該方法利 
    用其序列化形式進行重構: 

    private void readObject(java.io.ObjectInputStream in) 
    throws java.io.IOException, java.lang.ClassNotFoundException; 

    首先,ref 的類名(UTF 字符串)將從流 in 中讀出。如果類名為空字符串:  
    則從流中讀出對象,然后將 ref 初始化為該對象(即通過調用 in.readObject) 
     如果類名為非空:  
    則 ref 的完整類名由字符串 java.rmi.server.RemoteRef.packagePrefix 的 
    值和“.”加上從流中讀取的類名相連接而成。  
    創建 ref 類的實例(利用上述完整類名)。  
    該新實例(成為 ref 域)從流 in 中讀取其外部形式。  

    2 RemoteServer 類  
    java.rmi.server.RemoteServer 類是服務器實現類
        java.rmi.server.UnicastRemoteObject  
    和 java.rmi.activation.Activatable 的通用超類。 

    package java.rmi.server; 
    public abstract class RemoteServer extends RemoteObject


        protected RemoteServer(); 
        protected RemoteServer(RemoteRef ref); 

        public static String getClientHost() 
            throws ServerNotActiveException; 
        public static void setLog(java.io.OutputStream out); 
        public static java.io.PrintStream getLog(); 



    因為 RemoteServer 是抽象類,所以將無法實例化。因此,必須從子類實現中 
    調用某一 RemoteServer 的構造函數。第一個 RemoteServer 構造函數將創建 
    帶空遠程引用的 RemoteServer。第二個 RemoteServer 構造函數將創建帶給 
    定遠程引用 ref 的 RemoteServer。 

    getClientHost 方法允許一個活動方法確定當前線程中活動的遠程方法是由哪 
    臺主機初始化的。如果當前線程中沒有活動的遠程方法,則拋出異常 ServerNot 
    ActiveException。 
    setLog 方法將 RMI 調用記錄到指定輸出流中。如果輸出流為空,則關閉調用 
    日志。getLog 方法返回 RMI 調用日志流,從而使特定于應用程序的信息以同 
    步方式寫到調用日志中。 

    5.3 UnicastRemoteObject 類 
    類 java.rmi.server.UnicastRemoteObject 支持創建并導出遠程對象。該類 
    實現的遠程服務器對象具有下列特征: 

    對這種對象的引用至多僅在創建該遠程對象的進程生命期內有效。  
    通過 TCP 傳輸與遠程對象通信。  
    調用、參數和結果使用流協議在客戶機和服務器之間進行通信。  
    package java.rmi.server; 
    public class UnicastRemoteObject extends RemoteServer


        protected UnicastRemoteObject() 
            throws java.rmi.RemoteException; 
        protected UnicastRemoteObject(int port) 
            throws java.rmi.RemoteException; 
        protected UnicastRemoteObject(int port, 
                                      RMIClientSocketFactory csf, 
                                      RMIServerSocketFactory ssf) 
            throws java.rmi.RemoteException; 
        public Object clone() 
            throws java.lang.CloneNotSupportedException; 
        public static RemoteStub exportObject(java.rmi.Remote obj) 
            throws java.rmi.RemoteException; 
        public static Remote exportObject(java.rmi.Remote obj, int port) 
            throws java.rmi.RemoteException; 
        public static Remote exportObject(Remote obj, int port, 
                                          RMIClientSocketFactory csf, 
                                          RMIServerSocketFactory ssf) 
            throws java.rmi.RemoteException; 
        public static boolean unexportObject(java.rmi.Remote obj, boolean force) 
            throws java.rmi.NoSuchObjectException; 


      
    5.3.1 構造新遠程對象 
    遠程對象實現(實現一個或多個遠程接口的實現)必須被創建和導出。導出遠程 
    對象使得對象能接受來自客戶機的到來的調用。作為 UnicastRemoteObject  
    導出的遠程對象,其導出涉及在 TCP 端口監聽(注意,多個遠程對象可以接受 
    同一端口的到來的調用,因此沒必要在新的端口上監聽)。遠程對象實現可以擴 
    展類 UnicastRemoteObject 以使用其導出對象的構造函數,或者擴展其它類 
    (或者根本不擴展)并通過 UnicastRemoteObject 的 exportObject 方法導 
    出對象。  

    無參數的構造函數將創建遠程對象并在匿名(或任意)端口上導出,而這將在運 
    行時進行選擇。第二種形式的構造函數帶單個參數(即 port),它指定遠程對 
    象接受到來的調用的端口號。第三種構造函數創建的遠程對象在指定端口上通過 
     RMIServerSocketFactory 創建的 ServerSocket 接受到來的調用;客戶機 
    通過由 RMIClientSocketFactory 提供的 Socket 與遠程對象建立連接。 

    5.3.2 導出并非由 RemoteObject 擴展而來的實現 
    exportObject 方法(任何形式)可用于導出不是由擴展 UnicastRemoteObject 
    類實現的簡單對等遠程對象。第一種形式的 exportObject 方法帶單個參數 
    (即 obj),它是接受到來的 RMI 調用的遠程對象;該 exportObject 方法 
    在匿名(或任意)端口上導出遠程對象,而這將在運行時進行選擇。第二種形式 
    的 exportObject 方法帶兩個參數,分別是遠程對象 obj 和 port。port 是 
    遠程對象接受到來的調用的端口號。第三種 exportObject 方法用指定的 
    RMIClientSocketFactory、csf 和 RMIServerSocketFactory、ssf 在指定 
    port 上導出對象 obj。  
    在作為參數或返回值傳入 RMI 調用前,必須導出對象,否則當試圖把“未導出 
    的”對象作為參數或返回值傳遞給一個遠程調用時,將會拋出  
    java.rmi.server.StubNotFoundException。  
    導出后,對象既可作為參數傳入 RMI 調用,也可作為 RMI 調用的結果返回。  
    exportObject 方法返回 Remote stub。它是遠程對象的 stub 對象 obj,它 
    將替代遠程對象被傳入 RMI 調用。 

    5.3.3 在 RMI 調用中傳遞 UnicastRemoteObject 
    如上所述,當類型為 UnicastRemoteObject 的對象作為參數或返回值傳入  
    RMI 調用中時,該對象將由遠程對象的 stub 所代替。遠程對象實現保留在創 
    建它的虛擬機中,且不會移出(包括其值)。換言之,遠程對象通過引用傳入  
    RMI 調用;遠程對象實現不能通過值進行傳遞。 

    5.3.4 序列化 UnicastRemoteObject 
    如果 UnicastRemoteObject 類型的對象寫入用戶定義的 ObjectOutputStream 
    例如,該對象寫入使用序列化的文件),則其中所含的信息將是瞬態的且未予保 
    存。但如果對象是用戶定義的 UnicastRemoteObject 子類實例,它就能擁有 
    非瞬態數據并可在序列化對象時予以保存。  

    當 UnicastRemoteObject 從 ObjectInputStream 讀出時,它將自動導出到  
    RMI 運行時,以便接收 RMI 調用。如果由于某種原因而導致導出失敗,則序列 
    化恢復對象過程將予以終止,同時拋出異常。 

    5.3.5 逆導出 UnicastRemoteObject 
    unexportObject 方法使遠程對象 obj 無法接受到來的調用。如果強制參數為 
    真,則即使有對遠程對象的待定調用或當前調用,該遠程對象仍將被強制逆導出。 
    如果強制參數為假,則僅在無對該對象的待定調用和當前調用時才逆導出該對象 
    。如果對象被成功地逆導出,則運行時將把該對象從內部表中刪除。以這種強制 
    方式逆導出對象可能導致客戶機持有該遠程對象的過期遠程引用。如果遠程對象 
    先前并未導出到 RMI 運行時中,則該方法將拋出異常
        java.rmi.NoSuchObjectException。 

    5.3.6 clone 方法 
    只有支持 java.lang.Cloneable 接口的對象才可使用 Java 語言的缺省機制 
    復制。類 java.rmi.server.UnicastRemoteObject 并不實現該接口,但它實 
    現 clone 方法以便當子類需要實現 Cloneable 時遠程對象可以正確地進行復 
    制。clone 方法可由子類用于創建一個初始內容相同的復制的遠程對象。但是 
    可以被導出接受遠程調用且與原對象有所不同。 


    5.4 Unreferenced 接口  
    package java.rmi.server; 
    public interface Unreferenced

        public void unreferenced(); 


    java.rmi.server.Unreferenced 接口允許服務器對象通知,告訴它沒有客戶 
    機對它進行遠程引用。分布式垃圾收集機制將為每個遠程對象維護一個持有該遠 

    程對象引用的客戶虛擬機集合。只要某個客戶機持有該遠程對象的遠程引用, 
    RMI 運行時就會保存該遠程對象的本地引用。當“引用”集合為空時,即調用  

    Unreferenced.unreferenced 方法(如果服務器實現 Unreferenced 接口)。 
    遠程對象不需要支持 Unreferenced 接口。 
    只要存在遠程對象的某個本地引用,它就可以在遠程調用中傳遞或返給客戶機。 
    接收引用的進程將被添加到遠程對象的引用集合中。當引用集合為空時,即調用 
    遠程對象的 unreferenced 方法。這樣,Unreferenced 方法可以進行多次調 
    用(每當集合為空時)。當不再有引用(本地引用或客戶機持有的引用)時,才 
    會收集遠程對象。 

    5.5 RMISecurityManager 類  
    package java.rmi; 

    public class RMISecurityManager extends java.lang.SecurityManager

        public RMISecurityManager(); 
        public synchronized void checkPackageAccess(String pkg) 
            throws RMISecurityException; 


    RMISecurityManager 提供與 java.lang.SecurityManager 相同的安全特性, 
    但它覆蓋 checkPackageAcess 方法。 

    在 RMI 應用程序中,如果沒有設置安全管理器,則只能從本地類路徑加載  
    stub 和類。這可確保應用程序不受由遠程方法調用所下載的代碼的侵害。 


    5.6 RMIClassLoader 類 
    java.rmi.server.RMIClassLoader 類提供一套公共靜態方法,用于支持 RMI 
    中基于網絡的類加載。這些方法由 RMI 的內部編組流調用,用于實現 RMI 參數 
    和返回值類型的動態類加載。但為了模擬 RMI 的類加載行為,也可由應用程序 
    直接對其進行調用。RMIClassLoader 類沒有可以公共訪問的構造函數,因此無 
    法實例化。 

    package java.rmi.server; 

    public class RMIClassLoader

        public static String getClassAnnotation(Class cl); 
        public static Object getSecurityContext(ClassLoader loader); 
        public static Class loadClass(String name) 
            throws java.net.MalformedURLException, ClassNotFoundException; 
        public static Class loadClass(String codebase, String name) 
            throws java.net.MalformedURLException, ClassNotFoundException; 
        public static Class loadClass(URL codebase, String name) 
            throws java.net.MalformedURLException, ClassNotFoundException; 


    getClassAnnotation 方法將返回一個 String,該 String 代表網絡 
     codebase 路徑,遠程端點通過此路徑下載指定類的定義。RMI 運行時在內部 
    編組流中將使用由該方法返回的 String 對象作為類描述符的注解。該  
    codebase 字符串的格式是由空格界定的 codebase URL 字符串路徑。  
    返回的 codebase 字符串將依賴于所提供類的類加載器: 

    如果類加載器是下列之一:  
    “系統類加載器”(用于加載應用程序“類路徑”中指定的類并從方法 
     ClassLoader.getSystemClassLoader 返回的類加載器),  
    “系統類加載器”的父類,例如用于已安裝方式擴展的類加載器,  
    空值(用于加載虛擬機類的“自舉類加載器”),<  
    則返回 java.rmi.server.codebase 屬性的值。如果該屬性未設置則返回值為 
     null。  
    否則,如果類加載器是類 java.net.URLClassLoader 的實例,則返回的 
     codebase 字符串是一個以空格間隔的外部形式的 URL 列表,它由調用類加載 

    器上的 getURLs 方法返回。 如果 URLClassLoader 由 RMI 運行時創建用來 
    服務于一個 RMIClassLoader.loadClass 方法的調用,則無需任何許可就可獲 
    得相關的 codebase 字符串。 如果它是一個任意的 URLClassLoader 實例, 
    則調用程序必須擁有權限去連接 codebase 路徑中所有的 URL,在每個由  
    getURLs 方法返回的 URL 實例上調用 openConnection().getPermission() 
     來決定權限。  
    最后,如果類加載器不是 URLClassLoader 的實例,則
        java.rmi.server.codebase 
     屬性值被返回,如果屬性值未設置,則返回 null。  
    因為 getSecurityContext 方法不再適用于 JDK1.2 安全模型,所以不鼓勵使 
    用它;它用于 JDK1.1 內部,用來實現基于類加載器的安全檢查。 如果指定的 

    類加載器是由 RMI 運行時創建用來服務于一個 RMIClassLoader.loadClass  
    方法的調用,則返回類加載器 codebase 路徑中第一個 URL;否則返回 null。 

    這三種 loadClass 方法都試圖通過使用當前線程的上下文類加載器,利用指定 
    的名稱加載類并且在設有安全管理器時為特定 codebase 路徑加載內部的  
    URLClassLoader: 

    只帶一個參數(類 name)的 loadClass 方法隱式使用  
    java.rmi.server.codebase 屬性值作為 codebase 路徑。我們不鼓勵使用該 
    版的 loadClass 方法,因為我們已不再鼓勵使用 java.rmi.server.codebase  
    屬性。用戶應使用下列更通用的版本。  
    帶有 String codebase 參數的 loadClass 方法將它用作 codebase 路徑; 
    codebase 字符串必須是以空格間隔的其形式和 getClassAnnotation 方法返 
    回的相同 URL 列表。  
    帶有 java.net.URL codebase 參數的 loadClass 方法將單個 URL 用作  
    codebase。  
    對于所有 loadClass 方法,codebase 路徑將與當前線程的上下文類加載器 
    (通過在當前線程上調用 getContextClassLoader 來確定)一起使用,以確 
    定試圖用來加載類的內部類加載器實例。RMI 運行時將維持一個內部類加載器 
    實例表,以父類加載器和加載器的 codebase 路徑(一個有序 URL 列表)作為 
    鍵值。loadClass 方法以所需的 codebase 路徑和當前線程的上下文類加載器 
    為其父類,在表中查詢 URLClassLoader 實例。如果不存在該加載器,就會創 
    建一個并添加到表中。最后,將在所選類加載器上用指定的類 name 調用 
     loadClass 方法。  

    如果設有安全管理器(System.getSecurityManager 不返回 null),則  
    loadClass 的調用程序必須擁有能連到 codebase 路徑中所有 URL 的權限。 
    否則將拋出異常 ClassNotFoundException。為防止不受信任的代碼被加載到 
    沒有安全管理器的 Java 虛擬機中,在未設置安全管理器的情況下,所有  
    loadClass 方法都應忽略特定的 codebase 路徑,而只加載當前線程上下文類 
    加載器中指定 name 的類。 

    5.7 LoaderHandler 接口  
    package java.rmi.server; 

    public interface LoaderHandler


        Class loadClass(String name) 
            throws MalformedURLException, ClassNotFoundException; 
        Class loadClass(URL codebase,String name) 
            throws MalformedURLException, ClassNotFoundException; 
        Object getSecurityContext(ClassLoader loader); 



    -------------------------------------------------------------- 
    注意 - JDK1.2 中不鼓勵使用 LoaderHandler 接口。  
    -------------------------------------------------------------- 
    LoaderHandler 接口僅由 JDK1.1 的內部 RMI 實現使用。 


    5.8 RMI 套接字工廠  
    當 RMI 運行時實現需要 java.net.Socket 和 java.net.ServerSocket 的實 
    例以用于連接時,它并非直接實例化這些類的對象,而是在當前
        RMISocketFactory  
    對象(該對象由靜態方法 RMISocketFactory.getSocketFactory 返回)上調 
    用 createSocket 和 createServerSocket 方法。這將使應用程序可以用鉤子 
    來自定義 RMI 傳輸所用的套接字類型,例如 java.net.Socket 和  
    java.net.ServerSocket 類的子類。所用的 RMISocketFactory 實例可由可 
    信任的系統代碼設置一次。在 JDK 1.1 中,這種自定義被限制為關于套接字類 
    型的相對全局的決策,因為提供給工廠方法的參數只有主機和端口(對于  
    createSocket)及端口號(對于 createServerSocket)。 

    在 JDK 1.2 中,我們引入了新的接口 RMIServerSocketFactory 和  
    RMIClientSocketFactory,可更加靈活地自定義與遠程對象通訊所用的協議。  


    為使使用 RMI 的應用程序能利用這些新的套接字工廠接口,我們在  
    UnicastRemoteObject 和 java.rmi.activation.Activatable 中添加了幾 
    個新構造函數和 exportObject 方法,它們使用客戶機和服務器套接字工廠做 
    為附加參數。 

    由新構造函數或 exportObject 方法(以 RMIClientSocketFactory 和  
    RMIServerSocketFactory 為參數)導出的遠程對象將被 RMI 運行時區別對待 
    。在這種遠程對象的生命期內,運行時將用自定義 RMIServerSocketFactory  
    來創建 ServerSocket 以接受對遠程對象的到來的調用,同時用自定義  
    RMIClientSocketFactory 來創建 Socket 以連接客戶機和遠程對象。 

    由自定義套接字工廠導出的遠程對象 stub 和 skeleton 所用的 RemoteRef  
    和 ServerRef 實現分別是 UnicastRef2 和 UnicastServerRef2。UnicastRef2  
    類型的線表示法包含與 UnicastRef 類型不同的聯系“端點”的表示法(僅用 
    一個 UTF 格式的主機名字符串,后跟一個整型端口號表示)。對于  
    UnicastRef2,該端點的線表示則包括一個格式字節,用來指定端點表示的其余 
    內容(允許將來擴充),后跟的是指定格式的數據。當前,這些數據可包含  
    UTF 格式的主機名、端口號及可選的(由端點格式字節指定) 
    RMIClientSocketFactory 對象序列化表示。它可被客戶機用于在該端點生成 
    到遠程對象的套接字連接。端點表示不包括在遠程對象導出時指定的  
    RMIServerSocketFactory 對象。 

    當通過 UnicastRef2 類型的引用進行調用時,運行時將在創建遠程對象的套 
    接字連接時使用端點中 RMIClientSocketFactory 對象的 createSocket 方 
    法。同樣,當運行時為了特定遠程對象進行 DGC "dirty" 和 "clean" 調用 
    時,它必須在遠程虛擬機上調用 DGC,方法是使用遠程引用中指定的同一  
    RMIClientSocketFactory 對象所生成的連接。服務器端的 DGC 實現應負責 
    驗證結果是否正確。 

    如果遠程對象是由老的構造函數或 UnicastRemoteObject 中沒有將自定義套 
    接字工廠作為參數的方法導出,則和以前一樣擁有 UnicastRef 和  
    UnicastServerRef 類型的 RemoteRef 和 ServerRef,并且其端點也將使用 
    老式線表示,即一個 UTF 格式的主機字符串跟一個指定端口號的整數。這樣那 
    些不使用 JDK 1.2 新特性的 RMI 服務器可以與老式 RMI 客戶機進行互操作。 

    5.8.1 RMISocketFactory 類  
    java.rmi.server.RMISocketFactory 抽象類提供一個接口來指定傳輸中如何 
    獲得套接字。注意,下面的類使用 java.net 包中的 Socket 和 ServerSocket。 

    package java.rmi.server; 
    public abstract class RMISocketFactory 
    implements RMIClientSocketFactory, RMIServerSocketFactory 


        public abstract Socket createSocket(String host, int port) 
            throws IOException; 
        public abstract ServerSocket createServerSocket(int port) 
            throws IOException; 
        public static void setSocketFactory(RMISocketFactory fac) 
            throws IOException; 
        public static RMISocketFactory getSocketFactory(); 
        public static void setFailureHandler(RMIFailureHandler fh); 
        public static RMIFailureHandler getFailureHandler(); 



    靜態方法 setSocketFactory 可用于設置套接字工廠,而 RMI 將從中獲得套接字 
    。應用程序用自己的實例 RMISocketFactory 僅能調用該方法一次。例如,應用 
    程序定義的 RMISocketFactory 實現在所要求的連接上做一些基本的過濾并拋出 
    異常,或者返回其對 java.net.Socket 或 java.net.ServerSocket 類的擴展( 
    例如提供安全信道的擴展)。注意,只有在當前安全管理器允許設置套接字工廠 
    時才可設置 RMISocketFactory。如果不允許進行該項設置,則將拋出 Security 
    Exception。 

    靜態方法 getSocketFactory 返回由 RMI 使用的套接字工廠。如果未設置套接字 
    工廠,則返回值為 null。 

    當傳輸需要創建套接字時,傳輸層將在 getSocketFactory 方法返回的 RMISock 
    etFactory 上調用 createSocket 和 createServerSocket 方法。例如: 

    RMISocketFactory.getSocketFactory().createSocket(myhost, myport) 

    方法 createSocket 應創建一個連接到指定 host 和 port 的客戶機套接字。 c 
    reateServerSocket 方法應在指定 port 上創建服務器套接字。  

    缺省的 RMISocketFactory 傳輸實現使用 HTTP 通過防火墻提供透明的 RMI,如 
    下所述: 

    在 createSocket 中,工廠將自動嘗試與無法用套接字直接聯系的主機建立
    HTTP 連接。  
    在 createServerSocket 中,工廠將返回用于自動檢測新接受的連接是否為 HTT 
    P POST 請求的服務器套接字。如果是,則返回僅將請求主體透明地展示給傳輸然 
    后將其輸出格式化為 HTTP 響應的套接字。  
    方法 setFailureHandler 設置失敗句柄。在創建服務器套接字失敗時,該句柄將 
    由 RMI 運行時調用。該句柄返回一個布爾值,用于指示是否應重試。缺省的失敗 
    句柄返回值為 false,意味著缺省情況下運行時將不再嘗試創建套接字。 

    方法 getFailureHandler 在套接字創建失敗時返回當前句柄。失敗句柄未設置時 
    將為 null。 

    5.8.2 RMIServerSocketFactory 接口  
    為了支持與遠程對象的自定義通信,可以在導出遠程對象時為其指定一個 RMISe 
    rverSocketFactory 實例。這一點既可通過相應的 UnicastRemoteObject 構造函 
    數或 exportObject 方法完成,也可通過相應的 java.rmi.activation.Activat 
    able 構造函數或 exportObject 方法完成。如果該服務器套接字工廠在導出遠程 
    對象時與之關聯,則 RMI 運行時將使用遠程對象的服務器套接字工廠來創建 Se 
    rverSocket(使用 RMIServerSocketFactory.createServerSocket 方法),以接 
    受遠程客戶機的連接。 

    package java.rmi.server; 
    public interface RMIServerSocketFactory


        public java.net.ServerSocket createServerSocket(int port) 
            throws IOException; 


    5.8.3 RMIClientSocketFactory 接口  
    要自定義與遠程對象的通信,可在導出時遠程對象為其指定一個 RMIClientSock 
    etFactory 的實例。這一點既可通過相應的 UnicastRemoteObject 構造函數或  
    exportObject 方法完成,也可通過相應的 java.rmi.activation.Activatable  
    構造函數或 exportObject 方法完成。如果該客戶機套接字工廠在導出遠程對象 
    時與之相關聯,則客戶機套接字工廠將同遠程對象的引用一起下載到遠程虛擬機 
    。隨后,RMI 運行時將使用 RMIClientSocketFactory.createSocket 方法來建立 
    從客戶機到遠程對象的連接。 

    package java.rmi.server; 
    public interface RMIClientSocketFactory

        public java.net.Socket createSocket(String host, int port) 
        throws IOException; 


    5.9 RMIFailureHandler 接口  
    java.rmi.server.RMIFailureHandler 接口提供一種方法指明服務器套接字創建 
    失敗時指定 RMI 運行時如何響應(除非對象正在導出)。 

    package java.rmi.server; 

    public interface RMIFailureHandler

        public boolean failure(Exception ex); 


    當出現了防止 RMI 運行時創建 java.net.Socket 的異常時將調用 failure 方法 
    。如果運行時試圖重試,則該方法返回值為 true;否則將返回 false。 

    調用該方法前,需要通過調用 RMISocketFactory.setFailureHandler 來注冊失 
    敗句柄。如果該句柄未設置,則 RMI 運行時等待片刻后嘗試再創建 ServerSock 
    et。  

    注意,當 ServerSocket 首次導出對象時如果創建 ServerSocket 失敗,就不會 
    調用 RMIFailureHandler。而當 ServerSocket 接受請求失敗后再創建該 Serve 
    rSocket 時,即調用 RMIFailureHandler。 

    5.10 LogStream 類  
    類 LogStream 提供一種記錄錯誤的機制。對系統進行監控的人可能會對這些錯誤 
    感興趣。該類在內部用于日志服務器調用。 

    package java.rmi.server; 

    public class LogStream extends java.io.PrintStream

        public static LogStream log(String name); 
        public static synchronized PrintStream getDefaultStream(); 
        public static synchronized void setDefaultStream( 
        PrintStream newDefault); 
        public synchronized OutputStream getOutputStream(); 
        public synchronized void setOutputStream(OutputStream out); 
        public void write(int b); 
        public void write(byte b[], int off, int len); 
        public String toString(); 
        public static int parseLevel(String s); 
        // 日志等級常數 
        public static final int SILENT  = 0; 
        public static final int BRIEF   = 10; 
        public static final int VERBOSE = 20; 


    ---------------------------------------------------------------------- 
    ---------- 
    注意 -JDK1.2 中不鼓勵使用 LogStream 類 
    ---------------------------------------------------------------------- 
    ---------- 

    方法 log 返回由給定名稱標識的 LogStream。如果某名稱所對應的日志不存在, 
    即創建一個使用缺省流的日志。 

    方法 getDefaultStream 返回用于新日志的當前缺省流。 

    方法 setDefaultStream 為新日志設置缺省流。 

    方法 getOutputStream 返回當前日志輸出到的流。 

    方法 setOutputStream 設置日志的輸出流。 

    方法 write 的第一種形式將向該流寫一個字節數據。如果不是新起一行,則將把 
    該字節添加到內部緩沖區。如果是新起一行,則當前緩沖區中的行將按相應的日 
    志前綴發送到日志的輸出流中。方法 write 的第二種形式將寫字節子數組。 

    方法 toString 以字符串形式返回日志名。 

    方法 parseLevel 將日志等級的字符串名轉換為內部整型表示。 

    5.11 stub 和 skeleton 編譯器  
    rmic 的 stub 和 skeleton 編譯器用于為特定的遠程對象實現編譯相應的 stub 
     和 skeleton。該編譯器將由遠程對象類的類全名調用。該類必須在先前已成功 
    編譯過。 

    導入類的位置由環境變量 CLASSPATH 或參數 -classpath 指定。  
    除非指定參數 -d,否則編譯好的類文件將放在當前目錄下。  
    參數 -keepgenerated (或 -keep)為 stub 和 skeleton 保留生成的 java 源 
    文件。  
    也可指定 stub 協議的版本:  
     -  -v1.1 創建符合 JDK 1.1 stub 協議版本的 stub/skeleton  
     -  -vcompat(JDK 1.2 中為缺省值)創建同時兼容 JDK 1.1 和 1.2 stub 協議 
    版本的 stub/skeleton  
     -  -v1.2 創建僅符合 JDK 1.2 stub 協議版本的 stub(注意,JDK 1.2 stub  
    協議中并不需要 skeleton)  

    -show 選項為程序顯示一個圖形用戶界面。  
    大多數 javac 命令行參數均可用(-O 除外)且可與 rmic 一起使用:  
     -  -g 生成調試信息  
     -  -depend 反復編譯過期文件  
     -  -nowarn 不生成警告信息  
     -  -verbose 輸出有關編譯器所執行的操作的消息  
     -  -classpath <path> 指定查找輸入源及類文件的位置  
     -  -d <directory> 指定放置生成類文件的位置  
     -  -J< runtime flag> 將參數傳給 java 解釋器 

    凡是有該標志的文章,都是該blog博主Caoer(草兒)原創,凡是索引、收藏
    、轉載請注明來處和原文作者。非常感謝。

    posted on 2005-12-14 13:13 草兒 閱讀(1698) 評論(0)  編輯  收藏 所屬分類: Java編程經驗談
    主站蜘蛛池模板: 国产v片免费播放| 特色特黄a毛片高清免费观看| 亚洲成人中文字幕| 亚洲AV无码专区在线播放中文| 亚洲综合最新无码专区| 久久亚洲国产成人影院网站| 亚洲精品网站在线观看不卡无广告| 四虎免费影院4hu永久免费| 亚洲AV网站在线观看| 日产国产精品亚洲系列| 亚洲国产成人VA在线观看| 亚洲精品无码av天堂| 国产亚洲精品福利在线无卡一| 亚洲午夜久久久久久久久久 | 亚洲欧美国产精品专区久久| 亚洲一卡2卡三卡4卡无卡下载| 久久亚洲精品国产精品婷婷| 亚洲成a人片在线观看天堂无码 | 国产亚洲AV手机在线观看| 亚洲国产三级在线观看| 91亚洲精品第一综合不卡播放| 亚洲日产2021三区| 亚洲一区二区三区在线观看网站| 国产精品亚洲av色欲三区| 午夜在线免费视频 | h在线看免费视频网站男男| 99re6在线精品免费观看| 久久综合国产乱子伦精品免费| 国产在线jyzzjyzz免费麻豆| 岛国av无码免费无禁网站| 在线免费观看污网站| 亚洲日本韩国在线| 亚洲AV一宅男色影视| 亚洲综合伊人制服丝袜美腿| 亚洲AV无码之国产精品| 久久久受www免费人成| 成人浮力影院免费看| 国产特级淫片免费看| 亚洲午夜久久久久久久久电影网 | 免费a级毛片网站| 亚洲国产精品无码AAA片|