工做中特別是中間件落地時經常會遇到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容器的使用和源碼分析插件