【问题标题】:RMI: pass non-remote object classes to a serverRMI:将非远程对象类传递给服务器
【发布时间】:2012-05-29 12:10:03
【问题描述】:

假设我有一个远程类,它有一个带有 POJO 参数的方法:

class MyRemote implements Remote {

    void service(Param param) throws RemoteException;

}

客户端检索存根并执行以下操作:

// DerivedParam is defined by the client
// and is derived from Param
DerivedParam dparam = getDerivedParam();
myService.service(dparam);

它失败了,因为服务器不知道 DerivedParam 类(以及它可能实现的接口)。

问题:是否有可能将这些类从客户端传递到服务器以使这样的调用成为可能?

【问题讨论】:

    标签: java rmi


    【解决方案1】:

    我不是这方面的专家,但前段时间我确实使用了这个技巧。神奇之处在于通过设置java.rmi.server.codebase 属性来使用code mobility

    您使此属性指向您的共享类可能驻留的 URL 或以空格分隔的 URL 列表。例如,这可能是一个 FTP 服务器或一个 HTTP 服务器,其中包含有公共类的 jar 文件。

    一旦设置,代码库注释将包含在服务器和客户端编组的所有对象中,当任何一方找不到类时,他们会在代码库中提供的 URL 中查找它并动态加载它。

    请阅读Dynamic Code Downloading with Java RMI

    假设您只向客户端提供接口,并且实现将位于给定的代码库中。然后客户端请求服务器发送一个给定的对象,客户端期望接收一个实现给定接口的对象,但是实际的实现对于客户端来说是未知的,当它反序列化发送的对象时它必须去代码base 并为实际传递的对象下载相应的实现类。

    这将使客户端变得非常瘦,并且您将非常轻松地更新代码库中的类,而无需求助于更新每个客户端。

    假设您有一个具有以下界面的 RMI 服务器

    public interface MiddleEarth {
         public List<Creature> getAllCreatures();
    }
    

    客户端将只有MiddleEarthCreature 的接口,但类路径中没有任何实现。

    Creature 的实现是ElfManDwarfHobbit 类型的可序列化对象。而且这些实现位于您的代码库中,而不是您客户端的类路径中。

    当您要求您的 RMI 服务器向您发送中土世界所有生物的列表时,它会发送实现 Creature 的对象,即上面列出的任何类。

    当客户端接收到序列化的对象时,它必须查找类文件以便对它们进行反序列化,但这些文件不在本地类路径中。此流中的每个对象都带有给定的代码库标记,可用于查找缺失的类。因此,客户端求助于代码库来查找这些类。它会在那里找到正在使用的实际生物类别。

    代码库双向工作,因此这意味着如果您向服务器发送Creature(即Ent),它也会在代码库中查找它。

    这意味着当客户端和服务器都需要发布新类型的生物时,他们所要做的就是更新代码库中的creaturesImpl.jar,而不是服务器或客户端应用程序本身。

    【讨论】:

    • 非常感谢这么详细的回答!
    猜你喜欢
    • 2022-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多