我使用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
程序似乎无法识别代码库。就我而言,所有文件都是本地的。有谁知道这是什么问题?感谢
答案 0 :(得分:3)
尝试在代码库中明确指定包含com.ServerBootstrap.IServer
类的JAR文件的名称,例如
-Djava.rmi.server.codebase=file:serverClasses/myjarfile.jar
“Dynamic code downloading using JavaTM RMI (Using the java.rmi.server.codebase Property)”文档提供了有关代码库使用及其规范选项的更多信息。
答案 1 :(得分:0)
这不是一个完整的堆栈跟踪,我想你可能遗漏了显示问题根本原因的部分。
如果我没记错的话,ClassNotFoundException有时可能是由于在加载的类的静态初始化期间抛出的异常,或者它所依赖的某个类。如果发生这种情况,它将在下一级嵌套时在问题的第一个堆栈跟踪中显示为嵌套异常。我记得(可能不正确)如果您的应用程序重复尝试的类加载,初始化异常不在结果堆栈跟踪中。
编辑:完整的堆栈跟踪说我的理论不正确。
答案 2 :(得分:0)
使用为java.rmi.server.codebase
指定的相对路径,确保在启动客户端时您位于正确的目录(“serverClasses”的父目录)中。如果这很难确保,代码库的绝对路径可能更可靠。
另外,请记住,使用-jar
选项运行时,-classpath
选项将被完全忽略。我不认为这是一个问题; RMIClassLoader
仍然可以使用服务器的代码库设置工作。但是,如果您依赖于客户端可以访问类路径上指定的其他类,那将无法正常工作。您需要在主JAR文件的清单中使用Class-path
属性。