java.rmi.UnmarshalException:无法拉服务器的客户端类

问题描述:

我有两台机器上的RMI客户端/服务器设置,在服务器不需要客户端定义的类的简单情况下工作正常。但是,当我需要使用客户端定义的类时,我无法让服务器解组这些类。我怀疑这是我的java.rmi.server.codebase属性的一个问题,我将其作为参数传递给客户端应用程序。我遵循了Sun的RMI教程轨迹,我认为我完全遵循了这些步骤,只是在执行客户端和服务器时没有指定类路径参数,因为它们在根目录包目录上方的目录中执行(但是我也尝试过影响)。java.rmi.UnmarshalException:无法拉服务器的客户端类

例外,我得到试图执行详细介绍了不同的客户端组合时,下面都是一样的:

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如下:默认端口1099上

1日开始登记:

venice% rmiregistry &

2上端口启动web服务器2001指向代码库的通用接口:

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

3开始所注册的服务器对象的服务器应用程序(在测试/ 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试#1使用http主机名

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当我将服务器上的客户端类放在服务器的类路径中时,它们都执行正常。

所有帮助表示赞赏。

+0

我尝试了客户端类捆绑成一个jar文件,但是,这并不工作,要么: '$那不勒斯的java -Djava.rmi.server.codebase =文件:/用户/安卓/开发/ Java/workspace/epsilon/bin/client.jar -Djava.security.policy = client.policy test.myRmi myhostname' 另外,我切换了两台机器的角色,但结果是一样的。 – andrewz 2009-12-14 02:04:58

+0

如果我使用mac作为服务器和ubuntu作为客户端,但只有当两者都运行引用各自代码库的Web服务器时,我的设置才能正常工作,并且我使用http地址作为代码库。所以这一定是mac os网络权限问题,我相信。 – andrewz 2009-12-14 03:02:42

你真的需要使用RMI吗?我和一个朋友在学校尝试过一次,它的速度是慢,比我们之前做的简单的ObjectOutputStream网络慢得多。

+0

感谢您的建议,我会尝试一下。 – andrewz 2009-12-14 00:01:38

我强烈同意乍得Okere的说,RMI真的很慢,消耗资源。有时直接使用套接字可能是简单而有用的选择,关于你的异常你可以确认你的rmi服务器工作正常吗? http://www.javarmi.com/2010/05/java-rmi-error-unmarshalling-arguments/也许是可以帮助你