用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. html5——css选择器

    复习 div>p: 子代 div+p:div后面相邻的第一个p div~p: div后面所有的兄弟p 属性选择器 标志:[]:区别于id选择器:#,区别于类名选择器:. 特殊符号:^:开头    ...

  2. 仿win8磁贴界面以及功能

    做移动产品界面占很大的一部分,同时也是决定一款产品好的的重要因素,最近看见有人放win8的界面效果,搜了两款,一款是只是仿界面没有特效,另一款是自定义组件能够实现反转效果,今天分析一下这两类界面. 仿 ...

  3. VS2015编译ffmpeg的问题解决

    刚装了vs2015,打开一些ffmpeg项目,发现不能编译通过,包括stdio.h都无法找到,可能是vs2015的bug吧. 现在记录一下解决方法: 我的目录是这样定义的: C:\Program Fi ...

  4. apache配置多域名二级域名

    nginx配置多域名泛解析的看这个链接:https://www.cnblogs.com/Crazy-Liu/p/10879740.html 下面直接来操作: [root@localhost ~]# f ...

  5. 安装hiredis后swoole扩展消失

    php -m报错: PHP Warning: PHP Startup: Unable to load dynamic library 'swoole' (tried: /home/work/study ...

  6. LNMP动态网站架构及web应用部署,搭建discuz论坛

    1)部署Nginx 实验tar安装包可找本人拿记得点+关注,感谢亲们支持,评论拿包 systemctl stop firewalld iptables -F setenforce 0 1)安装支持软件 ...

  7. jquery 实现 单选框点击取消

    <label for="1" class="z-label"> <input type="radio" class=&qu ...

  8. Django URL(路由系统)

    Django URL Django 1.11版本 URLconf官方文档 URL配置(URLconf)就像 Django 所支撑网站的目录.它的本质是URL模式以及要为该URL模式调用的视图函数之间的 ...

  9. 腾讯云&硬盘信息

    fly@UBT-sCloud:~/pub_work/05-ARM/00-s5pv210$ sudo fdisk -lDisk /dev/ram0: 64 MiB, 67108864 bytes, 13 ...

  10. 7.1.2 Python 内置异常类层次结构

    这一节就是拿来主义了,连接:https://blog.csdn.net/Karen_Yu_/article/details/78629918 异常名称 描述 BaseException 所有异常的基类 ...