Java遠端呼叫
主要參考
http://www.kaixinwenda.com/article-yxc135-7690958.html
http://bbs.chinaunix.NET/thread-1179312-1-1.html
Java 遠端處理
Java遠端方法呼叫(RMI)提供了Java程式語言的遠端通訊功能,這種特性使客戶機上執行的程式可以呼叫遠端伺服器上的物件,使Java程式設計人員能夠在網路環境中分佈操作。
建立一個簡單的Java分散式遠端方法呼叫程式可以按以下幾個步驟操作,
一、定義遠端介面:
在 Java 中,遠端物件是實現遠端介面的類的例項, 遠端介面宣告每個要遠端呼叫的方法。在需要建立一個遠端物件的時候,我們通過傳遞一個介面來隱藏基層的實施細節,客戶通過介面控制程式碼傳送訊息即可。
遠端介面具有如下特點:
1) 遠端介面必須為public屬性。如果不這樣,除非客戶端與遠端介面在同一個包內,否則 當試圖裝入實現該遠端介面的遠端物件時,呼叫會得到錯誤結果。
2) 遠端介面必須擴充套件介面java.rmi.Remote。
3) 除與應用程式本身特定的例外之外,遠端介面中的每個方法都必須在自己的throws從句中 宣告java.rmi.RemoteException。(或 RemoteException 的父類)。
4) 作為引數或返回值傳遞的一個遠端物件(不管是直接,還是本地物件中嵌入)必須宣告為遠 程介面,而不應宣告為實施類。
下面是遠端介面的定義
- 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;
- }
二、實現遠端介面:
遠端物件實現類必須擴充套件遠端物件java.rmi.UnicastRemoteObject類,並實現所定義的遠端介面。遠端物件的實現類中包含實現每個遠端介面所指定的遠端方法的程式碼。這個類也可以含有附加的方法,但客戶只能使用遠端介面中的方法。因為客戶是指向介面的一個控制程式碼,而不是它的哪個類。必須為遠端物件定義建構函式,即使只准備定義一個預設建構函式,用它呼叫基礎類建構函式。因為基礎類建構函式可能會丟擲 java.rmi.RemoteException,所以即使別無它用必須丟擲java.rmi.RemoteException例外。
以下是遠端物件實現類的宣告:
- 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 方法的類可以是實現類自身,也可以完全是另一個類。下面通過RmiSampleServer 來建立一個遠端物件的例項,並通過java.rmi.registry.LocateRegistry類的createRegistry 方法從指定埠號啟動註冊服務程式,也可以通過執行 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方法來構造註冊服務程式 stub 程式例項,二是呼叫伺服器遠端物件上的遠端方法。
以下是客戶端類的宣告:
- 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下開發,對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時,出現的問題很蹊蹺,網上也搜不到:
error: ./test/FibImp.class 中的類檔案格式無效。 major.minor 版本 "51.0" 太新,此工具無法識別。
error: 未找到類 test.FibImp。
這類錯誤出現的原因是: major.minor 就像是我們可以這麼想像,同樣是微軟體的程式,32 位的應用程式不能拿到 16 位系統中執行那樣。
參見 http://www.blogjava.Net/Jay2009/archive/2009/04/23/267108.html
好吧,那就再換一臺linux伺服器
編譯就有問題,應該是環境變數的問題,在javac 之後新增 -classpath . 即可
javac -classpath . testClient/FibClient.java
生成存根
rmic -classpath . test.FibImp
在執行程式的時候也要在java 後面新增-classpath .
相關文章
- java遠端呼叫(rmi)常見的兩個錯誤Java
- Metasploit遠端呼叫Nessus出錯
- 遠端呼叫 - spring+rmiSpring
- 分散式系統:遠端呼叫分散式
- java通過url呼叫遠端介面返回json資料JavaJSON
- bbossaop遠端服務介紹-遠端服務呼叫例項
- RCF--RPC(遠端呼叫框架)RPC框架
- 遠端呼叫中介軟體(RPC)RPC
- RabbitMQ 入門 - 遠端呼叫 (RPC)MQRPC
- dubbo 遠端服務無法呼叫
- 怎麼跨App 遠端呼叫EJBAPP
- Google遠端過程呼叫-GRPCGoRPC
- 本地MinIO儲存服務Java遠端呼叫上傳檔案Java
- SmartRoute之遠端介面呼叫和負載負載
- 呼叫遠端procedure的2個問題
- RPC(遠端過程呼叫)詳解RPC
- SpringCloud(一)微服務遠端呼叫 -- RestTemplateSpringGCCloud微服務REST
- Java RMI遠端方法呼叫詳解Java
- bbossaop遠端服務介紹-點對點遠端服務呼叫和組播服務呼叫的區別
- phpcms—— 內容中的附件呼叫和新增遠端地址的呼叫PHP
- 徒手擼框架--實現 RPC 遠端呼叫框架RPC
- Storm系列(五)DRPC實現遠端呼叫ORMRPC
- ABAP FUNCTION 遠端呼叫的一個引數Function
- 在客戶端儲存對EJB的遠端呼叫是否可行?客戶端
- dubbo原始碼解析(三十)遠端呼叫——rest協議原始碼REST協議
- (2)什麼是服務拆分和遠端呼叫
- Android程式使用SOAP呼叫遠端WebService服務AndroidWeb
- struts工程呼叫遠端EJB元件時怎麼部署元件
- 遠端呼叫procedure可能會有一些缺陷!
- 在Java中實現遠端方法呼叫(轉)Java
- dubbo原始碼解析(三十二)遠端呼叫——thrift協議原始碼協議
- dubbo原始碼解析(三十一)遠端呼叫——rmi協議原始碼協議
- rabbitmq中文教程python版 - 遠端過程呼叫MQPython
- 如果呼叫遠端遠端url介面為https,且存在客戶端證書驗證,如何在客戶端處理HTTP客戶端
- Java高效開發-遠端debugJava
- java Remote Debug(遠端除錯)JavaREM除錯
- java遠端提交表單問題Java
- Java-呼叫R語言和呼叫Python(前後端展示)JavaR語言Python後端