简体   繁体   English

RMI:将非远程对象类传递给服务器

[英]RMI: pass non-remote object classes to a server

Suppose I have a remote class that has a method with a POJO parameter: 假设我有一个远程类,该类具有带有POJO参数的方法:

class MyRemote implements Remote {

    void service(Param param) throws RemoteException;

}

The client retrieves a stub and does: 客户端检索存根并执行以下操作:

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

It fails, because the server has no clue about the DerivedParam class (and interfaces that it possibly implements). 它失败了,因为服务器对DerivedParam类(以及它可能实现的接口)一无所知。

The question: is it somehow possible to pass those classes from client to server to make such an invocation possible? 问题:是否有可能将这些类从客户端传递到服务器,以使这样的调用成为可能?

I am no an expert on the subject, but I did pulled this trick some time ago. 我不是该主题的专家,但是前段时间我确实做到了这一点。 The magic is in the use of code mobility by means of setting the java.rmi.server.codebase property. 神奇之处在于通过设置java.rmi.server.codebase属性来使用代码移动性。

You make this property point to a URL or space-separated list of URLs where your shared classes may reside. 您使该属性指向共享类可能驻留的URL或URL的空格分隔列表。 This could be, for instance, an FTP server or an HTTP server where a jar file with common classes reside. 例如,这可能是FTP服务器或HTTP服务器,其中包含具有通用类的jar文件。

Once set up, the codebase annotation will be included in all objects marshalled by server and client, and when either party cannot find a class, they look it up in the URLs provided in the code base and would dynamically load it. 设置完成后,代码库批注将包含在服务器和客户端编组的所有对象中,并且当任何一方都找不到类时,他们会在代码库提供的URL中进行查找并动态加载。

Please read Dynamic Code Downloading with Java RMI . 请阅读使用Java RMI进行动态代码下载

Let's say you provide to your client only interfaces, and the implementations will be located in a given code base. 假设您仅向客户端提供接口,并且实现将位于给定的代码库中。 Then the client requests the server to send a given object, the client expects to receive an object that implements a given interface, but the actual implementation is unknown to the client, when it deserializes the sent object is when it has to go to the code base and download the corresponding implementing class for the actual object being passed. 然后客户端请求服务器发送给定的对象,客户端希望接收一个实现给定接口的对象,但是客户端反序列化发送的对象是在必须转到代码时,客户端才知道实际的实现并为要传递的实际对象下载相应的实现类。

This will make the client very thin, and you will very easily update your classes in the code base without having to resort to updating every single client. 这将使客户端非常瘦,并且您将非常容易地更新代码库中的类,而不必诉诸于更新每个客户端。

Let's say you have a RMI server with the following interface 假设您有一个具有以下界面的RMI服务器

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

The client will only have the interfaces for MiddleEarth and Creature , but none of the implementations in the class path. 客户端仅具有MiddleEarthCreature的接口,而类路径中没有任何实现。

Where the implementations of Creature are serializable objects of type Elf , Man , Dwarf and Hobbit . Creature的实现是ElfManDwarfHobbit类型的可序列化对象时。 And these implementations are located in your code base, but not in your client's class path. 这些实现位于您的代码库中,而不位于客户端的类路径中。

When you ask your RMI server to send you the list of all creatures in Middle Earth, it will send objects that implement Creature , that is, any of the classes listed above. 当您要求RMI服务器向您发送“中地球”中所有生物的列表时,它将发送实现Creature对象,即上面列出的任何类。

When the client receives the serialized objects it has to look for the class files in order to deserialized them, but these are not located in the local class path. 当客户端收到序列化的对象时,它必须查找类文件以反序列化它们,但是这些文件不在本地类路径中。 Every object in this stream comes tagged with the given code base that can be used to look for missing classes. 此流中的每个对象都带有给定的代码库标记,该代码库可用于查找缺少的类。 Therefore, the client resort to the code base to look for these classes. 因此,客户端求助于代码库来查找这些类。 There it will find the actual creature classes being used. 在那里,它将找到正在使用的实际生物类别。

The code base works in both directions, so it means that if you send your server a Creature (ie an Ent ) it will look for it in the code base as well. 代码库在两个方向上均有效,因此这意味着,如果您向服务器发送Creature (即Ent ),它也会在代码库中寻找它。

This means that when both, client and server need to publish new types of creatures all they have to do is to update the creaturesImpl.jar in the code base, and nothing in the server or client applications themselves. 这意味着,当两者,客户端和服务器需要发布新的类型的生物所有他们所要做的是更新creaturesImpl.jar代码库中,并没有在服务器或客户端应用程序本身。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM