2010-07-11 65 views
1

我成功創建了RMI服務和客戶端。我可以調用方法等。但是現在我想嘗試以下方法:我想要一個像LinkedList這樣的標準Java對象託管在服務上。 另外,我想'假裝'我已經有了使用LinkedList的現有代碼。我想要的是獲得一個實際由服務管理的LinkedList,但我可以像訪問一個普通的LinkedList一樣訪問本地。最重要的是,我想做一些最小化的日誌記錄,就像調用.add()一樣,它會在服務器上寫入:「添加調用」。Java RMI:如何傳遞POJO

這不是爲了生產,只是爲了幫助我理解它是如何工作的!

到目前爲止,我已經嘗試了很多東西。最有前途的是我創建了一個擴展LinkedList並實現Remote的類。該類試圖將自身與構造註冊表這樣註冊:

try {

UnicastRemoteObject.exportObject((Remote)this); Naming.rebind("theList", (Remote)this); } catch (Exception e) { System.out.println("fail"); System.out.println(e.getMessage()); }

我必須這樣做,因爲我需要延長的LinkedList,所以我不能繼承UnicastRemoteObject。

輸出我得到的,當我嘗試運行此,在服務器端:

 
fail 
Connection refused to host: 192.168.178.27; nested exception is: 
java.net.ConnectException: Connection refused 

而且在客戶端:

 
java.lang.ClassCastException: MyList_Stub cannot be cast to java.util.LinkedList 
at $Proxy0.createList(Unknown Source) 
at RemoteProgram.main(RemoteProgram.java:27) 

提前感謝!

回答

2

你要做的是非常低效,不是一個好主意。基本上,您可以發送任何可以序列化的方法調用。如果你想獲得良好的性能,我建議你只有一個代表你的服務的遠程對象,並作爲你需要的所有服務的外觀(每個遠程對象產生單獨的文件描述符,因此通常有很多遠程對象不是一個好主意)。另外,如果您經常添加和刪除對象,那麼每次添加或刪除元素時都會發送消息,這並不合理。我建議有以下兩個非常簡單的方法,一個單一的遠程對象:

LinkedList retrieveLinkedListByName(String); 
boolean commitNewVersionOfLinkedListByName(String,LinkedList); 

在應用程序啓動時,您可以下載鏈接的列表,然後定期和在應用程序退出,您可以發送回鏈接名單。每次向鏈表添加或刪除元素時,使用網絡應該會更有效。只要LinkedList的元素是可序列化的,你就不需要做任何魔術(比如擴展遠程)來發送它。

+0

嘿邁克爾,謝謝你的迴應。但我只是試圖理解這些概念。我指定它的方式 - 你將如何去做,以便每次改變它都被傳送到服務器,儘管效率很低? – partel 2010-07-11 12:07:19

2
java.lang.ClassCastException: MyList_Stub cannot be cast to java.util.LinkedList 
at $Proxy0.createList(Unknown Source) 
at RemoteProgram.main(RemoteProgram.java:27) 

LinkedList是一個具體類,RMI與接口一起工作,因此您應該將其轉換爲客戶端的List接口。

+0

...至於連接被拒絕的異常,我首先看看你正在使用的安全策略(假設沒有像防火牆這樣的外部問題)。 – darri 2010-07-11 11:47:11

0

同意其他海報,這是一個非常低效的設計。

至於你的例外情況,我不知道你怎麼能在服務器中得到'連接被拒絕'並且仍然能夠運行客戶端。您需要發佈堆棧跟蹤。