posts - 10,comments - 2,trackbacks - 0
          RMI,遠(yuǎn)程方法調(diào)用(Remote Method Invocation)是Enterprise JavaBeans的支柱,是建立分布式Java應(yīng)用程序的方便途徑。RMI是非常容易使用的,但是它非常的強大。
            RMI的基礎(chǔ)是接口,RMI構(gòu)架基于一個重要的原理:定義接口和定義接口的具體實現(xiàn)是分開的。下面我們通過具體的例子,建立一個簡單的遠(yuǎn)程計算服務(wù)和使用它的客戶程序
          一個正常工作的RMI系統(tǒng)由下面幾個部分組成: 
        1. 遠(yuǎn)程服務(wù)的接口定義
        2. 遠(yuǎn)程服務(wù)接口的具體實現(xiàn)
        3. Stub 和 Skeleton 文件
        4. 一個運行遠(yuǎn)程服務(wù)的服務(wù)器
        5. 一個RMI命名服務(wù),它允許客戶端去發(fā)現(xiàn)這個遠(yuǎn)程服務(wù)
        6. 類文件的提供者(一個HTTP或者FTP服務(wù)器)
        7. 一個需要這個遠(yuǎn)程服務(wù)的客戶端程序

        8.   下面我們一步一步建立一個簡單的RMI系統(tǒng)。首先在你的機(jī)器里建立一個新的文件夾,以便放置我們創(chuàng)建的文件,為了簡單起見,我們只使用一個文件夾存放客戶端和服務(wù)端代碼,并且在同一個目錄下運行服務(wù)端和客戶端。
            如果所有的RMI文件都已經(jīng)設(shè)計好了,那么你需要下面的幾個步驟去生成你的系統(tǒng):
            1、  編寫并且編譯接口的Java代碼
            2、  編寫并且編譯接口實現(xiàn)的Java代碼
            3、  從接口實現(xiàn)類中生成 Stub 和 Skeleton 類文件
            4、  編寫遠(yuǎn)程服務(wù)的主運行程序
            5、  編寫RMI的客戶端程序
            6、  安裝并且運行RMI系統(tǒng)

          我的程序是在NetBeans IDE 5.5和JDK1.6下編寫的,當(dāng)然運行是在命令提示符下進(jìn)行的


          1、接口
          第一步就是建立和編譯服務(wù)接口的Java代碼。這個接口定義了所有的提供遠(yuǎn)程服務(wù)的功能,在這里我們所有完成的就是加減乘除,下面是源程序:

          1. package rmiDemo;
          2. //Calculator.java
          3. //define the interface
          4. import java.rmi.Remote;
          5. public interface Calculator extends Remote
          6. {
          7.     public long add(long a, long b) 
          8.         throws java.rmi.RemoteException
          9.     public long sub(long a, long b) 
          10.         throws java.rmi.RemoteException
          11.     public long mul(long a, long b) 
          12.         throws java.rmi.RemoteException
          13.     public long div(long a, long b) 
          14.         throws java.rmi.RemoteException

          注意:這個接口繼承自Remote,每一個定義的方法都必須拋出一個RemoteException異常對象。
          建立這個文件,把它存放在剛才的目錄下,并且編譯。

          2、接口的具體實現(xiàn)

            下一步,我們就要寫遠(yuǎn)程服務(wù)的具體實現(xiàn),這是一個CalculatorImpl類文件:

          1. package rmiDemo;
          2. //CalculatorImpl.java
          3. //Implementation
          4. import java.rmi.server.UnicastRemoteObject;
          5. public class CalculatorImpl extends UnicastRemoteObject implements Calculator 
          6.     // 這個實現(xiàn)必須有一個顯式的構(gòu)造函數(shù),并且要拋出一個RemoteException異常 
          7.     public CalculatorImpl() 
          8.         throws java.rmi.RemoteException { 
          9.         super(); 
          10.     } 
          11.     public long add(long a, long b) 
          12.         throws java.rmi.RemoteException { 
          13.         return a + b; 
          14.     } 
          15.     public long sub(long a, long b) 
          16.         throws java.rmi.RemoteException { 
          17.         return a - b; 
          18.     } 
          19.     public long mul(long a, long b) 
          20.         throws java.rmi.RemoteException { 
          21.         return a * b; 
          22.     } 
          23.     public long div(long a, long b) 
          24.         throws java.rmi.RemoteException { 
          25.         return a / b; 
          26.     } 

            這個實現(xiàn)類使用了UnicastRemoteObject去聯(lián)接RMI系統(tǒng)。在我們的例子中,我們是直接的從UnicastRemoteObject這個類上繼承的,事實上并不一定要這樣做,如果一個類不是從UnicastRmeoteObject上繼承,那必須使用它的exportObject()方法去聯(lián)接到RMI。
            如果一個類繼承自UnicastRemoteObject,那么它必須提供一個構(gòu)造函數(shù)并且聲明拋出一個RemoteException對象。當(dāng)這個構(gòu)造函數(shù)調(diào)用了super(),它久激活UnicastRemoteObject中的代碼完成RMI的連接和遠(yuǎn)程對象的初始化。
          3、Stubs 和Skeletons

            下一步就是要使用RMI編譯器rmic來生成樁和框架文件,這個編譯運行在遠(yuǎn)程服務(wù)實現(xiàn)類文件上。
                 在IDE中build所有程序
            >rmic rmiDemoCalculatorImpl

            在你的目錄下運行上面的命令,成功執(zhí)行完上面的命令你可以發(fā)現(xiàn)一個Calculator_stub.class文件,如果你是使用的Java2SDK,那么你還可以發(fā)現(xiàn)Calculator_Skel.class文件。

            4、主機(jī)服務(wù)器

            遠(yuǎn)程RMI服務(wù)必須是在一個服務(wù)器中運行的。CalculatorServer類是一個非常簡單的服務(wù)器。

          1. package rmiDemo;
          2. //CalculatorServer.java
          3. import java.rmi.Naming;
          4. public class CalculatorServer {
          5.    public CalculatorServer() {
          6.      try {
          7.        Calculator c = new CalculatorImpl();
          8.        Naming.rebind("rmi://localhost:1099/CalculatorService", c);
          9.      } catch (Exception e) {
          10.        System.out.println("Trouble: " + e);
          11.      }
          12.    }
          13.    public static void main(String args[]) {
          14.      new CalculatorServer();
          15.    }
          16. }

            5、客戶端

            客戶端源代碼如下:

          1. package rmiDemo;
          2. //CalculatorClient.java
          3. import java.rmi.Naming
          4. import java.rmi.RemoteException
          5. import java.net.MalformedURLException
          6. import java.rmi.NotBoundException
          7. public class CalculatorClient { 
          8.     public static void main(String[] args) { 
          9.         try { 
          10.             Calculator c = (Calculator)
          11.                            Naming.lookup(
          12.                  "rmi://localhost
          13.                         /CalculatorService"); 
          14.             System.out.println( c.sub(4, 3) ); 
          15.             System.out.println( c.add(4, 5) ); 
          16.             System.out.println( c.mul(3, 6) ); 
          17.             System.out.println( c.div(9, 3) ); 
          18.         } 
          19.         catch (MalformedURLException murle) { 
          20.             System.out.println(); 
          21.             System.out.println(
          22.               "MalformedURLException"); 
          23.             System.out.println(murle); 
          24.         } 
          25.         catch (RemoteException re) { 
          26.             System.out.println(); 
          27.             System.out.println(
          28.                         "RemoteException"); 
          29.             System.out.println(re); 
          30.         } 
          31.         catch (NotBoundException nbe) { 
          32.             System.out.println(); 
          33.             System.out.println(
          34.                        "NotBoundException"); 
          35.             System.out.println(nbe); 
          36.         } 
          37.         catch (
          38.             java.lang.ArithmeticException
          39.                                       ae) { 
          40.             System.out.println(); 
          41.             System.out.println(
          42.              "java.lang.ArithmeticException"); 
          43.             System.out.println(ae); 
          44.         } 
          45.     } 

            保存這個客戶端程序到你的目錄下(注意這個目錄是一開始建立那個,所有的我們的文件都在那個目錄下)。
                   在IDE中build所有程序。
            6、運行RMI系統(tǒng)

            現(xiàn)在我們建立了所有運行這個簡單RMI系統(tǒng)所需的文件,現(xiàn)在我們終于可以運行這個RMI系統(tǒng)啦!來享受吧。

            我們是在命令控制臺下運行這個系統(tǒng)的,你必須開啟三個控制臺窗口,一個運行服務(wù)器,一個運行客戶端,還有一個運行RMIRegistry。

            首先運行注冊程序RMIRegistry,你必須在包含你剛寫的類的那么目錄下運行這個注冊程序。

            >rmiregistry

            好,這個命令成功的話,注冊程序已經(jīng)開始運行了,不要管他,現(xiàn)在切換到另外一個控制臺,在第二個控制臺里,我們運行服務(wù)器CalculatorService,因為RMI的安全機(jī)制將在服務(wù)端發(fā)生作用,所以你必須增加一條安全策略。以下是對應(yīng)安全策略的例子 
          grant {
          permission java.security.AllPermission "", "";
          };

            注意:這是一條最簡單的安全策略,它允許任何人做任何事,對于你的更加關(guān)鍵性的應(yīng)用,你必須指定更加詳細(xì)安全策略。

            現(xiàn)在為了運行服務(wù)端,你需要除客戶類(CalculatorClient.class)之外的所有的類文件。確認(rèn)安全策略在policy.txt文件之后,使用如下命令來運行服務(wù)器。

            > java -Djava.security.policy=C:\Documents and Settings\Administrator\RMI\build\classes\  rmiDemo.CalculatorServer

            這個服務(wù)器就開始工作了,把接口的實現(xiàn)加載到內(nèi)存等待客戶端的聯(lián)接。好現(xiàn)在切換到第三個控制臺,啟動我們的客戶端。

            為了在其他的機(jī)器運行客戶端程序你需要一個遠(yuǎn)程接口(Calculator.class) 和一個stub(CalculatorImpl_Stub.class)。 使用如下命令運行客戶端

             > java -Djava.security.policy=C:\Documents and Settings\Administrator\RMI\build\classes\ rmiDemo. CalculatorClient

            如果所有的這些都成功運行,你應(yīng)該看到下面的輸出:
            1
            9
            18
            3

            

        9. posted on 2007-05-22 20:08 CHUANDAOJUN 閱讀(6545) 評論(2)  編輯  收藏 所屬分類: EJB

          FeedBack:
          # re: RMI基礎(chǔ)教程
          2010-01-30 19:31 | 楊俊華
            > java -Djava.security.policy=C:\Documents and Settings\Administrator\RMI\build\classes\ rmiDemo.CalculatorServer

          這個目錄是怎么來的?

          還有,運行在那個目錄下能不能說一下啊。
          謝謝  回復(fù)  更多評論
            
          # re: RMI基礎(chǔ)教程
          2011-10-31 11:54 | 沈曦
          很好,謝謝。

          有一點需要說明的是:
          運行 rmic 編譯前,需要先編譯 Caculator.java 和 CaculatorImpl.java 文件,并將產(chǎn)生的.class文件置于當(dāng)前目錄,否則會產(chǎn)生“類找補到”的錯誤提示。  回復(fù)  更多評論
            

          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 泗阳县| 塘沽区| 凌海市| 北票市| 颍上县| 璧山县| 封丘县| 安徽省| 宜兰县| 嫩江县| 古丈县| 武威市| 河北省| 临猗县| 常宁市| 屯昌县| 古丈县| 三明市| 敦化市| 延吉市| 洛川县| 沙坪坝区| 长葛市| 乐陵市| 大埔区| 隆回县| 柳林县| 荥经县| 邯郸市| 阳朔县| 阜城县| 聊城市| 陆良县| 沙河市| 阿尔山市| 施秉县| 双柏县| 昂仁县| 乌什县| 柳林县| 娱乐|