背景及解决方案
我们假设一个情况,hbase的reader是1.0版本的,hbase的writer是2.0版本的,所以他们依赖的jar包版本也不一致,如果直接一起加载到JVM虚拟机,那就会有jar包的冲突。
为了避免冲突,就需要给每个插件都设置一个自己的类加载器(类加载的顺序参考之前的jvm - 类的加载),这样不同版本的jar包就不会冲突。
下面用streamreader的job初始化详细的讲解这个流程。
JarLoader
JarLoader是每个插件的类加载器,为了避免重复的生成,会通过map的形式存放在内存jarLoaderCenter中,key就是plugin.pluginType.pluginName,value就是JarLoader。
pluginType是一个枚举,包括reader、writer、transformer、handler,pluginName就是插件的名称。比如streamreader的key就是plugin.reader.streamreader。
每次获取类加载器的时候,就会从jarLoaderCenter中获取,如果有对应的key-value,就返回JarLoader,如果没有,就创建一个JarLoader,并存入jarLoaderCenter再返回JarLoader。
JarLoader创建
如果jarLoaderCenter没有对应的JarLoader,就会创建一个JarLoader。
首先是获取路径path,就是读取reader.streamreader的plugin.json配置文件中生成的path信息。
在创建JarLoader的时候,就会把path路径的jar文件以及子路径的jar文件都加入加入到class path中,所以每个插件所需要的jar包在通过JarLoader加载的时候是相互隔离的,这样就避免的jar包冲突。
比如加载的时候,streamreader除了把streamreader-0.0.1-SNAPSHOT.jar加载进来,也会加载libs以下的包。
ClassLoaderSwapper
由于我们需要在不同的地方使用不同的类加载器,所以在使用之前就需要对类加载器进行切换。
比如当前(用黄色代表)的类加载器是A,我们现在使用类加载B。
我们首先把当前的类加载器存起来,放入紫色(storeClassLoader)中暂存。然后再把需要使用的类加载B放入黄色中,代表当前使用的类加载是B。
然后就可以使用B进行类加载,当使用完后,就需要把暂存在紫色的类加载器进行还原。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。