【问题标题】:java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: java.lang.ClassNotFoundException: ServicesTableaujava.rmi.UnmarshalException:解组参数错误;嵌套异常是:java.lang.ClassNotFoundException: ServicesTableau
【发布时间】:2012-12-13 20:37:01
【问题描述】:

我需要您在 JAVA RMI 方面的帮助,我开发了一个用于对表进行排序的示例程序。但我得到了这个例外:

Erreur RemoteException occurred in server thread; nested exception is: 
    java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
    java.lang.ClassNotFoundException: ServicesTableau

这是我的服务器源代码:

public class Serveur {
    public static void main(String args[]) {

        try {

            System.out.println("Server start ...");
            ServicesTableauImpl od = new ServicesTableauImpl();
            String url = "rmi://" + args[0] + "/ServicesTableauImpl";
            System.out.println("Passe");
            Naming.rebind(url, od);
            System.out.println("Attente d'invocations de client / CTRL-C pour stopper");
        } catch (Exception e) {
            System.out.println("Erreur " + e.getMessage());
        }
    /*
    catch(java.net.MalformatedURLException e){
    System.out.println("Mauvais nom de serveur");
    System.exit(1);
    }
    catch(RemoteException e){
    System.out.println("Pas de Rmiregistry");
    System.exit(1);
    }
    */
    }
}

【问题讨论】:

  • 这个类 ServicesTableauImpl 在类路径中可用吗?
  • @PradeepSimha 缺少的类是ServicesTableau,而不是ServicesTableauImpl。阅读异常。

标签: java rmi


【解决方案1】:

该类在 RMI 注册表的 CLASSPATH 中不可用。修复它的最简单方法是在同一个 JVM 中启动 Registry,通过 LocateRegistry.createRegistry(). 将结果存储在静态字段中。

【讨论】:

  • 我在 Linux 下工作,感谢您的回复(我使用 rmiregistry 现在可以正常工作了)
  • Linux 对答案没有任何影响。
【解决方案2】:

这发生在我身上是因为我没有在与服务器相同的目录中运行rmiregistry

【讨论】:

    【解决方案3】:

    我花了几个小时成功启动了 Orcale 的简单示例表单!

    希望能帮到你

    首先,我在 Windows 上运行程序

    我完全从here复制代码

    但我删除了这个包并将这三个 .class 文件放在一起以说服

    如果你不熟悉这个,我希望你也这样做

    因为当包裹进来时,问题会更复杂

    需要做三个步骤:

    1.启动rmiregistry

    start rmiregistry -J-Djava.class.path=./
    

    用于“远程接口定义”

    以便 rmiregistry 可以找到类

    然后解决ClassNotFoundException

    2.运行服务器

    start java Server
    

    然后就可以看到输出了:

    服务器准备就绪

    3.运行客户端

    java Client
    

    输出:

    响应:你好,世界!

    那就说说怎么处理包

    通常是Server.class和interface.class---“远程接口定义”

    应该在同一个包中

    你需要知道如何使用包运行.class

    java {packagename}.Server
    

    类路径默认为“./”

    包声明将有助于找到Server.class所需的interface.class

    所以我们不需要单独设置-cp

    顺便说一句,如果你尝试设置真正的类路径,你会得到错误

    至于“启动rmiregistry”

    它没有默认的类路径

    所以我们需要设置它

    并且应该和classpath的默认值“./”一样

    【讨论】:

    • 由于类路径默认为.,正如您正确指出的那样,明确指定它不可能成为解决方案的一部分。服务器类和远程接口不需要在同一个包中。答案只是华夫饼。
    【解决方案4】:

    在某些情况下,您需要将 rmi 客户端代码(接口和主代码)移动到默认包。在服务器端重复它。它可以解决您的问题(在 rmi 中使用打包并不那么明显)。

    【讨论】:

    • 自 Java 1.4 以来,使用默认包甚至无法正常工作。您当然必须在客户端和服务器上使用 same 包,即严格来说相同的 class,但它不应该是默认包。
    【解决方案5】:

    答案是基于 IDE 的项目。

    您需要从 build 文件夹中“start rmiregistry”。

    例如: 在 Intellij

    1. 在“target -> classes”文件夹中打开终端
    2. 运行“启动 rmiregistry”
    3. 然后使用 intellij 运行您的服务器代码

    对于 eclipse 我希望它的 build 文件夹

    【讨论】:

    • 你的意思是说“这个答案是针对基于 IDE 的项目的吗?”;如果不是,你指的是哪个答案?
    • 毫无意义的回答。这在应用程序部署的地方不起作用。
    【解决方案6】:

    此错误是因为没有编写安全管理器代码,因此无法加载类。 因此,请确保为安全管理器添加代码。
    如果编译器没有找到安全管理器,则创建一个新的。在 main 方法中添加代码。

    if (System.getSecurityManager() == null) then
        System.setSecurityManager(new RMISecurityManager())
    

    【讨论】:

    • 不,不是。这是由于找不到类。您需要阅读整个异常。如果他正在使用 RMI 代码库功能,这只是由于缺乏安全经理,这没有说明。
    猜你喜欢
    • 2011-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-26
    • 1970-01-01
    • 2011-11-13
    • 1970-01-01
    • 2012-08-26
    相关资源
    最近更新 更多