felix框架
框架基于osgi模式,因此在集成很多依赖的时候出现了问题,比如文章中遇到的类加载失败的问题:
问题截图
可以看出是org.apache.hadoop.hdfs.DistributedFileSystem加载失败导致的
可以debugger查询到这里去查询类的时候使用的是下面的这个方法:
CACHE_CLASSES.put(classLoader, map);
加载的类会放到对应的缓存对象中,缓存对象中的信息和classloader有关系,因此后面加载的时候去获取的时候会获取失败;详细信息点进去可以看到里面的引用的对象的加载器是有BundleClassLodaerJava5加载的。
原因
通过查询资料我们了解到felix框架的每一个bundle都有一个自己的类加载器,这个类加载器的名称我们可以借助代码获取到:
getClass().getClassLoader();
也可以使用相关调试工具查看到到,比如截图中的visualVM:
解决办法
查看代码逻辑可以看出,hadoop中查找的类会被缓存到一个CACHE_CLASSES对象中,其中是按照类加载的不同进行缓存的,因此要不然就是修改这部分的源代码逻辑,要不然就是让每次加载的时候修改新的类加载器:BundleClassLodaerJava5。
因此这里在创建hadoop的配置类的时候手动修改为当前类的类加载器,然后我们debugger
重新看下缓存类中的缓存属性是不是对应BundleClassLodaerJava5有了对应的类缓存:
总结:
Thread.currentThread().setContextClassLoader(getClass().getClassLoader());