Java RMI代码库无法正常工作

时间:2014-05-21 22:36:10

标签: java rmi classnotfoundexception codebase

据我所知,我在客户端设置的RMI代码库将传递给服务器。然后,服务器使用此代码库来查找不在服务器类路径中的类。

只要服务器类路径中有所有必需的类,远程方法调用就可以正常工作。然后我尝试从服务器类路径中删除所需的类,并在启动RMI客户端时在codebase属性中指定所需类的新位置。不幸的是,这会给我一个ClassNotFoundException: java.lang.ClassNotFoundException:client.Pi

堆栈追踪:

java.rmi.ServerException: RemoteException occurred in server thread; nested exce
ption is:
java.rmi.UnmarshalException: error unmarshalling arguments; nested excep
tion is:
java.lang.ClassNotFoundException: client.Pi
at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Sou
rce)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Sour
ce)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Unknow
n Source)
at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source)
at sun.rmi.server.UnicastRef.invoke(Unknown Source)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unkn
own Source)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source)
at com.sun.proxy.$Proxy0.executeTask(Unknown Source)
at client.ComputePi.main(ComputePi.java:26)
Caused by: java.rmi.UnmarshalException: error unmarshalling arguments; nested ex
ception is:
java.lang.ClassNotFoundException: client.Pi
at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Sou
rce)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Sour
ce)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.ClassNotFoundException: client.Pi
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.rmi.server.LoaderHandler$Loader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at sun.rmi.server.LoaderHandler.loadClassForName(Unknown Source)
at sun.rmi.server.LoaderHandler.loadClass(Unknown Source)
at sun.rmi.server.LoaderHandler.loadClass(Unknown Source)
at java.rmi.server.RMIClassLoader$2.loadClass(Unknown Source)
at java.rmi.server.RMIClassLoader.loadClass(Unknown Source)
at sun.rmi.server.MarshalInputStream.resolveClass(Unknown Source)
at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
at java.io.ObjectInputStream.readClassDesc(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at sun.rmi.server.UnicastRef.unmarshalValue(Unknown Source)
... 11 more

启动服务器:

C:\TEMP\RMI\RMIDemo\src>java 
-cp C:\Users\samue_000\public_html\classes\compute.jar;C:\TEMP\RMI\RMIDemo\src 
-Djava.security.policy=server.policy 
-Djava.rmi.server.useCodebaseOnly=false  
engine.ComputeEngine

>> ComputeEngine bound

启动客户端

C:\TEMP\RMI\RMIDemo\src>java 
-cp C:\Users\samue_000\public_html\classes\compute.jar;c:\Temp\RMI\RMIDemo\src;c:\temp 
-Djava.security.policy=client.policy 
-Djava.rmi.server.codebase=file:/C:/Users/samue_000/public_html/classes 
client.ComputePi

在客户端的类路径(c:\ temp)中,存在客户端所需的client.Pi类。为了告诉服务器该类所在的位置,我将一个副本放在一个单独的文件夹中,并使用codebase属性指定该文件夹。该类的确切位置是C:/Users/samue_000/public_html/classes/client/Pi.class。 它全部运行在同一台物理机器上(没有vm)。所以我不明白为什么服务器没有从客户端获取代码库并加载所需的client.Pi类。

我已尝试将发布的信息最小化到所需部分,以免过度填充此帖子。如果有更多信息需要帮助我解决这个问题,请告诉我。这让我发疯了。我正在研究这个问题几个小时和几天......

编辑:我使用了与oracle中此article中描述的几乎相同的代码。唯一的区别是我以编程方式创建rmi注册表而不是单独启动注册表。所以代码本身应该没有任何问题。只要Pi类在服务器的类路径中它就可以正常工作。但是只要Pi类只存在于代码库和客户端的类路径中,它就不再起作用了。

3 个答案:

答案 0 :(得分:2)

通常,RMI代码库URL是HTTP URL,它们通常是指JAR文件,而不是目录。

-Djava.rmi.server.codebase=file:/C:/Users/samue_000/pubic_html/classes 

这是一个file:网址,它只能在适用的同一系统上运行。如果服务器位于不同的主机上,那么它就不会成为它的头部或尾部。

然而,由于它全部在同一台机器上,它应该工作。你可以发布远程接口吗?

答案 1 :(得分:0)

最后不要省略/,然后尝试:

-Djava.rmi.server.codebase=file:/C:/Users/samue_000/public_html/classes/ 

答案 2 :(得分:-1)

您可以下载课程文件。但是您需要使用路径分隔符来终止路径。这就是文件说明的内容。 这本来应该是评论,但我失去了对该网站发表评论的权利,直到我达到50点信誉点为止。