`
candy1234
  • 浏览: 3814 次
  • 性别: Icon_minigender_1
  • 来自: 珠海
社区版块
存档分类
最新评论

OSGi Bundle解析源码分析

    博客分类:
  • OSGi
阅读更多
Bundle的解析过程就是对Bundle的MF文件进行分析,根据配置的依赖关系构造依赖模型。
(源码见:ResolverImpl.resolveBundles0)
假设有2个Bundle,import/export分别是:
BundleA:import pkg.b; export pkg.a; BundleB:import pkg.a; export pkg.b;也就是2个Bundle相互依赖

解析步骤(主要部分):

1、假设首先对BundleA解析,先获取BundleA的所有imports,然后迭代每个import找到匹配的export,并设置import和export的依赖引用关系。
// 设置了依赖引用关系后就知道import是由哪个Bundle导出
export.getExporter().addRef(imp.getBundle());
imp.addPossibleSupplier(export); // 找到pkg.b的一个可能的提供者为BundleB导出的pkg.b
但是,如果自己也export了相同的包,则会被舍弃,会采用它依赖的export。因此,如果一个Bundle import了一个同名的包(自己Bundle也有,而且不管有没有export),则永远不会找到自己包下的类(根据类查找规则,会在依赖的export下寻找)。也就是说,Bundle中包命名一定要注意不要同名。

2、如果export所在的bundle不是已解析(resolved)的,这里的BundleB还没有解析,则开始解析BundleB,同步骤1。
当在解析BundleB的import pkg.a时,发现BundleA还不是已解析(resolved)的(正在解析中resolving),又对BundleA进行解析,同步骤1。
但是,当解析到import pkg.b时,发现它已经有提供者了(前面已经找到了匹配的export),就把该BundleA添加到依赖循环列表中。
这里,BundleA解析结束(没有其他未解析的import了)返回,但状态还是resolving。接着,发现import pkg.a的提供者BundleA为resolving,又把该BundleB添加到依赖循环列表中。
这里,BundleB解析结束(没有其他未解析的import了)返回,但状态还是resolving。

3、循环依赖处理
对解析BundleA涉及的依赖环列表进行依赖检查,如果里面所有Bundle都能正确的找到依赖,则设置它们的状态为已解析(resolved)。

该过程涉及到的相关实体:

Version:表示Bundle或者Package的版本对象。对应的还有个VersionRange,表示版本范围。

VersionSupplier:版本提供者基类,表示一个特定版本的Bundle或者Package(系统可以同时存在多个版本的Bundle或者Package)。

VersionHashMap:用于保存VersionSupplier,它的键为Bundle或者Package的名称,值为与之对应的多个版本构成的数组,定义如下(在父类MappedList中):
	// the mapping with key -> Object[] mapping 
	protected HashMap internal = new HashMap(); 

该对象用来保存系统所有解析的的exports、bundles和generics(在ResolverImpl中实现)。

对于多个版本的情况,是如何处理的呢?实现了Comparator接口,在compare中处理排序逻辑,源码如下:
    // Compares two VersionSuppliers for descending ordered sorts.   
    // The VersionSuppliers are sorted by the following priorities   
    // First the resolution status of the supplying bundle.   
    // Second is the supplier version.   
    // Third is the bundle id of the supplying bundle.   
    public int compare(Object o1, Object o2) {   
        if (!(o1 instanceof VersionSupplier) || !(o2 instanceof VersionSupplier))   
            throw new IllegalArgumentException();   
        VersionSupplier vs1 = (VersionSupplier) o1;   
        VersionSupplier vs2 = (VersionSupplier) o2;   
        // if the selection policy is set then use that   
        if (resolver.getSelectionPolicy() != null)   
            return resolver.getSelectionPolicy().compare(vs1.getBaseDescription(), vs2.getBaseDescription());   
        String systemBundle = resolver.getSystemBundle();   
        // 系统Bundle优先
        if (systemBundle.equals(vs1.getBundle().getSymbolicName()) && !systemBundle.equals(vs2.getBundle().getSymbolicName()))   
            return -1;   
        else if (!systemBundle.equals(vs1.getBundle().getSymbolicName()) && systemBundle.equals(vs2.getBundle().getSymbolicName()))   
            return 1;   
        // 已解析的优先于未解析的
        if (vs1.getBundle().isResolved() != vs2.getBundle().isResolved())   
            return vs1.getBundle().isResolved() ? -1 : 1;  
        // 版本高的优先 
        int versionCompare = -(vs1.getVersion().compareTo(vs2.getVersion()));   
        if (versionCompare != 0)   
            return versionCompare;   
        // Bundle Id小的优先(优先安装的优先)
        return vs1.getBundle().getBundleId() <= vs2.getBundle().getBundleId() ? -1 : 1;   
    }  


BaseDescription:对一个状态的基本描述,所有的描述对象都有一个名称和版本。

VersionConstraint:表示2个Bundle(就require bundle而言)或一个Bundle和一个Package之间的关系(就import/export而言)。
方法isSatisfiedBy(BaseDescription supplier)用来判断约束是否满足。


ResolverConstraint:VersionConstraint辅助类。

GroupingChecker:检查导出包“uses”指令的一致性。 这是一个比较耗时的操作。
分享到:
评论

相关推荐

    Eclipse-OSGi内核源码分析

    在Eclipse-OSGi的内核源码分析中,会涉及到对Bundle接口的实现,该接口定义了Bundle的基本行为和属性。 Bundle接口提供了对Bundle状态的管理,具体包括Bundle的操作方法,如启动、停止、更新和卸载,以及获取Bundle...

    Eclipse-OSGi内核源码分析.pdf

    Eclipse OSGi框架内核源码分析还需考虑如何处理Bundle之间的依赖关系,例如动态加载类和资源,以及处理依赖项的解析。当一个Bundle需要其他Bundle提供的服务时,它必须声明这些依赖项,并在运行时由OSGi框架解析这些...

    基于osgi框架实战源码

    标题"基于osgi框架实战源码"揭示了本次学习的主题,即OSGi框架在实际项目中的应用。"osgi实战源码"这一描述进一步强调了这是一份可以动手实践的源代码,它以一个具体的购物车案例为背景,展示了如何在项目中运用OSGi...

    浅析OSGI的bundle依赖

    当bundle启动时,OSGI框架会解析其MANIFEST.MF文件中的元数据,识别出依赖的其他bundle,并确保这些依赖项已启动并可用。 在OSGI中,bundle的依赖关系主要通过MANIFEST.MF文件来定义。这个文件包含了bundle的基本...

    OSGI实战及源码

    通过实际操作和源码分析,读者可以掌握如何构建、部署和管理OSGI模块化的应用。 OSGI实战部分可能会涵盖以下关键知识点: 1. **OSGI基本概念**:介绍OSGI的基本架构,包括Bundle、Service、生命周期管理(启动、...

    blueprint-osgi-bundle:OSGi 示例

    **文件名称列表解析:** "blueprint-osgi-bundle-master" 可能是项目源代码的主分支,通常包括项目的所有源码、资源文件、构建脚本等,用于克隆或下载到本地进行开发和学习。 **详细知识点:** 1. **OSGi框架**:...

    org.eclipse.osgi_3.7.0.v20110613及源码

    四、源码分析 org.eclipse.osgi-3.7.0.v20110613-sources.jar文件包含了org.eclipse.osgi的源代码,对于开发者来说,这是理解和学习OSGi框架内部运作的重要资源。通过阅读源码,我们可以看到如何创建和管理bundle,...

    tomcat 集成 osgi服务,示例源码

    5. **源码**:提供的源码可能包括了Tomcat的扩展或插件,用于实现OSGi服务的生命周期管理,如启动、停止、更新bundle。 6. **文档**:文档通常会包含集成步骤、配置指南、常见问题解答等,帮助开发者理解和实施...

    OSGi原理与最佳实践的源码

    3. **分析依赖解析**:通过查看类加载器和MANIFEST.MF解析逻辑,理解OSGi如何处理模块间的依赖。 4. **学习模块化设计**:通过源码,我们可以学习如何将一个大型项目拆分为多个模块,并合理定义它们之间的交互。 ...

    OSGI错误分析解决

    当bundle之间存在依赖关系时,如果没有正确声明或解析,就可能导致错误。 描述中提到的链接指向了一个博客文章,虽然内容未给出,但通常这样的资源会包含具体错误案例、分析过程和解决方法。在实际问题排查中,日志...

    osgi-in-action源码.rar

    《OSGi实战》源码分析 OSGi(Open Services Gateway Initiative)是一种Java模块化系统,它为构建可扩展、模块化的应用程序提供了强大的框架。OSGi的核心特性是动态性,允许在运行时安装、卸载、启动和停止服务,极...

    很久之前的osgi整理

    标题 "很久之前的osgi整理" 暗示了这篇内容可能涉及的是OSGi(OSGi Alliance)技术的早期分析或教程,这是一个用于Java应用程序模块化的框架。在Java开发中,OSGi允许开发者将大型应用分解为独立的、可重用的模块,...

    osgi学习笔记(二)

    9. **源码分析** 学习OSGi时,深入理解源码可以帮助开发者更好地掌握其实现原理。例如,可以研究Apache Felix或Equinox的源码,了解它们如何处理bundle的加载、依赖解析和服务注册等核心功能。 10. **挑战与解决...

    OSGi与Equinox 创建高度模块化的Java系统 第4章完整源码

    这包括bundle的加载、解析、启动和停止等操作,以及如何通过Equinox API与OSGi服务进行交互。 3. **Bundle开发**:学习如何编写符合OSGi规范的Java代码,创建bundle的manifest.mf文件,声明导出和导入的包,配置元...

    osgi spring实例

    至于压缩包内的"整合代码原版",这可能是一个完整的项目源码,包括了OSGi和Spring的配置文件、服务定义、bundle实现、启动脚本等。开发者可以通过分析这些代码,了解如何在OSGi环境下配置和管理Spring应用,以及如何...

    osgi学习笔记(一)

    在《OSGI进阶.pdf》这本书中,可能涵盖了更深入的话题,比如bundle的打包和部署、服务注册与查找、bundle间通信的协议(如白板模式和Declarative Services)以及如何使用OSGi进行企业级应用开发。这本书可能会详细...

    ext.bundle.osgi.common-1.0.8.zip

    《深入解析Gradle Android插件:ext.bundle.osgi.common-1.0.8.zip与开源项目的融合》 在当今的移动应用开发领域,Android Studio作为主要的集成开发环境,Gradle作为其默认的构建工具,已经成为了开发者不可或缺的...

Global site tag (gtag.js) - Google Analytics