【问题标题】:rmi class can not found exceptionrmi 类找不到异常
【发布时间】:2010-12-03 05:21:08
【问题描述】:

我使用 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

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

【问题讨论】:

    标签: java exception rmi codebase


    【解决方案1】:

    尝试在代码库中明确指定包含 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)”文档提供了有关代码库使用及其规范选项的更多信息。

    【讨论】:

    • 它有效!是否可以将它设置在其他地方,这样我就不必每次都添加它。
    • @CKeven:你可以使用System.getProperties().setProperty(name, value) 做同样的事情......只要你做的足够早。
    • 我真的不知道该怎么做。你能明确告诉我吗?谢谢
    • 当您需要加载从 RMI 服务器(例如您的 IServer 类)导出的类时使用代码库。然后,有必要指定代码库来告诉您的 RMI 客户端在哪里可以找到 JAR 文件。
    • 您可以尝试 - 正如 Stephen C. 建议的那样 - 在您的代码中调用以下代码: System.setProperty("java.rmi.server.codebase","file:serverClasses/myjarfile.jar");
    【解决方案2】:

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

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

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

    【讨论】:

    • 我只是把它们都放好了。谢谢
    【解决方案3】:

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

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

    【讨论】:

    • 奇怪的是程序甚至无法识别 jar 文件中的类。你知道这是为什么吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-13
    • 2016-06-19
    • 2013-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多