Java RMI 代码库不工作

标签 java rmi classnotfoundexception codebase

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

只要服务器类路径中提供了所有必需的类,远程方法调用就可以正常工作。然后,我尝试从服务器类路径中删除所需的类,并在启动 RMI 客户端时在代码库属性中指定所需类的新位置。不幸的是,这会给我一个 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。 它全部运行在同一台物理机上(没有虚拟机)。所以我不明白为什么服务器不从客户端获取代码库并加载所需的 client.Pi 类。

我已尝试将发布的信息最小化为所需部分,以免这篇文章过满。如果需要更多信息来帮助我解决此问题,请告诉我。这让我发疯。我花了几个小时和几天的时间来解决这个问题......

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

最佳答案

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

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

这是一个file: URL,它只能在它所适用的同一系统上工作。如果服务器位于不同的主机上,则不会产生任何影响。

但是,由于它们都在同一台机器上,所以它应该可以工作。可以贴一下远程接口(interface)吗?

关于Java RMI 代码库不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23794997/

相关文章:

java - 从通过 kerberos key 表进行身份验证的 Java 应用程序在远程服务器上执行脚本

java - 将 Spring 与 jsp 结合使用 : RequestMappings

java - 使用端口 1099 的 IntelliJ Idea IDE

java - RMI: java.lang.ClassCastException: com.sun.proxy.$Proxy1 无法转换为 Funktion

java - 静态内部类实例化 - ClassNotFoundException

java - 在使用自定义 genericElement 的情况下如何修复 "No generic element handlers found for namepsace"错误?

java - 将整数添加到链接列表中

java - 如何在 Java 中实现 Marshalling 类?

TomEE 1.6.0.2 上 org.apache.commons.collections4 类的 ClassNotFoundException

java - 启动 tyrus 独立服务器时出现 ClassNotFoundException