2

我使用 java rmi 编写了一个简单的项目并导出到一个可执行的 jar 文件。当我尝试运行它时,有时我会遇到异常,有时它会起作用。当我指定 -Djava.rmi.server.codebase=file:serverClasses/ 时,它似乎没有正确创建 jar 文件。这是堆栈跟踪:

java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
    java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
    java.lang.ClassNotFoundException: com.ServerBootstrap.IServer
    at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:413)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:267)
    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:273)
    at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:251)
    at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:377)
    at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
    at java.rmi.Naming.rebind(Naming.java:177)
    at com.v3q6.eece411.A2.ServerBootstrap.ChatRoomServer.main(ChatRoomServer.java:37)
Caused by: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
    java.lang.ClassNotFoundException: com.ServerBootstrap.IServer
    at sun.rmi.registry.RegistryImpl_Skel.dispatch(Unknown Source)
    at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:403)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:267)
    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)
Caused by: java.lang.ClassNotFoundException: com.ServerBootstrap.IServer
    at java.net.URLClassLoader$1.run(URLClassLoader.java:217)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:323)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:268)
    at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:336)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:264)
    at sun.rmi.server.LoaderHandler.loadProxyInterfaces(LoaderHandler.java:728)
    at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:672)
    at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:609)
    at java.rmi.server.RMIClassLoader$2.loadProxyClass(RMIClassLoader.java:646)
    at java.rmi.server.RMIClassLoader.loadProxyClass(RMIClassLoader.java:311)
    at sun.rmi.server.MarshalInputStream.resolveProxyClass(MarshalInputStream.java:255)
    at java.io.ObjectInputStream.readProxyDesc(ObjectInputStream.java:1548)
    at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1510)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1749)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1346)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:368)
    ... 12 more

该程序似乎无法识别代码库。就我而言,所有文件都是本地文件。有谁知道是什么问题?谢谢

4

3 回答 3

3

尝试在代码库中明确指定包含com.ServerBootstrap.IServer类的 JAR 文件的名称,例如

-Djava.rmi.server.codebase=file:serverClasses/myjarfile.jar

使用 JavaTM RMI 进行动态代码下载(使用 java.rmi.server.codebase 属性) ”文档提供了有关使用代码库及其规范选项的更多信息。

于 2009-10-02T04:48:46.387 回答
0

这不是完整的堆栈跟踪,我认为您可能遗漏了显示问题根本原因的部分。

如果我没记错的话,ClassNotFoundException 有时可能是由于正在加载的类或它所依赖的某个类的静态初始化期间引发的异常。如果发生这种情况,它将在下一个嵌套级别的问题的第一个堆栈跟踪中显示为嵌套异常。我记得(可能是错误的)如果您的应用程序重复尝试类加载,则初始化异常不在生成的堆栈跟踪中。

编辑:完整的堆栈跟踪说我的理论不正确。

于 2009-10-02T04:20:24.663 回答
0

为 指定相对路径java.rmi.server.codebase后,请确保在启动客户端时位于正确的目录(“serverClasses”的父目录)中。如果这很难确保,代码库的绝对路径可能更可靠。

另外,请记住,使用该-jar选项运行时,该-classpath选项将被完全忽略。我认为这不是问题。RMIClassLoader应该仍然能够使用服务器的代码库设置工作。但是,如果您依赖于可以访问类路径中指定的其他类的客户端,那将无法正常工作。您需要Class-path在主 JAR 文件的清单中使用该属性。

于 2009-10-02T04:40:38.167 回答