【问题标题】:running rmi server, classnotfound [duplicate]运行 rmi 服务器,classnotfound [重复]
【发布时间】:2010-10-02 15:45:12
【问题描述】:

您好,我正在尝试运行一个将类绑定到命名服务器的 java 应用程序,但我经常收到 ClassNotFoundException

首先我启动注册表:

rmiregistry

然后从 eclipse 我尝试执行服务器但得到这个错误

java.rmi.ServerException:服务器线程发生RemoteException;嵌套异常是: java.rmi.UnmarshalException:解组参数错误;嵌套异常是: java.lang.ClassNotFoundException: progInternet2008.commons.NominabileFactory 在 sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:396) 在 sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:250) 在 sun.rmi.transport.Transport$1.run(Transport.java:159) 在 java.security.AccessController.doPrivileged(本机方法) 在 sun.rmi.transport.Transport.serviceCall(Transport.java:155) 在 sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535) 在 sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790) 在 sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649) 在 java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) 在 java.lang.Thread.run(Thread.java:619) 在 sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:255) 在 sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:233) 在 sun.rmi.server.UnicastRef.invoke(UnicastRef.java:359) 在 sun.rmi.registry.RegistryImpl_Stub.rebind(未知来源) 在 progInternet2008.Pozzobon.tesi.Slave.main(Slave.java:54) 引起:java.rmi.UnmarshalException:错误解组参数;嵌套异常是: java.lang.ClassNotFoundException: progInternet2008.commons.NominabileFactory 在 sun.rmi.registry.RegistryImpl_Skel.dispatch(未知来源) 在 sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:386) 在 sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:250) 在 sun.rmi.transport.Transport$1.run(Transport.java:159) 在 java.security.AccessController.doPrivileged(本机方法) 在 sun.rmi.transport.Transport.serviceCall(Transport.java:155) 在 sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535) 在 sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790) 在 sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649) 在 java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) 在 java.lang.Thread.run(Thread.java:619) 引起:java.lang.ClassNotFoundException:progInternet2008.commons.NominabileFactory 在 java.net.URLClassLoader$1.run(URLClassLoader.java:200) 在 java.security.AccessController.doPrivileged(本机方法) 在 java.net.URLClassLoader.findClass(URLClassLoader.java:188) 在 java.lang.ClassLoader.loadClass(ClassLoader.java:307) 在 java.lang.ClassLoader.loadClass(ClassLoader.java:252) 在 java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320) 在 java.lang.Class.forName0(本机方法) 在 java.lang.Class.forName(Class.java:247) 在 sun.rmi.server.LoaderHandler.loadProxyInterfaces(LoaderHandler.java:711) 在 sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:655) 在 sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:592) 在 java.rmi.server.RMIClassLoader$2.loadProxyClass(RMIClassLoader.java:628) 在 java.rmi.server.RMIClassLoader.loadProxyClass(RMIClassLoader.java:294) 在 sun.rmi.server.MarshalInputStream.resolveProxyClass(MarshalInputStream.java:238) 在 java.io.ObjectInputStream.readProxyDesc(ObjectInputStream.java:1531) 在 java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1493) 在 java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1732) 在 java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329) 在 java.io.ObjectInputStream.readObject(ObjectInputStream.java:351) ... 12 更多

我已阅读 RMI Java 教程,但仍然无法正常工作...

作为 VM 参数,我设置了这个:

-Djava.rmi.server.codebase=file:${workspace_loc}/progInternet2008

请帮帮我

(我使用的是 Java 6)

【问题讨论】:

  • 你最终解决了这个问题吗?
  • A 文件:codebase URL 仅在客户端和服务器在同一台机器上时有效,在这种情况下,您根本不需要 codebase 功能,或者当它引用共享驱动器时从客户端和服务器上看是一样的,这意味着一个局域网,你是否需要这个功能也是值得怀疑的。

标签: java eclipse rmi rmiregistry


【解决方案1】:

我很确定您必须使用与应用程序相同的类路径来启动 RMI 服务器。我相信它采用与java相同的参数,即-cp [your class path]。

【讨论】:

  • 当您说 RMI 服务器时,您是指 rmiregistry 应用程序还是应用程序的服务器组件与客户端组件?
【解决方案2】:

好的,我刚刚克服了这个问题。确保在运行 rmiregistry 时设置了 CLASSPATH 环境变量。

例如,您可能有一个脚本:

set CLASSPATH=[path to jdbc driver].jar
rmiregistry.exe

这就是让我丢失的类路径正常工作所需的全部内容。我不确定如何将-cp commandline 发送到rmiregistry.exe。它的文档非常缺乏。

【讨论】:

  • Sun 的 RMI 教程明确告诉您不要这样做。这可能会导致问题。
  • @A.Levy 他们到底在哪里说的?这可能导致问题的唯一方法是使用代码库功能。
  • 点赞。这是最后 10 个问题中唯一有效的解决方法。 useCodeBaseOnly=false 不能作为参数。 -Djava.security.policy=file 设置所有权限也不起作用。 -Djava.rmi.server.codebase=some.jar 不像其他人所说的那样工作......
【解决方案3】:

发生异常是因为 rmiregistry 应用程序不知道从哪里加载类。当您尝试在 RMI 注册表中绑定对象时,注册表会下载该对象的类定义。其他一些答案告诉您通过设置 rmiregistry 应用程序的类路径来解决此问题,以便它在启动时具有类定义并且不需要下载任何东西,但是 Sun 的 Java RMI 教程 @987654321 @。我怀疑这可能会导致注册表中类的版本与服务器上的类发生冲突。

处理该问题的正确方法是按照您的尝试设置 java.rmi.server.codebase 属性。该属性要求目录路径以正斜杠结尾,如下所示:

-Djava.rmi.server.codebase=文件:${workspace_loc}/progInternet2008/

如果 ${workspace_loc} 变量是相对路径并且 rmiregistry 应用程序未在同一目录中启动,因此相对路径不正确,您也可能会遇到问题。如果您将路径设为绝对路径,或者在适当的目录中启动 rmiregistry,ClassNotFoundException 应该会消失。有关更多详细信息,请参阅tutorial on the java.rmi.server.codebase property。

【讨论】:

  • 教程只是说因为它使用了代码库功能,它破坏了代码库功能。否则这不是问题。
【解决方案4】:

尝试在 VM Arg 末尾添加 /bin:

-Djava.rmi.server.codebase=file:${workspace_loc}/progInternet2008/bin

您将运行的文件在此目录中,因此您需要将其包含在路径中。

【讨论】:

  • 没有证据表明类文件在 bin 目录中。
【解决方案5】:

我花了一整天卸载和重新安装我的 JDK 并更改类路径和环境变量。但罪魁祸首是命令 start rmigregistry 没有以正确的方式启动 rmiregistry。因此,感谢此页面上的 cmets,解决方案是暂时取消设置 CLASSPATH。这是通过命令set CLASSPATH=

完成的

【讨论】:

  • 使用 your CLASSPATH 无法为 you “以正确的方式”启动它,它无法提前知道。是否正确取决于您。不要责怪工具。
【解决方案6】:

我从 JDK1.6.0_33 升级到 1.7.0_45 也遇到了同样的问题。我找到了这个文档并通过启动 rmiregistry 解决了这个问题:

rmiregistry -Djava.rmi.server.useCodebaseOnly=false

参考下面 http://docs.oracle.com/javase/7/docs/technotes/guides/rmi/enhancements-7.html

【讨论】:

    【解决方案7】:

    我遇到了同样的问题,要解决此问题,请确保在运行 rmiregistry 时将您的 CLASSPATH 设置为包含服务器类的路径。

    在 linux 机器上运行以下命令。

    export CLASSPATH="<server_class_path>"
    

    确保 CLASSPATH 已设置:

    echo $CLASSPATH
    

    设置类路径后,运行 rmiregistry

    rmiregistry &
    

    【讨论】:

      【解决方案8】:

      从 /bin、/build 或 /build/classes 文件夹中运行 rmiregisrty 命令,无论哪个文件夹是构建文件的根目录。

      我花了半天时间试图解决同样的问题。

      【讨论】:

      • 非常感谢!它只适用于最简单的运行(仅限本地)。
      • 你救了 25 个人!
      • 谢谢,这就是我需要的答案!我更进一步,只是使用命令LocateRegistry.createRegistry(1099); 在我的代码中启动了注册表
      • @lolynns 你应该得到奖牌
      • 对于 intellij 人员,该文件夹位于 out/production/myrmi。具有 .class 文件的那个
      【解决方案9】:

      关闭最初启动 rmiregistry 的 cmd 窗口。在新的 cmd 中转到项目类文件所在的位置(uptill bin)并使用以下命令启动注册表:

      rmiregistry -J-Djava.rmi.server.useCodebaseOnly=false

      如果您使用的是 Eclipse,请运行 ServerSideProject,您的 ImplementationClass 实例将绑定到指定的 URL。

      只需在绑定方法下方打印一行,然后查看它是否被打印。如果打印成功,说明您的服务器工作正常。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-07-04
        • 2019-03-04
        • 1970-01-01
        • 2015-02-03
        • 2021-09-26
        • 2011-02-28
        • 2016-01-11
        • 2012-10-13
        相关资源
        最近更新 更多