Java远程方法调用
主要參考
http://www.kaixinwenda.com/article-yxc135-7690958.html
http://bbs.chinaunix.net/thread-1179312-1-1.html
Java 遠程處理?
Java遠程方法調(diào)用(RMI)提供了Java程序語言的遠程通訊功能,這種特性使客戶機上運行的程序可以調(diào)用遠程服務器上的對象,使Java編程人員能夠在網(wǎng)絡環(huán)境中分布操作。?
創(chuàng)建一個簡單的Java分布式遠程方法調(diào)用程序可以按以下幾個步驟操作,?
?
?一、定義遠程接口:?
在 Java 中,遠程對象是實現(xiàn)遠程接口的類的實例, 遠程接口聲明每個要遠程調(diào)用的方法。在需要創(chuàng)建一個遠程對象的時候,我們通過傳遞一個接口來隱藏基層的實施細節(jié),客戶通過接口句柄發(fā)送消息即可。?
遠程接口具有如下特點:?
1) 遠程接口必須為public屬性。如果不這樣,除非客戶端與遠程接口在同一個包內(nèi),否則 當試圖裝入實現(xiàn)該遠程接口的遠程對象時,調(diào)用會得到錯誤結(jié)果。?
2) 遠程接口必須擴展接口java.rmi.Remote。?
3) 除與應用程序本身特定的例外之外,遠程接口中的每個方法都必須在自己的throws從句中 聲明java.rmi.RemoteException。(或 RemoteException 的父類)。?
4) 作為參數(shù)或返回值傳遞的一個遠程對象(不管是直接,還是本地對象中嵌入)必須聲明為遠 程接口,而不應聲明為實施類。?
下面是遠程接口的定義
package test; import java.rmi.Remote; import java.rmi.RemoteException; import java.math.BigInteger;public interface Fib extends Remote {public int getFib(int n) throws RemoteException; // public BigInteger getFib(BigInteger n) throws RemoteException; }
二、實現(xiàn)遠程接口: ?
遠程對象實現(xiàn)類必須擴展遠程對象java.rmi.UnicastRemoteObject類,并實現(xiàn)所定義的遠程接口。遠程對象的實現(xiàn)類中包含實現(xiàn)每個遠程接口所指定的遠程方法的代碼。這個類也可以含有附加的方法,但客戶只能使用遠程接口中的方法。因為客戶是指向接口的一個句柄,而不是它的哪個類。必須為遠程對象定義構(gòu)造函數(shù),即使只準備定義一個默認構(gòu)造函數(shù),用它調(diào)用基礎類構(gòu)造函數(shù)。因為基礎類構(gòu)造函數(shù)可能會拋出 java.rmi.RemoteException,所以即使別無它用必須拋出java.rmi.RemoteException例外。?
以下是遠程對象實現(xiàn)類的聲明:
package test; import java.math.BigInteger; import java.rmi.*; import java.rmi.server.UnicastRemoteObject;public class FibImp extends UnicastRemoteObject implements Fib {public FibImp() throws RemoteException {super();}public int getFib(int n) throws RemoteException {return n+2;}}
? 三、編寫服務器類: ?
包含 main 方法的類可以是實現(xiàn)類自身,也可以完全是另一個類。下面通過RmiSampleServer 來創(chuàng)建一個遠程對象的實例,并通過java.rmi.registry.LocateRegistry類的createRegistry 方法從指定端口號啟動注冊服務程序,也可以通過執(zhí)行 rmiregistry 命令啟動注冊服務程序,注冊服務程序的缺省運行端口為 1099。必須將遠程對象名字綁定到對遠程對象的引用上: Naming.rebind("//localhost:8808/SAMPLE-SERVER" , Server);?
以下是服務器類的聲明:
package test; import java.net.MalformedURLException; import java.rmi.Naming; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; public class FibonacciServer {/*** @param args*/public static void main(String[] args) {try {LocateRegistry.createRegistry(8804); FibImp f = new FibImp();// 注冊到 registry 中Naming.rebind("//localhost:8804/SAMPLE-SERVER", f);System.out.println("fib server ready");} catch (RemoteException re) {System.out.println("Exception in FibonacciImpl.main: " + re);} catch (MalformedURLException e) {System.out.println("MalformedURLException " + e);}} }
? 四、編寫使用遠程服務的客戶機類:
客戶機類的主要功能有兩個,一是通過Naming.lookup方法來構(gòu)造注冊服務程序 stub 程序?qū)嵗?#xff0c;二是調(diào)用服務器遠程對象上的遠程方法。?
以下是客戶端類的聲明:
package testClient;import test.Fib; import java.math.BigInteger; import java.net.MalformedURLException; import java.rmi.Naming; import java.rmi.NotBoundException; import java.rmi.RemoteException; public class FibClient {/*** @param args*/public static void main(String[] args) {String url = "//localhost:8804/SAMPLE-SERVER";try {Fib calc = (Fib) Naming.lookup(url);for (int i = 0; i < 10; ++i) {int f = calc.getFib(i);System.out.println(f);}} catch (MalformedURLException e) {e.printStackTrace();} catch (RemoteException e) {e.printStackTrace();} catch (NotBoundException e) {e.printStackTrace();}} }
之前一直在eclipse下開發(fā),對java的命令行編譯,運行不是很清楚,下面的編譯耗費了很多時間。
在包外面進行編譯
javac test/*.java
javac testClient/*.java
使用rmic編譯stub文件,在jdk1.5以后,利用java的reflect機制,因此就不會生成skeleton文件了
在windows下
運行rmic -classpath . test.FibImp,即可生成FibImp_Stub.class
在linux總是提示:/test/FibImp.class 中的類文件格式無效。 ?major.minor 版本 "51.0" 太新,此工具無法識別。
還需要排查
啟動rmiregistry
直接輸入rmiregistry即可
運行服務器:
java test.FibonacciServer
運行客戶機:
java testClient.FibClient
下面是用實驗室的Linux服務器的操作過程
一臺服務器編譯沒有問題,但是在rmic生成存根class時,出現(xiàn)的問題很蹊蹺,網(wǎng)上也搜不到:
error: ./test/FibImp.class 中的類文件格式無效。 ?major.minor 版本 "51.0" 太新,此工具無法識別。
error: 未找到類 test.FibImp。
這類錯誤出現(xiàn)的原因是:?major.minor 就像是我們可以這么想像,同樣是微軟件的程序,32 位的應用程序不能拿到 16 位系統(tǒng)中執(zhí)行那樣。
參見 http://www.blogjava.net/Jay2009/archive/2009/04/23/267108.html
好吧,那就再換一臺linux服務器
編譯就有問題,應該是環(huán)境變量的問題,在javac 之后添加?-classpath . 即可
javac -classpath . testClient/FibClient.java?
生成存根
rmic -classpath . test.FibImp
在運行程序的時候也要在java 后面添加-classpath .
總結(jié)
以上是生活随笔為你收集整理的Java远程方法调用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python函数式编程指南
- 下一篇: RMI原理及开发实例