首页 > 代码库 > 【转】获取OSGi任意Bundle的ClassLoader
【转】获取OSGi任意Bundle的ClassLoader
在OSGi环境中,在Bundle内部代码中要得到自己Bundle的ClassLoader就很简单,在自己Bundle的代码中,直接写this.getClass().getClassLoader()就得到了自己Bundle的ClassLoader了。但怎么在其他Bundle或外部代码中得到任意一个Bundle的ClassLoader呢?Bundle和BundleContext都没有提供getClassLoader方法来获取,我就用了一种比较另类的方法来获取。突破口就在Bundle.loadClass(String className)方法,目前此方法已经在QuickWebFramework中应用了。
思路:
1.调用Bundle的findEntries方法,得到Bundle中任意一个class文件。
2.根据这个class文件的路径,得到类名
3.调用Bundle的loadClass方法,得到这个类
4.调用这个类的getClassLoader方法,得到ClassLoader
PS:
1.由上面的思路可知此方法不能用于没有一个Java类的Bundle
2.OSGi系统Bundle(即ID为0的Bundle)得不到class文件,所以此方法不能用于OSGi系统Bundle
代码如下:
1 public static ClassLoader getBundleClassLoader(Bundle bundle) { 2 // 搜索Bundle中所有的class文件 3 Enumeration<URL> classFileEntries = bundle.findEntries("/", "*.class", 4 true); 5 if (classFileEntries == null || !classFileEntries.hasMoreElements()) { 6 throw new RuntimeException(String.format("Bundle[%s]中没有一个Java类!", 7 bundle.getSymbolicName())); 8 } 9 // 得到其中的一个类文件的URL 10 URL url = classFileEntries.nextElement(); 11 // 得到路径信息 12 String bundleOneClassName = url.getPath(); 13 // 将"/"替换为".",得到类名称 14 bundleOneClassName = bundleOneClassName.replace("/", ".").substring(0, 15 bundleOneClassName.lastIndexOf(".")); 16 // 如果类名以"."开头,则移除这个点 17 while (bundleOneClassName.startsWith(".")) { 18 bundleOneClassName = bundleOneClassName.substring(1); 19 } 20 Class<?> bundleOneClass = null; 21 try { 22 // 让Bundle加载这个类 23 bundleOneClass = bundle.loadClass(bundleOneClassName); 24 } catch (ClassNotFoundException e) { 25 throw new RuntimeException(e); 26 } // 得到Bundle的ClassLoader 27 return bundleOneClass.getClassLoader(); 28 29 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。