问题
上一篇文章中已经可以允许插件中有自己的依赖jar包了(原理就是插件中依赖jar包交给插件专属的插件类加载器PluginClassLoader进行加载,业务系统中依赖的jar包交由业务类加载器AliooClassLoader进行加载)
大家知道java中是尽可能面向对象编程的,如果请求插件中的功能类方法返回值类型是一些常见的3方jar,比如com.alibaba.fastjson.JSONObject,按照之前的设计会存在2种情况:
-
业务系统中没有依赖fastjson
Caused by: java.lang.ClassNotFoundException: com.alibaba.fastjson.JSONObject -
业务系统中也依赖fastjson
loader constraint violation: loader ‘alioo-container-classloader’ @4961f6af (instance of com.lzc.alioo.container.AliooClassLoader, child of ‘platform’ jdk.internal.loader.ClassLoaders P l a t f o r m C l a s s L o a d e r ) w a n t s t o l o a d c l a s s c o m . a l i b a b a . f a s t j s o n . J S O N O b j e c t . A d i f f e r e n t c l a s s w i t h t h e s a m e n a m e w a s p r e v i o u s l y l o a d e d b y ′ a p p ′ ( i n s t a n c e o f j d k . i n t e r n a l . l o a d e r . C l a s s L o a d e r s PlatformClassLoader) wants to load class com.alibaba.fastjson.JSONObject. A different class with the same name was previously loaded by 'app' (instance of jdk.internal.loader.ClassLoaders PlatformClassLoader)wantstoloadclasscom.alibaba.fastjson.JSONObject.Adifferentclasswiththesamenamewaspreviouslyloadedby′app′(instanceofjdk.internal.loader.ClassLoadersAppClassLoader).
一个可以投入项目真正使用的业务容器及插件上面中的这个情况在所难免,所以今天我们继续迭代,想办法支持一下这个情况
解法
如果是一些常见的第3方jar,可能存在业务系统与插件中都会使用的第3方jar,且在插件中会将其作为返回值类型,我们需要将这类第3方jar统一交由业务系统类加载器AliooClassLoader进行加载。
那么插件中依赖的那么多第3方jara其中哪些类需要使用AliooClassLoader进行加载呢,这里就需要引入一个配置文件 META-INF/import.index 进行标记说明,不在这个文件里的,还是分别需要由插件类加载器与业务类加载器各自进行加载
完整代码库
由于代码库会不断迭代,大家下载下来的代码会是最新版,为了方便大家找到本期的示例代码,已为其进行tag标识:v1.2
业务插件
https://github.com/lzc-alioo/alioo-container-plugin-x1
注: alioo-container-plugin-x2 与alioo-container-plugin-x1相同故未上传
业务插件打包工具
https://github.com/lzc-alioo/alioo-boot-maven-plugin
业务容器
https://github.com/lzc-alioo/alioo-container
测试工程
https://github.com/lzc-alioo/classloadertest