如何通过远程接口调用传递class对象

owenludong 2013-10-16
有没有办法在运行期间把a应用的class 装载到代码里没有该类的b应用的运行classloader里。 如果直接通过rpc接口传递class对象到b应用,那么b应用在做序列化的时候 发现没有这个class存在,会报序列化错误。 我的目的是让b应用在运行期间能够使用这个类。
subchen 2013-10-16
可以把 A.class 文件本身也序列化,然后传递给 b应用,然后 b 应用用 classloader 加载这个 A.class,然后在 反序列化这个 A object。
owenludong 2013-10-16
那不是非常麻烦,如果A 文件里有其他类的引用,不是还要加载那个类文件?
RednaxelaFX 2013-10-16
果然是RPC场景。
淘宝系(特别是以前淘宝TBOSS)的同事可能会听说过我们有个叫Implant(或者可能有人听说的名字是Buluku)的内部项目,主要就是用来处理RPC场景的类加载相关的问题。

这东西有过几种不同方案的实现。假如把提供服务的一端叫server,把调用服务的一端叫client,

第一种是在server嵌入我们的implant-agent,然后client通过implant-client来做RPC。Implant-client最重要的部分就是一个ClassLoader,当要调用RPC而发现需要作为参数而创建的对象的类、作为返回值而需要反序列化的类在本地找不到时,就会向server端的implant-agent发出请求让它帮忙把Class文件的内容传一份过来,然后在client这边调用defineClass()来加载。Client对server的发现机制有中间的implant-server处理(这是经典结构不多解释了)。

这个很蛋疼吧⋯

第二种是我们让各种提供服务的应用在提供服务的同时提供它们的接口所需要的Class文件,打成JAR包上传给我们。然后我们就在本地有Class了。这个版本的实现超简单,就是动态更新JAR包的部分有点麻烦而已。然而用起来还是有点麻烦,特别是那些提供服务的应用在开发阶段接口还不稳定的时候很不喜欢每次动了接口都要上传JAR包给我们。

第三种是我们使用其它序列化方式,例如Hessian,然后我们绕开Class文件直接“造”出Hessian序列化后的二进制数据。用户只要传Map过来我们就能对应的把键值对序列化成跟Java字段一样的形式,外加要序列化的类的全限定名,就能造出跟原本Hessian对Java对象的序列化一样的数据。在接收的一端(server)那边是有需要的Class的,所以那边反序列化完全没问题。然后server返回数据给client的时候,client这边没有返回值的类也没关系,Hessian找不到类的话会自动反序列化成Map。
这种实现当然有其限制:序列化/反序列化的对象都必须是POJO,而且不能带有任何业务逻辑而必须是纯装数据用的。但典型RPC场景传参数和返回值的对象也就是这样的,所以实际用的时候倒也还行。

================================

微博上发了这帖的链接,有人回复问:
引用
classloader不是可以通过网络load的吗?为什么一定要下载到本地?不知道我理解错了没

我回复了:
RednaxelaFX 写道
可以通过网络load,URLClassLoader就直接能干这活;但你得提供出网络资源才行,例如说你要有个规范如何把类名啊版本号啊之类的映射到唯一的URL上,要有个内部DNS服务器做URL到实际文件资源的映射。当然可以做就是一样麻烦而已。
owenludong 2014-10-20
Implant或者Buluku这个项目 目前还可以拿到代码吗?淘宝这边可以找谁
RednaxelaFX 2014-10-21
owenludong 写道
Implant或者Buluku这个项目 目前还可以拿到代码吗?淘宝这边可以找谁

不知道谁在维护…多半现在都没人在用那个库了吧
(要是还有人在用和在维护的话我会心情复杂,因为那个是我写的…
owenludong 2014-10-22
RednaxelaFX 写道
owenludong 写道
Implant或者Buluku这个项目 目前还可以拿到代码吗?淘宝这边可以找谁

不知道谁在维护…多半现在都没人在用那个库了吧
(要是还有人在用和在维护的话我会心情复杂,因为那个是我写的…



哈哈,我们现在也有类似的跨JVM类加载的场景,不知道有没有什么代码可以参考
RednaxelaFX 2014-10-23
owenludong 写道
哈哈,我们现在也有类似的跨JVM类加载的场景,不知道有没有什么代码可以参考

原本写的Implant的代码我现在自然是没有了。但是要按我前面回帖说的思路来重新实现一个出来要不了多少时间。别纠结了自己动手吧
Global site tag (gtag.js) - Google Analytics