用osgi实现java的模块化和热插拔时要考虑好两个问题,不同bundle间如何通信?依赖怎么处理?

OSGi的一个标准就是各个bundle之间是相互隔离的,每个bundle都有自己的classloader,并且不同的版本之间都是相互隔离的,这样就使bundle从物理上进行了隔离,那么OSGi 的bundle之间是怎么进行通信的呢?

下面我们将要介绍3中方法。

Bundles之间通信的方法

方法 描述
1.Export-Package 根据OSGi规范,每个工程可以通过声明Exprot-Package对外提供访问此工程中的类和接口,可以先把bundle导出,再导入到需要调用的bundle中
2.OSGi服务 通过将要对外提供功能声明为OSGi的服务实现面向接口、面向服务式的设计;
3.Event 基于OSGi的Event服务也是实现模块交互的一种可选方法,模块对外发布事件,订阅了此事件的模块就会相应地接收到消息,从而做出反应,以达到交互的目的。

OSGi bundle之间互相通信的方法

在JAVA程序中,用到外部包中的类几乎是必然的事情,在OSGI和MAVEN环境下,引用外部包的方法总结如下:

1.java.开头的包,是JDK提供了,代码中直接import。

2.org.osgi开头的(包括core、compendium等),是osgi规范提供的,已经包含在osgi框架(Felix)中,开发时需要导入,但是发布程序中不需要包含,由Felix提供,实现方法是添加scope为provided的maven依赖,如:

<dependency>

<groupId>org.osgi</groupId>

<artifactId>org.osgi.core</artifactId>

<version>4.3.0</version>

<scope>provided</scope>

</dependency>

另外如果使用AS容器,而不是osgi嵌入http service,那么jee相关的包如servlet-api也是provided。

3.第三方jar包,可能有多个bundle共享的,直接osgi化,然后作为独立bundle安装到Felix中,例如commons-io-1.4.jar,Felix的WebConsole子项目依赖它,我们的很多bundle也可能用到它,开发时在maven中加入

<dependency>

<groupId>commons-io</groupId>

<artifactId>commons-io</artifactId>

<version>1.4</version>

</dependency>

部署时从maven库中找到这个jar包,然后直接放到Felix的bundle目录,启动Felix,就可以看到这个jar包作为一个独立bundle已经启动,其他bundle就可以通过直接Import-Package的方式来引用这些包。的之所以能够这么做是因为这个jar已经osgi化了,查看jar包中的META-INF/MENIFEST.MF文件,只要其中有Bundle-SymbolicName: org.apache.commons.io等一系列Bundle-*的属性值,并且有Export-Package导出内部的包就可以确定。现在大部分从maven库中获得的比较新的jar包,基本上都已经支持OSGI了。如果一个jar包确实不包含OSGI信息,也可以通过手动编辑它的MENIFEST.MF文件增加OSGI信息,来实现这个jar包独立作为bundle运行。例如json-20090211.jar,直接编辑它的MENIFEST.MF如下:

Manifest-Version: 1.0
Created-By: 1.6.0_07 (Sun Microsystems Inc.)
Export-Package: org.json
Bundle-Name: JSON
Bundle-Version: 20090211
Bundle-SymbolicName: org.json
确保jar包的格式(如果解压编辑,要重新打包,最好用解压软件直接打开编辑自动打包),然后就直接在Felix中运行了。

4.第三方的jar包,不考虑多个bundle共享,只确保一个bundle的独立依赖,可以把这些依赖的jar嵌入到开发的bundle中发布。如在开发com.ailk.common.log4j时,查看log4j的pom发现它依赖多个其他jar包(不同版本log4j依赖的jar包不一样,这里是1.2.15版本的情况)

<dependency>

<groupId>javax.mail</groupId>

<artifactId>mail</artifactId>

<version>1.4</version>

</dependency>

<dependency>

<groupId>javax.jms</groupId>

<artifactId>jms</artifactId>

<version>1.1</version>

</dependency>

<dependency>

<groupId>com.sun.jdmk</groupId>

<artifactId>jmxtools</artifactId>

<version>1.2.1</version>

</dependency>

<dependency>

<groupId>com.sun.jmx</groupId>

<artifactId>jmxri</artifactId>

<version>1.2.1</version>

</dependency>

maven中加入这些就可以在开发时引用了,但是发布到Felix框架时,我们要把这些jar包一起提供才行,方法是把这些jar包嵌入到我们的bundle中,使用maven-bundle-plugin,增加instructions配置<Embed-Dependency>*;scope=compile|runtime</Embed-Dependency>,这样maven在打包是就可以自动把这些依赖的jar包嵌入。要注意这些依赖的scope和Embed-Dependency的表述方式的匹配,具体Embed-Dependency可能的写法请参见maven-bundle-plugin在线文档。

这种方式引用外部包,好处是自带依赖,操作简单,不像方法3中那样,如果依赖jar包更新要受到影响,并且要注意多个bundle共享依赖是否有冲突。坏处是所有依赖jar包都要一起打包到bundle中,显得非常臃肿。

5.自己开发的bundle之间,互相引用其他bundle的包,被引用者注意要Export-Package,并打包部署到maven库,其他引用的bundle在开发阶段通过maven依赖直接引用,在部署时确保几个管理的bundle同时都在Felix中并且resolved。

6.嵌入包瘦身,针对上面第四点,在嵌入第三方包到bundle时,如果完全按照pom中指定的依赖全部打包进bundle,bundle体积会比较大,但是这些jar包是否全部都是必须的呢?不一定。例如log4j的pom指定依赖javax.mail的mail.jar,但是如果不使用mail方式的appender,这个jar基本上是用不到的。同样mybatis的pom中也包含了5种log实现作为依赖,包括log4,slf4j,common-logging等,但是实际上这个日志功能并不是必须全部具备,嵌入全部这些log实现的jar就显得多余。但是如果在pom中不配置这些jar包的依赖,开发编译阶段没有问题,但是bundle在resolve的过程会包缺少需要的package。解决方法是在pom中仍然加入这些Jar包的依赖,但是增加一个<optional>true</optional>的属性,同时修改打包instructions为<Embed-Dependency>*;scope=compile|runtime;optional=!true</Embed-Dependency>。经验证,这做是可以的,log4j的bundle不再包含mail,jms,jmxtools,jmxri几个jar包后,体积减少了一半以上,功能不受影响。

http://blog.csdn.net/rosen_luo/article/details/47398391

OSGI依赖问题处理的更多相关文章

  1. [OSGI]Eclipse4.2 OSGI依赖Bundle

    Eclipse 4.2 OSGI 依赖的Bundle: org.eclipse.osgiorg.apache.felix.gogo.runtimeorg.apache.felix.gogo.comma ...

  2. JVM笔记11-类加载器和OSGI

    一.JVM 类加载器: 一个类在使用前,如何通过类调用静态字段,静态方法,或者new一个实例对象,第一步就是需要类加载,然后是连接和初始化,最后才能使用. 类从被加载到虚拟机内存中开始,到卸载出内存为 ...

  3. OSGi学习-总结

    本文是osgi实战一书的前几章读书总结 1.  OSGi简介 Java缺少对高级模块化的支持,为了弥补Java在模块化方面的不足,大多数管理得当的项目都会要求建立一整套技术,包括: 适应逻辑结构的编程 ...

  4. [转载] 高效 MacBook 工作环境配置

    原文: http://mp.weixin.qq.com/s?__biz=MjM5NzMyMjAwMA==&mid=208231200&idx=1&sn=8a76ddc56c1f ...

  5. [转载] 高效MacBook工作环境配置

    原文: http://www.xialeizhou.com/?p=71 高效MacBook工作环境配置 发表于 2015 年 8 月 1 日 由 xialeizhou 本文记录整个配置过程,供新入手M ...

  6. Win7安装和配置Tigase 5.2server

    Win7安装和配置Tigaseserver 笔者:chszs,转载注明. 博客首页:http://blog.csdn.net/chszs 1.下载tigase-server-5.2.0-b3447.e ...

  7. 高效 MacBook 工作环境配置

    转自:https://mp.weixin.qq.com/s/sloc6HgKcosXtWcbMB_5hA 工欲善其事,必先利其器,工具永远都是用来解决问题的,没必要为了工具而工具,一切工具都是为了能快 ...

  8. 高效 MacBook 工作环境配置,超实用!

    作者:正鹏 & 隃墨 http://www.xialeizhou.com/?p=71 前言 工欲善其事,必先利其器,工具永远都是用来解决问题的,没必要为了工具而工具,一切工具都是为了能快速准确 ...

  9. OSGI中的service依赖关系管理

    众所周知.对于高动态高可扩展的应用,OSGI是一个很好的平台.可是.也因此添加了复杂性.开发中对service的依赖变得复杂. 这也是service的关系管理成为OSGI中一个很重要的部分,我们来看看 ...

随机推荐

  1. Centos6.6 安装nfs网络文件系统

    一.介绍 nfs网络文件系统的,大部分用在内网文件共享,比如,对集群上传文件做共享,经常用在图片部分,当然数据量大了还是要做分离,做为专门的接口比较好,介绍一下基本安装环境: 1)Cnetos6.6 ...

  2. 如何创建一个项目,让gitlab自动触发jenkins进行构建

    前进是:你已经配置好jenkins+gitlab自动化布置了,这里只是常规构建新的项目时,需要做的配置,记录下来,以免忘了又着急 参考这篇博客: https://www.jianshu.com/p/e ...

  3. Centos7搭建ansible运维自动化工具

    1)设置主机名和hosts文件 2)配置阿里云repo源 Wget -O /etc/yum.repos.d/aliyun.repo https://mirrors.aliyun.com/repo/Ce ...

  4. IDEA生成增强for循环

    itar 生成array for代码块 for (int i = 0; i < array.length; i++) { = array[i]; } itco 生成Collection迭代 fo ...

  5. 阅读《JavaScript设计模式》第二章心得

    面向对象编程 面向对象编程就是将你的需求抽象成一个对象.然后针对这个对象分析其特征(属性)与动作(方法).这个对象我们称之为类.面向对象编程思想其中的一个特点就是封装. 1.私有属性.私有方法.特权方 ...

  6. centos中安装jdk

    1.上传jdk安装文件到根目录 2.解压到相关目录 (1)创建相应目录mkdir -p /usr/local/java (2)解压 tar -zxvf jdk-7u80-linux-x64.tar.g ...

  7. mongodb数据库的导出与导入

    数据库的导出 导出类型为json,数据库:mapdb,集合:bike 字段:bikeId,lat,lng,current_time,source ,条件为source字段为ofo第一条数据 mongo ...

  8. 【Codeforces Global Round 1 A】Parity

    [链接] 我是链接,点我呀:) [题意] 给你一个k位数b进制的进制转换. 让你求出来转成10进制之后这个数字是奇数还是偶数 [题解] 模拟一下转换的过程,加乘的时候都记得对2取余就好 [代码] im ...

  9. noip模拟赛 计数

    [问题描述] 给出m个数a[1],a[2],…,a[m] 求1~n中有多少数不是a[1],a[2],…,a[m]的倍数. [输入] 输入文件名为count.in. 第一行,包含两个整数:n,m 第二行 ...

  10. 关于Linux的本地回环路由lo [127.0.0.1 ]

    最近 打算配开发板的socket通讯,打印环境变量发现却没有 127.0.0.1 / # ifconfig -a eth0 Link encap:Ethernet HWaddr 86:43:C9:A1 ...