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

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

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

    靈魂-放水

    為學日益,為道日損。

    BlogJava 首頁 新隨筆 聯系 聚合 管理
      296 Posts :: 10 Stories :: 274 Comments :: 0 Trackbacks

    大衛注1

    寫完CORBA系列后,本想接著寫寫其它幾種典型的遠程通信協議:RMIXML-RPCSOAP,但由于工作的原因,加之房子裝修等麻煩事,一直沒有心情動筆。今天接到裝修公司老板電話說開工證要晚幾天辦下來,要停工4-5天,狂怒后突然有了靜下心來完成原本想寫的東西的想法,既來之,則安之(i.e.郁悶啊,郁悶啊,就習慣了...

    大衛注2

    這個系列基本上是一份筆記,沒有加入太多我自己的東西,僅僅記錄了自己在使用過程中遇到的問題,及其解決辦法。

     

    在傳統的RPC編程接口逐漸淡出人們視線的同時,新的、更便于使用且附加了更多特性的RPC編程接口也不斷涌現,CORBA作為分布式對象計算技術的典范,在很長一段時間內極大地吸引了大家的注意,但是由于CORBA規范試圖覆蓋過多的內容,使得CORBA顯得過于復雜,也極大地限制了CORBA的應用范圍,本系列將向大家介紹幾種輕量級的,更適于在Java開發中使用的RPC編程接口:RMIXML-RPCSOAP

    RMIRemote Method Invocation

    與本系列將介紹的其它兩種RPC編程接口不同,RMIRemote Method Invocation)顯得有些老舊,它是在Java-IDL加入J2SE之前被引入的。RMI開發流程與CORBA如出一轍(從出現的時間上無法確定RMI是否是按照CORBA規范定制的),因此,其開發過程相對比較煩瑣,但是由于RMIEJB的基礎,因此,它在Java開發中具有十分重要的地位。

    以下是創建遠程方法調用的5個步驟:

    1.   定義一個擴展了Remote接口的接口,該接口中的每一個方法必須聲明它將產生一個RemoteException異常;

    2.   定義一個實現該接口的類;

    3.   使用rmic程序生成遠程實現所需的存根和框架;

    4.   創建一個客戶程序和服務器進行RMI調用;

    5.   啟動rmiregistry并運行自己的服務程序和客戶程序。

    下面舉一個簡單、而且被無數次引用的例子:Echo

    1、定義Echo接口

    //Echo.java

    //The Echo remote interface

    package demo.rmi;

    import java.rmi.*;

    public interface Echo extends Remote {

          String echo(String msg) throws RemoteException;

    }

    2、實現Echo接口

    //EchoServer.java

    //The implementation of the Echo remote object

    package demo.rmi;

    import java.net.*;

    import java.rmi.*;

    import java.rmi.registry.*;

    import java.rmi.server.*;

    public class EchoServer

          extends UnicastRemoteObject

          implements Echo {

           //默認構件器,也要“擲”出RemoteException違例

          public EchoServer() throws RemoteException {

                super();

          }

          public String echo(String msg) throws RemoteException {

                return "Echo: " + msg;

          }

          public static void main(String [] args) {

                /*創建和安裝一個安全管理器,令其支持RMI作為Java開發包的一部分,適用于RMI唯一一個是RMISecurityManager.*/

                System.setSecurityManager(new RMISecurityManager());

                try {

                         /*創建遠程對象的一個或多個實例,下面是EchoServer對象*/

                      EchoServer es = new EchoServer();

                      /*向RMI遠程對象注冊表注冊至少一個遠程對象。一個遠程對象擁有的方法即可生成指向其他遠程對象的句柄,這樣,客戶到注冊表里訪問一次,得到第一個遠程對象即可.*/

                      Naming.rebind("EchoServer", es);

                      System.out.println("Ready to provide echo service...");

                } catch (Exception e) {

                      e.printStackTrace();

                }

          }

    }

    這個實現類使用了UnicastRemoteObject去連接RMI系統。在我們的例子中,我們是直接的從UnicastRemoteObject這個類上繼承的,事實上并不一定要這樣做,如果一個類不是從UnicastRmeoteObject上繼承,那必須使用它的exportObject()方法去連接到RMI。(否則,運行時將被告知無法序列化。)

    如果一個類繼承自UnicastRemoteObject,那么它必須提供一個構造函數并且聲明拋出一個RemoteException對象(否則,會遇到編譯錯誤)。當這個構造函數調用了super(),它就激活UnicastRemoteObject中的代碼完成RMI的連接和遠程對象的初始化。

    3、運行rmic編譯實現類,產生_Stub

    demo.rmi.EchoServer.java上級目錄下運行如下命令:

    rmic demo.rmi.EchoServer

    4、編寫客戶程序

    //EchoClient.java

    //Uses remote object EchoServer

    package demo.rmi;

    import java.rmi.*;

    import java.rmi.registry.*;

    public class EchoClient {

          public static void main(String [] args) {

                System.setSecurityManager(new RMISecurityManager());

                try {

                      Echo t = (Echo)Naming.lookup("EchoServer");

                      for (int i = 0; i < 10; i++) {

                            System.out.println(t.echo(String.valueOf(i)));

                      }

                } catch (Exception e) {

                      e.printStackTrace();

                }

          }

    }

    5、運行

    編碼的工作就只有這些,現在可以依次啟動rmiregistry(啟動rmiregistry時可以附加一個端口,一般使用默認的端口1099即可,這是默認的Naming Service運行端口)、EchoServerEchoClient了。但是,雖然有些RMI的資料沒有提到,但你運行時不可避免會遇到如下兩個錯誤:

    1java.security.AccessControlException: access denied (java.net.SocketPermission 127.0.0.1:1099 connect,resolve)

    原因很簡單,RMI Server/Client程序試圖通過Socket連接訪問本機的rmiregistry服務(即RMINaming Service,其運行的默認端口是1099)。要解決這個問題,可以在運行Server/Client時指定一個Policy文件(關于Policy的更多信息,見參考2),如下:

    java -Djava.security.policy=demo/rmi/policyfile.txt demo.rmi.EchoServer

    Policy文件的內容為:

    grant{

          permission java.net.SocketPermission "localhost:1099", "connect, resolve";

    };

    即允許訪問本機的1099端口。

    或者干脆來個徹底開放:

    grant {

          permission java.security.AllPermission "", "";

    };

    2java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:

            java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:

            java.lang.ClassNotFoundException: demo.rmi.EchoServer_Stub

            ...

    如果你湊巧用啟動rmiregistry的終端窗口啟動了EchoServer,那么你很走運,你看不到上面的錯誤,但如果你不是在看完這篇文章后就再也用不到RMI,那么,這個錯誤在那里等著你,:)

    錯誤很明顯,rmiregistry找不到與EchoServer放在同一目錄下的EchoServer_Stub,因為package所在demo.rmi目錄的上級目錄不在rmiregistryclasspath中,這個問題有兩種解決方案:

    a)在啟動rmiregistry前先調整一下CLASSPATH環境變量,以目錄E:"為例,執行:

    set CLASSPATH=%CLASSPATH%;E:"

    b)修改code,在EchoServer中通過如下代碼:

    Registry r = LocateRegistry.createRegistry(8111);

    r.rebind("EchoServer", es);

    在程序內部創建一個LocateRegistry,并將自身注冊到該LocateRegistry,其中的數值8111表示LocateRegistry運行的端口。

    同樣,對于客戶程序,也需要作相應的調整:

    Registry r = LocateRegistry.getRegistry("localhost", 8111);

    Echo e = (Echo)r.lookup("EchoServer");

    而不是像上面例子中一樣訪問Naming類的static方法來訪問默認的rmiregistry服務。

    參考:

    1.      Java RMI Tutorial, http://www.ccs.neu.edu/home/kenb/com3337/rmi_tut.html

    2.      Policy Tool - Policy File Creation and Management Tool. http://java.sun.com/j2se/1.4.2/docs/tooldocs/windows/policytool.html

    3.     Java RMI入門實戰,http://www.huihoo.com/java/rmi/index.html
    posted on 2008-03-11 16:13 放水老倌 閱讀(1199) 評論(0)  編輯  收藏 所屬分類: J2EE
    主站蜘蛛池模板: 国产中文在线亚洲精品官网| 成人午夜免费视频| 亚洲爆乳精品无码一区二区三区| 成年女人免费视频播放77777 | 可以免费看黄的网站| 成人免费ā片在线观看| 色五月五月丁香亚洲综合网| 亚洲一区二区三区亚瑟| 亚洲精品国产成人99久久| 久久综合亚洲色HEZYO国产| 日本特黄特色免费大片| 精品久久久久成人码免费动漫 | 久久久久久亚洲AV无码专区| 亚洲人成网站18禁止一区| 日本高清免费网站| a毛片基地免费全部视频| 一区二区三区观看免费中文视频在线播放| 美女视频黄.免费网址 | 国产福利在线观看免费第一福利| 国产一区二区免费| 2022国内精品免费福利视频| 在线观看免费亚洲| 亚洲爆乳少妇无码激情| 亚洲熟妇AV一区二区三区浪潮| 亚洲国产精品成人精品小说| 亚洲午夜精品一区二区 | 国产99久久久国产精免费| 国产成人亚洲毛片| 国产亚洲人成在线播放| 久久亚洲欧美国产精品| 亚洲丁香婷婷综合久久| 亚洲欧美在线x视频| 美女视频黄a视频全免费网站一区| 国产亚洲男人的天堂在线观看| 亚洲欧好州第一的日产suv| 亚洲熟妇丰满xxxxx| 国产精品亚洲AV三区| 色www免费视频| 一进一出60分钟免费视频| 一级毛片在线播放免费| 国产福利免费视频|