Equinox加载Bundle Class的实现

发表于:2011-11-25 10:57

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:building block    来源:51Testing软件测试网采编

#
java
分享:

  Equinox在创建Bundle的ClassLoader时,首先获取bundle的classpath,然后执行createBCLPrevileged方法,此方法最后转交由BaseData来创建ClassLoader。

  BaseDate创建ClassLoader的关键代码片段为:

  • ClassLoadingHook[] hooks = adaptor.getHookRegistry().getClassLoadingHooks(); 
  •     ClassLoader parent = adaptor.getBundleClassLoaderParent(); 
  •     BaseClassLoader cl = null
  •     for (int i = 0; i < hooks.length && cl == null; i++) 
  •        cl = hooks[i].createClassLoader(parent, delegate, domain, this, bundleclasspath); 
  •     if (cl == null
  •        cl = new DefaultClassLoader(parent, delegate, domain, this, bundleclasspath); 
  •     return cl;
  •   在Equinox中,默认的情况下adaptor.getBundleClassLoaderParent返回的为bootstrap classloader,可通过修改启动的osgi.parentClassLoader 来改变这个parent classloader,

      osgi.parentClassLoader 的可选值有四个,分别是:

      ● boot:默认

      ● app:SystemClassLoader

      ● ext:SystemClassLoader的parent

      ● fwk:启动Equinox的ClassLoader

      ClassLoadingHook在createClassLoader的时候都没有做动作,因此最后ClassLoader都是通过创建DefaultClassLoader对象来构建的,其中parent参数为null,delegate参数为BundleLoader实例,bundleclasspath参数为bundle的classpath。

      经过以上步骤后,完成了ClassLoader的创建,可以开始加载class了,根据上面上述,Bundle的Class就由DefaultClassLoader来完成了。

      查看DefaultClassLoader的loadClass代码,发现真正的加载class的过程是转为调用了delegate 的findClass来完成的,delegate参数对应的为BundleLoader实例,转为跟踪BundleLoader的findClass方法。

      BundleLoader的findClass方法的代码片段:

  • if (checkParent && parentCL != null && name.startsWith(JAVA_PACKAGE)) 
  •    return parentCL.loadClass(name);
  •   从以上这个代码片段,可以看到,Equinox将java.开头的类转交给了parent classloader去加载,这也意味着没必要在系统中提供对外export java.开头的package。

      如果不是java.开头的类,则交由findClassInternal方法来完成加载。

      findClassInternal方法遵循的为OSGi规范中定义的Class的加载顺序,不过仍然稍有改动:

      1)判断是否交由parent classloader去完成加载

      在启动Equinox时,Equinox会读取org.osgi.framework.bootdelegation属性,该属性对应配置的为需要从parent classloader中加载的package,如值配置的为*,说明所有的都从parent classloader中加载 ,如值配置的为具体的package,那么则放入bootDelegation集合;如配置的为带通配符的package,那么则放入bootDelegationStems集合。

      判断时Equinox首先判断是否所有的都从parent classloader中加载,如是则从parent classloader中加载;

      如需要加载的类的package位于bootDelegation或bootDelegationStems集合中,那么同样从parent classloader中加载。

      如不从parent classloader中加载,则进入下面的步骤。

    21/212>
    《2023软件测试行业现状调查报告》独家发布~

    关注51Testing

    联系我们

    快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

    法律顾问:上海兰迪律师事务所 项棋律师
    版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
    投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

    沪ICP备05003035号

    沪公网安备 31010102002173号