初始Karaf

OSGi和Karaf

Karaf是一种OSGi框架,那么OSGi代表着什么呢?OSGi(Open Service Gateway Initiative)是一个由OSGi联盟发起的以Java为技术平台的动态模块化规范。
简单来说,大家都用过Spring IOC容器,其主要作用就是根据配置信息解析bean(其实就是类实例)之间的依赖关系,从而创建所需的bean。而OSGi框架和容器类似,只不过加载的东西由bean变成了模块。OSGi的基本单位就是模块(Bundle)。Bundle简单来说,就是在Jar包基础上,扩展了Bundle元数据信息、特定含义的程序和资源等。所以,OSGi框架就是能在运行中自由加载和卸载Bundle,从而完成各种功能。
Karaf作为OSGi框架,在其上又扩展了一个概念-Feature。Feature其实就是一组Bundle的集合,加载一个Feature就等于加载一组Bundle。可以说,Feature是一种更高层次的聚合表示,能够简化Bundle间的依赖关系。

Karaf使用

根据http://liquid-reality.de/Karaf-Tutorial/01/,可以很顺利地安装Karaf,并且从得到一个简单的Demo(Tasklist)。

git clone https://github.com/cschneider/Karaf-Tutorial.git

Tasklist

很多博客也是直接用这个例子进行说明,但很多细节都没有提到,对于初学者非常不友好。下面我会对这个Demo进行详细说明。

目录结构

tasklist
 |- tasklist-model
 |- tasklist-persistence
 |- tasklist-command
 |- tasklist-ui
 |- tasklist-feature
     |- features.xml

tasklist的目录结构大致如上所示(略去了不重要的目录和文件)。

tasklist-model

其中有两个类(供其他Bundle使用):

  1. Task:只有get和set方法。
  2. TaskService:一个接口。

tasklist-persistence

提供了一个TaskService的简单实现,即使用一个HashMap来存储任务。并且调用构造函数时就会存储两个任务:

  1. Task(1, “Buy some coffee”, “Take the extra strong”)
  2. Task(2, “Finish karaf tutorial”, “Last check and wiki upload”)

tasklist-command


这个注解的意思是,使task命令在Karaf全局可见,并且task下还有三个子命令add,list,get:

  • add:添加Task
  • list:列举当前的Task
  • get:根据taskId,得到相应Task

tasklist-ui

继承HttpServlet,对于Http请求:

  • 若包含taskId,则返回相应Task的详细描述
  • 若不包含taskId,则显示所有Task。

features.xml

这个文件是最关键的,定义了三个Feature:

  • example-tasklist:既有对Task的持久化,又支持UI。
  • example-tasklist-persistence:支持Shell命令和持久化,但不支持UI。
  • example-tasklist-ui:依赖其他Feature(如http,http-whiteboard),支持UI,但不支持Shell命令和持久化。

运行Karaf

首先需要在tasklist目录下运行mvn clean install将各个模块打包成Bundle并存入Maven仓库。

  1. feature:repo-add命令从mvn本地仓库中net/lr/tasklist/tasklist-features/1.0.0-SNAPSHOT目录下读取tasklist-features-1.0.0-SNAPSHOT.xml中的Feature配置信息。
  2. feature:install命令安装example-tasklist-persistence。
  3. 此时支持了task:add/get/list命令,但不支持UI服务(在浏览器打开http://localhost:8181/tasklist)原因是tasklist-ui未激活。
  4. feature:install命令安装example-tasklist-ui,此时UI可使用。

    需要注意的是已经安装的feature,就算重启,Karaf也会保留的。如果不需要,可使用feature:uninstall卸载。