java.rmi.ServerException:RemoteException 发生在服务器线程 (ClassNotF



以下方法:

    private void startServer() { // snippet that starts the server on the local machine
        try {
             RemoteMethodImpl impl = new RemoteMethodImpl();
             Naming.rebind( "Illusive-Server" , impl );
        } catch(Exception exc) {
            JOptionPane.showMessageDialog(this, "Problem starting the server", "Error", JOptionPane.ERROR_MESSAGE);
            System.out.println(exc);
        }
    }

引发此异常:

java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
        java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
        java.lang.ClassNotFoundException: Interfaces.RemoteMethodIntf

当我开始我的项目时,我在 JOptionPane 中收到一条消息,说启动服务器时出现问题,然后出现上述异常。这可能是什么原因呢?

我不明白为什么当我导入正确的软件包时,最后一个异常语句说找不到 exc 类

此异常有四种情况。

  1. 导出时:您没有运行"rmic",也没有采取 Javadoc 序言中描述的步骤,以便UnicastRemoteObject使其变得不必要。

  2. 绑定时:注册表没有存根或远程接口,也没有它们依赖于其类路径的内容。

  3. 查找时:客户端的类路径中没有这些内容。

  4. 调用远程方法时:您要么向其 CLASSPATH 中不存在的类的服务器发送某些内容,要么从不在 CLASSPATH 上的类的服务器(包括异常(接收某些内容:在这两种情况下,都可能是远程接口的方法签名中提到的类或接口的派生类或接口实现。

这是情况 2。注册表找不到命名类。

有几种解决方案:

  1. 使用包含相关 JAR 或目录的类路径启动注册表。

  2. 通过LocateRegistry.createRegistry().在服务器 JVM 中启动注册表

  3. 使用动态存根,如 Javadoc 的序言中所述 UnicastRemoteObject. 但是,您可能仍然会遇到远程接口本身或其所依赖的类的相同问题,在这种情况下,上面的 1-3 仍然适用于该类/这些类。

  4. 确保不会发生上述情况 (4(。

  5. 使用代码库功能。这实际上是一个部署选项,IMO在初始开发阶段要避免。

Remote Server Error:RemoteException occurred in server thread; nested exception is:
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: mathInterface

该错误非常简单地解决,请执行以下步骤:

  • 例如,您的 java 文件考虑 D 驱动器
  • 启动 rmiregistry D 驱动器(示例 D:\start rmiregistry(然后不要在其他驱动器上启动 rmiregistry,它将产生上述错误

(无论您的文件在哪里,请从rmiregistry开始(

我会尽量更好地解释我做了什么:第一。我声明了类路径变量,如下所示:

  1. set classpath=%classpath%
  2. set classpath=C:compiler
  3. set classpath=C:compilerlibrocap07rmihelloHello.java
  4. set classpath=C:compilerlibrocap07rmihelloServer.java
  5. set classpath=C:compilerlibrocap07rmihelloClient.java
  • (全部在一个行集中:

set classpath=%classpath%;C:compiler;C:compilerlibrocap07rmihelloHello.java;C:compilerlibrocap07rmihelloServer.java;C:compilerlibrocap07rmihelloClient.java)

  • (我不确定.java文件是否是有问题的,但我也出于怀疑而写了它们(。

2nd. 我用行javac -d C:compiler Hello.java Server.java Client.java编译。其中C:compiler是根目录,类似于 Eclipse IDE 上的 src。

第三。我跑了start rmiregistry线。(不管你在哪里运行它,它都是一样的(。

4. 我跑了:

start java -classpath C:compiler -Djava.rmi.server.codebase=file:C:compiler/ libro.cap07.rmi.hello.Server

你已经知道C:compiler,但你需要在命令可以找到.class文件的最后一个定义包地址。打开任何.java文件并复制没有包的包地址。当你打开src目录(在我的例子中是C:\compiler(时,你会看到所有创建的目录序列。正确创建此命令行后,无论您在何处运行它,C:,D:,src,以及它运行的任何地方。

5th. 最后,我用以下命令运行客户端类:

java -classpath C:compiler libro.cap07.rmi.hello.Client

总之,如果类路径变量不会创建,或者创建错误,或者第 4 点的句子没有得到很好的解决,JVM 会抛出相同或类似的错误。在那里搜索!

(对不起我的英语(。

您可以从任何地方启动 rmiregistry,但您必须确保编译的类已经在类路径中。例如:-

E:ARMSRemoteUpdaterWebContentWEB-INFclasses>set classpath=%classpath%;E:ARMSRemoteUpdaterWebContentWEB-INFclasses <ENTER>
E:ARMSRemoteUpdaterWebContentWEB-INFclasses>c: <ENTER>
C:>rmiregistry

以上应该可以正常工作。

通常,如果您从已编译类的根位置启动 rmiregistry(上面的例子是 E:\ARMSRemoteUpdater\WebContent\WEB-INF\classes(,这将起作用,因为 .(点 - 当前目录(已在类路径中设置。

但是一旦你删除.(点 - 当前目录(从您的类路径中,上述工作条件也将失败。

希望我已经详细解释了。

我遇到了同样的问题,不同的解决方案对我有用。我正在运行两个不同的 IntelliJ 项目,每个项目中都有一个接口副本。其中一个在包中,另一个不在,这就是导致此错误的原因。

解决 方案:

  • 确保接口副本不在包中。
  • 确保接口副本具有完全相同的包名称。

最新更新