版权声明:可以任意转载,转载时请标明文章原始出处-ScriptShi
网上的 osgi的资料相对比较少,且复制性很差,照着执行了几个博客都不可以。但是我这里的可复制性为100%!大部分都是算原创的。
osgi 是java的动态模块化运行技术,目前开源的osgi实现有很多,这里我们采用apache的felix来进行实现。
主要完成了直接使用maven来开发osgi,而不是idea,idea写出来的bundle在运维部署的可行性太差了,所以我们把maven做osgi的坑走一遍。
osgi 生命周期
OSGI框架负责Bundle的安装、卸载等,定义了Bundle的生命周期,完整的生命周期状态转移图:
对于启动过程状态从 INSTALLED -> RESOVLED -> STARTING -> ACTIVE
- INSTALLED:表示Bundle已经通过OSGI框架的有效性校验并产生了唯一的Bundle ID。
- RESOVLED:表示OSGI框架已解析MANIFEST文件中描述的依赖。
- STARTING:该状态是一个瞬态,会调用BundleActivator start函数,如果未抛出异常则转到ACTIVE否则退回到RESOLVED状态。
- ACTIVE:表示Bundle已成功启动。
类加载机制不同于常用的层次化加载,OSGI为每个Bundle提供了一个ClassLoader,由于不同Bundle之间会相互调用, 导致OSGI类加载模型的依赖关系并不是层次化的而是网络状的。
代码
https://github.com/xjtushilei/osgi-demo
需要注意的地方,我在代码文件(主要是配置文件)的TODO
有说明
实验环境
Apache Maven 3.5.2 (138edd61fd100ec658bfa2d307c43b76940a5d7d; 2017-10-18T15:58:13+08:00)
Maven home: C:\Users\script\apache-maven-3.5.2\bin\..
Java version: 1.8.0_144, vendor: Oracle Corporation
Java home: C:\Program Files (x86)\Java\jdk1.8.0_144\jre
Default locale: zh_CN, platform encoding: GBK
OS name: "windows 10", version: "10.0", arch: "x86", family: "windows"
模块说明
felix-framework-6.0.0
Apache Felix是Apache软件基金会赞助的一个OSGI容器,这里下载的是官方的felixhelloworld
是纯粹的一个boudle,没使用第三方包helloworlduseotherjar
使用了第三方包 lang3
运行过程
linux 与 windows 的反斜杠方向不一样自行调整
打包 bundle
# 在工程的根目录下:
# 打包模块1
cd hello-world
mvn package
# 打包模块2
cd ..
cd hello-world-use-other-jar
mvn package
启动 osgi 容器
# 在工程的根目录下:
cd felix
# 一定要在felix目录下才能执行成功,不知道felix这个包什么目的!
java -jar \bin\felix.jar
结果如下:
____________________________
Welcome to Apache Felix Gogo
g!
安装 与 运行 bundle
install ../hello-world/target/hello-world-1.0.jar
install ../hello-world-use-other-jar/target/hello-world-use-other-jar-1.0.jar
# 显示目前有哪些boudle
lb
lb结果如下:
START LEVEL 1
ID|State |Level|Name
0|Active | 0|System Bundle (6.0.0)|6.0.0
1|Active | 1|jansi (1.17.1)|1.17.1
2|Active | 1|JLine Bundle (3.7.0)|3.7.0
3|Active | 1|Apache Felix Bundle Repository (2.0.10)|2.0.10
4|Active | 1|Apache Felix Gogo Command (1.0.2)|1.0.2
5|Active | 1|Apache Felix Gogo JLine Shell (1.1.0)|1.1.0
6|Active | 1|Apache Felix Gogo Runtime (1.1.0)|1.1.0
10|Installed | 1|hello-world (1.0.0)|1.0.0
11|Installed | 1|hello-world-use-other-jar (1.0.0)|1.0.0
可以看到我们安装了两个 bundle,接下来启动我们的 bundle
start 10
# Hello World Bundle started!
start 11
# Hello World (UseOtherJar) Bundle started!
# 106
停止运行我们的 bundle
stop 10
# Hello World Bundle stop!
stop 11
# Hello World锛堜娇鐢ㄧ涓夋柟鍖咃級 Bundle stop!
# 1.600441E38
可能是windows的cmd里是gbk编码,汉语在console里发生了乱码。无关紧要。
其他命令
现有的名字空间有三种:
- felix - 关于felix框架的核心命令,比如列出所有bundle,安装/卸载bundle等等
- gogo - 包含grep,cat,echo这类的指令,并且gogo是个Felix的子项目,他是参照RFC 147来实现的,这个标准定义了OSGi环境的shell应该是怎么样的。
- obr - 关于OSGi Bundle Repository功能的指令
命令有三个大类,目前我们暂时只使用了其中一种 felix
,我们输入help
可以看到所有的命令
help
查看有哪些命令uninstall
取消安装 bundleexit 1
退出 osgi 容器lb
显示目前有哪些 bundless
显示已安装的bundles的状态信息,信息包括bundle ID,短名,状态等等。start
启动一个bundlestop
关闭一个bundleupdate
载入一个新的JAR文件更新一个bundleinstall
安装一个新的bundle到容器中uninstall
卸载一个已在容器中的bundle
MANIFEST.MF 说明
Bundle-Name
给bundle定义一个短名,方便人员阅读Bundle-SymbolicName
给bundle定义一个唯一的非局部名。方便分辨。Bundle-Activator
声明在start和stop事件发生时会被通知的监听类的名字。Import-Package
定义bundle的导入包。
解决jar冲突的示例代码
又通过服务注册的方式进行了jar冲突的解决。
见分支
https://github.com/xjtushilei/osgi-demo/tree/communication