java.rmi.ServerException:服务器线程中发生RemoteException(ClassNotFoundException)

时间:2012-03-02 09:52:42

标签: java exception rmi

以下方法:

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中的消息,说明启动服务器的问题,然后是上述异常。这可能是什么原因?

我不明白为什么最后一条异常声明说明当我导入正确的包时类没有找到

5 个答案:

答案 0 :(得分:12)

此例外有三种情况。

  1. 导出时:您没有运行' rmic'并且您没有采用UnicastRemoteObject的Javadoc序言中描述的步骤来使其不必要。

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

  3. 查找时:客户端在类路径上没有这些东西。

  4. 这是案例2.注册表无法找到指定的类。

    有四种解决方案:

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

    2. 通过LocateRegistry.createRegistry().

    3. 在服务器JVM中启动注册表
    4. 使用动态存根,如UnicastRemoteObject.的Javadoc前言中所述。然而,您可能仍会遇到与远程接口本身或它依赖的类相同的问题,在这种情况下上述1-3仍适用于该班级/那些班级。

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

答案 1 :(得分:4)

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

答案 2 :(得分:2)

我将尽力更好地解释我所做的事情: 1号我声明了classpath变量,如下所示:

  1. set classpath=%classpath%
  2. set classpath=C:\compiler
  3. set classpath=C:\compiler\libro\cap07\rmi\hello\Hello.java
  4. set classpath=C:\compiler\libro\cap07\rmi\hello\Server.java
  5. set classpath=C:\compiler\libro\cap07\rmi\hello\Client.java
  • (全部位于一个线集中:

set classpath=%classpath%;C:\compiler;C:\compiler\libro\cap07\rmi\hello\Hello.java;C:\compiler\libro\cap07\rmi\hello\Server.java;C:\compiler\libro\cap07\rmi\hello\Client.java)

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

第二。我用行javac -d C:\compiler Hello.java Server.java Client.java进行了编译。其中C:\compiler是根目录,例如Eclipse IDE上的src。

3rd。我运行了start rmiregistry行。 (无论您在哪里运行,都是一样的。)

第四。我跑了:

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

您已经知道C:\compiler,但是您需要在命令的末尾定义包地址,以便命令可以找到.class文件。打开任何.java文件,然后复制没有包sendense的包地址。打开src目录(在我的情况下为C:\ compiler)时,您会看到所有创建的目录序列。正确创建此命令行后,无论在哪里运行,C:,D:,src都可以运行。

5th。最后,我使用以下方法运行Client类:

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

总而言之,如果无法创建classpath变量,或者创建错误,或者无法正确解决第4点的句子,那么JVM会抛出相同或相似的错误。在这里搜索!

(对不起,我的英语)。

答案 3 :(得分:0)

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

解决方案:

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

答案 4 :(得分:-1)

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

E:\ARMSRemoteUpdater\WebContent\WEB-INF\classes>set classpath=%classpath%;E:\ARMSRemoteUpdater\WebContent\WEB-INF\classes <ENTER>

E:\ARMSRemoteUpdater\WebContent\WEB-INF\classes>c: <ENTER>

C:\>rmiregistry

以上情况应该可以。

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

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

希望我已经详细解释过了。