工作中特别是中间件落地时常常会遇到jar包冲突的情况,本篇文章将分析目前业界的Jar包隔离解决方案。
Java 应用程序因某种因素,加载不到正确的类而导致其行为跟预期不一致。
方法二:通过自定义ClassLoader实现隔离在博客 Java 中隔离容器的实现 中提到了将每个jar包视为多个bundle,通过自定义classloader隔离运行,并且还可以实现多个jar包共享一个类。 该Demo通过启动一个KContainer类运行,KContainer类中主要包含一个BundleList和SharedClassList。每一个Bundle代表一个jar包或者class路径,Bundle类包含一个自定义的BundleClassLoader类(继承UrlClassLoader),由于不同BundleBundleClassLoader不同,可以实现 隔离运行 ,而这个BundleClassLoader需要传入一个SharedClassList,classloader在加载一个类时,如果没有加载到,则可以从外部传进来的SharedClassList中加载,这样就实现了 多个jar包共享一个类 。
protected Class<?> findClass(String name) throws ClassNotFoundException { logger.debug(“try find class {}”, name); Class<?> claz = null; try { claz = super.findClass(name); } catch (ClassNotFoundException e) { claz = null; } if (claz != null) { logger.debug(“load from class path for {}”, name); return claz; } //如果没有加载到,从共享的类中加载 claz = sharedClasses.get(name); if (claz != null) { logger.debug(“load from shared class for {}”, name); return claz; } logger.warn(“not found class {}”, name); throw new ClassNotFoundException(name); } 复制代码
需要共享出去给别人用的类可以通过在类路径下通过一个properties文件指定,在loadBundle的时候加载进SharedClassList。
方法三:轻量级隔离容器SOFAArkSOFAArk同样也是使用不同的类加载器加载冲突的三方依赖包,进而做到在同一个应用运行时共存。 SOFAArk通过Ark Plugin区分应用中哪些依赖包是需要单独的类加载器加载 。借助 SOFABoot 官方提供的 maven 打包插件,开发者可以把若干普通的 JAR 包打包成 Ark Plugin 供应用依赖或者把普通的 Java 模块改造成 Ark Plugin。应用使用添加 maven 依赖的方式引入 Ark Plugin,运行时,SOFAArk 框架会自动识别应用的三方依赖包中是否含有 Ark Plugin,进而使用单独的类加载器加载。其运行时逻辑图如下:
在Ark Plugin的POM文件中,会配置导出类和导入类的配置。导出类即把 Ark Plugin 中的类导出给 Ark Biz 和其他 Ark Plugin 可见。对于 Ark Plugin 来说,如果需要使用其他 Ark Plugin 的导出类,必须声明为自身的导入类。
方法四:阿里的Pandora隔离容器阿里的Pandora是闭源的,网上资料比较少。 可以从阿里的一次演讲PPT上得知,Pandora仍然是基于ClassLoader实现的 Pandora这类的隔离容器的缺点:
下一篇文章将着重分析蚂蚁金服的SOFA-ARK容器的使用和源码分析