工做中特别是中间件落地时经常会遇到jar包冲突的状况,本篇文章将分析目前业界的Jar包隔离解决方案。java
Java 应用程序因某种因素,加载不到正确的类而致使其行为跟预期不一致。bash
方法一:手动排查框架
方法二:经过自定义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。maven
方法三:轻量级隔离容器SOFAArk SOFAArk一样也是使用不一样的类加载器加载冲突的三方依赖包,进而作到在同一个应用运行时共存。 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 的导出类,必须声明为自身的导入类。ui
方法四:阿里的Pandora隔离容器 阿里的Pandora是闭源的,网上资料比较少。 能够从阿里的一次演讲PPT上得知,Pandora仍然是基于ClassLoader实现的 Pandora这类的隔离容器的缺点:spa
下一篇文章将着重分析蚂蚁金服的SOFA-ARK容器的使用和源码分析插件