簡體   English   中英

java.rmi.UnmarshalException:無法通過服務器提取客戶端類

[英]java.rmi.UnmarshalException: unable to pull client classes by server

我在兩台機器上都有一個RMI客戶端/服務器設置,在服務器不需要客戶端定義類的簡單情況下,它可以很好地工作。 但是,當我需要使用在客戶端定義的類時,無法使服務器取消編組這些類。 我懷疑這是我將java.rmi.server.codebase屬性作為參數傳遞給客戶端應用程序的問題。 我遵循了Sun的RMI Tutorial跟蹤,我認為我完全遵循了這些步驟,只是在執行客戶端和服務器時沒有指定classpath參數,因為它們在根包目錄正上方的目錄中執行(但是我也嘗試這樣做,沒有影響)。

我在嘗試執行下面詳細描述的不同客戶端組合時遇到的異常都是相同的:

RmiServer exception: java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: java.lang.ClassNotFoundException: test.MyTask at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:353) at sun.rmi.transport.Transport$1.run(Transport.java:177) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.Transport.serviceCall(Transport.java:173) at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:553) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:808) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:667) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) at java.lang.Thread.run(Thread.java:636) at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:255) at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:233) at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:142) at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:178) at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:132) at $Proxy0.execute(Unknown Source) at test.myClient.main(myClient.java:32)

詳細信息是:

我的客戶端/服務器rmi是通過路由器后面的家庭網絡設置的。 路由器被分配了一個靜態IP地址,我將其稱為myhostname 在指向正確機器的路由器中設置了適當的端口映射。

角色,機器,操作系統,IP地址:

server, venice, linux ubuntu 9.10, 10.0.1.2
client, naples, mac os x leopard, 10.0.1.4

我在/home/andrews/workspace/epsilon/bin內按以下方式啟動服務器端:

1個默認端口1099上的啟動注冊表:

venice% rmiregistry &

2在端口2001上啟動Web服務器,指向通用接口的代碼庫:

venice% java webserver/ClassFileServer 2001 /home/andrew/workspace/epsilon/bin

3個啟動服務器應用程序(test / myServer中的主類),用於注冊服務器對象:

venice% java -Djava.rmi.server.codebase="http://myhostname:2001/" -Djava.security.policy=server.policy -Djava.rmi.server.hostname=myhostname test/myServer &

現在,客戶端位於/Users/andrews/Development/Java/workspace/epsilon/bin

1啟動一個本地Web服務器,該服務器可以將客戶端類服務器提供給服務器(不確定是否需要這樣做,但是我添加了我嘗試過的方法,但仍然沒有成功;我為2001年的venice路由器添加了端口映射功能, 2002年到naples

naples$ java webserver/ClassFileServer 2002 /Users/andrews/Development/Java/workspace/epsilon/bin/

嘗試運行客戶端(注意:我沒有指定-cp參數,因為客戶端在根包目錄的上方執行):

1使用HTTP主機名嘗試#1

naples$ java -Djava.rmi.server.codebase=http://10.0.1.4:2002/ -Djava.security.policy=client.policy test.myClient myhostname

注意1:最后將myhostname參數傳遞給客戶端,以便將其解析為服務器的rmi主機名。

注意2:我也嘗試使用localhost:2002而不是10.0.1.4:2002

注意3:我嘗試使用myhostname:2002因為myhostname已分配給路由器,並且我具有正確的端口映射設置,所以該地址應解析為naples而不是venice

2次嘗試#2:

naples$ java -Djava.rmi.server.codebase=file:/Users/andrews/Development/Java/workspace/epsilon/bin/ -Djava.security.policy=client.policy test.myClient myhostname

注意1:代碼庫的url格式正確,我創建了一個小程序,將當前文件目錄路徑轉換為url,並使用了該程序。 使用file:///Users...具有相同的效果。

其他說明:

1我的服務器和客戶端策略文件正確指定了路徑,因為我已經使用好路徑和壞路徑測試了此設置,並為壞路徑獲取了安全例外

2如果我不使用客戶端定義的對象,客戶端正確連接到服務器並且服務器執行,則此設置有效。

3當我將客戶端類放在服務器的類路徑中的服務器上時,一切正常。

感謝所有幫助。

您真的需要使用RMI嗎? 我和一個朋友試圖在學校的一次,它是緩慢的方式慢得多然后我們早些時候做簡單的ObjectOutputStream聯網。

我非常同意Chad Okere的說法,RMI確實非常緩慢且消耗資源。 有時直接使用Sockets可能是簡單而有用的選擇,關於您的例外情況您能否確認rmi服務器正常工作? http://www.javarmi.com/2010/05/java-rmi-error-unmarshalling-arguments/也許可以幫助您

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM