Apache Karaf是一个强大的OSGi容器。它为发布OSGi应用程序提供了支持。
一个OSGi程序是由一系列OSGi bundles组成的。OSGi bundle 是一个在MANIFEST中带有附加元数据的jar文件。
在OSGi中,一个bundle可以依赖于其它的bundles。因此,大部分情况下,在部署一个OSGi应用程序之前,你需要先把这个应用程序需要的其它bundles部署上。
如何部署这些需要的bundles呢?首先你要找到这些bundles(上网或者本地有包),然后install这些包(install+name)。这时候请注意,这些被依赖的bundles也可能还依赖于其它bundles,你要要部署上。
此外,和我们用别的框架做的应用程序一样,OSGi应用程序也需要有配置文件(在etc目录下)来定义一些变量(http://karaf.apache.org/manual/latest/users-guide/provisioning.html)。所以,在你启动一个程序之前,除了要部署它所依赖的bundles之外,还必须要创建和部署配置文件。
我们把部署一个应用程序所需的bundles和configuration到容器中的过程,叫做“配置”。正如我们所看到的一样,这种“配置”有时候需要的文件会很多,并且要很准确。
Apache Karaf为我们提供了一种简单、灵活的方式来配置和发布OSGi应用程序。在Karaf中,使用Apache Karaf feature来实现这种配置。
Feature的定义:
a namea versiona optional description (eventually with a long description)a set of bundlesoptionally a set configurations or configuration filesoptionally a set of dependency features
当你install一个feature的时候,karaf 会install feature中所定义的全部的资源。它会自动地解析和install所有定义的bundles、配置文件以及它所依赖的其它的features(feature中还可以定义features)。
Features通过它自定义的XML标签来描述。一个XML文件可以包含多个features。这个文件也被成为feature资源文件。注意,在install一个feature之前,你还需要使用使用feature:repo-add 来注册这个资源。下面是一个feature文件的实例:
<features xmlns="http://karaf.apache.org/xmlns/features/v1.2.0">
<feature name="feature1" version="1.0.0">
<bundle>...</bundle>
<bundle>...</bundle>
</feature>
<feature name="feature2" version="1.1.0">
<feature>feature1</feature>
<bundle>...</bundle>
</feature>
</features>
你可以看到Feature的XML描述文件有它自己的一套模式,详情可以查看用户使用手册。(链接地址http://karaf.apache.org/manual/latest/users-guide/provisioning-schema.html)。
feature1略; feature2的版本为1.1.0,它的元素中包含了一个对feature1的引用和一个bundl,
你可以在标签中明确地指定使用哪个版本(<feature version="1.0.0">feature1</feature>),你也可以不指定,karaf会install最近更新的、稳定的版本。当你使用feature:install来安装feature2时,karaf会自动安装feature1和bundle。
一个feature资源(repository)是通过在XML中使用URL(这个URL是feature特定的URL来定义的,如mvn:org.apache.karaf.features/standard/3.0.2/xml/features)来注册。
安装好的features会保存在karaf的缓存(cache:在data目录下)中,这样你之前安的features资源在你重启karaf之后仍然会保留。如果你执行了clean并重启karaf或者删除了karaf cache,所有之前安的features资源就会丢失,你就需要再手动安装一遍。为了防止出现这种情况,你可以制定features为boot类型的。
什么是boot features?一个boot feature会被karaf自动安装,即使它没有提前使用feature:install安装。这个配置在etc/org.apache.karaf.features.cfg文件中,文件中有两个属性被用来定义boot features。
featuresRepositories features repositories (features XML) URLs集合featuresBoot 需要预装的features
目前,karaf还没有为features提供完整的升级周期。基本上,一个feature升级包括两步:
首先卸载掉(uninstall)features (最好能明确地指定版本)和features repository.Register the new version of the features repository and install the features with the target version.
默认情况下,通过feature来部署的bundles都有一个start-level,在etc/config.properties配置文件中,使用karaf.startlevel.bundle(80)属性来设置。这个值也可以使用XML中元素<bundle/>的start-level属性来override。例如下面,确保myproject-dao在my-project中其它的bundles之前被启动。
<feature name="my-project" version="1.0.0">
<bundle start-level="80">mvn:com.mycompany.myproject/myproject-dao</bundle>
<bundle start-level="85">mvn:com.mycompany.myproject/myproject-service</bundle>
</feature>
处理使用start-level,一个更好的解决方式是在myproject-service中添加对myproject-dao的依赖,让OSGi框架来决定启动顺序,这个会比设置start-level更健壮。
你可以install一个bundle但是不启动它。feature中的bundles默认是自动启动的。当然也可以指定bundle不自动启动(处于resolved状态),只要在 <bundle/>元素中指定start为false即可。
<feature name="my-project" version="1.0.0">
<bundle start-level="80" start="false">mvn:com.mycompany.myproject/myproject-dao</bundle>
<bundle start-level="85" start="false">mvn:com.mycompany.myproject/myproject-service</bundle>
</feature>
备注:在karaf 3.0.0以前还没有start这个属性,需要在etc/org.apache.karaf.features.xml中指定respectStartLvlDuringFeatureStartup 属性为false,并且4.0之后将不再使用这种配置文件的方式了。
通过使用<bundle/>元素中的dependency 属性,一个bundle可以被标注为一个被依赖对象。这个信息被用来分析出将要被安装的bundles的完整集合。
一个feature可以依赖于其他的feature集合, 当安装my-project的时候,other也会自动安装。
<feature name="my-project" version="1.0.0">
<feature>other</feature>
<bundle start-level="80" start="false">mvn:com.mycompany.myproject/myproject-dao</bundle>
<bundle start-level="85" start="false">mvn:com.mycompany.myproject/myproject-service</bundle>
</feature>
还可以为依赖的feature的版本号定义一个范围,karaf会安装最高可用版本的feature。如果指定了版本就会安装这个版本的。
<feature name="spring-dm">
<feature version="[2.5.6,4)">spring</feature>
...
</feature>
Feature XML文件中的 <config/>元素允许feature创建和/或复制配置(通过configuration PID来区分)。<config/>中的name就是PID,安装之后相当于在etc文件中添加了一个com.foo.bar.cfg文件。
<config name="com.foo.bar">
myProperty = myValue
</config>
<config/>元素中的主要内容是key=value的属性集合。除了使用<config/>,还可以使用 <configfile/>元素代替直接手动操作karaf的配置,使用finalname 指定文件目的地址的相对路径,根目录为KARAF_BASE 的值,URL为文件的原路径(可以是karaf提供的任意URL,详情请看http://karaf.apache.org/manual/latest/users-guide/urls.html),当目标地址已经存在该文件的时候,通过设置override为true或false来选择是否替换原文件。 (好处:通过改变文件,就不需要在feature.xml中进行修改了)。
<configfile finalname="/etc/myfile.cfg" override="false">URL</configfile>
一个feature接收一个resolver属性,强制为feature指定一个用户,当安装这个feature的时候,这个用户将持有这些安装的bundles。不指定的时候是默认用户,可以用install a OBR来代替默认用户,(这个不是命令,详情请看http://karaf.apache.org/manual/latest/users-guide/obr.html)。
<feature name="my-project" version="1.0.0" resolver="(obr)">
...
</feature>
命令:
feature:repo-list:列出所有注册的features 资源库(repository);当你使用feature:repo-add注册features资源库的URL的时候,Karaf会解析features的XML文件。
feature:repo-list –r:强制karaf重新安装features资源库(也可以用来更新features的定义)。
feature:repo-add:注册features资源库(这样就在karaf中有了一个新的可用的features);
添加的可以是:
1. Feature资源库的URL,这个URL直接指向一个features XML文件);
如:feature:repo-add mvn:org.apache.karaf.cellar/apache-karaf-cellar/2.3.1/xml/features
详情:http://karaf.apache.org/manual/latest/users-guide/urls.html
2. 在etc/org.apache.karaf.features.repos.cfg中定义的一个资源库的名(注意这个是名,都什么样的资源库放在配置文件里面呢?);
如:feature:repo-add cellar;当不提供版本的时候,会自动安装最近更新的可用版本。也可以直接指定版本,如:feature:repo-add cellar 2.3.1
feature:repo-add -i cellar:注册并安装资源库;
feature:repo-refresh:当资源库的XML文件发生变化的时候,重新加载资源库变化的内容;没有参数的时候默认更新所有的资源库;还可以直接更新特定的资源库;
例如1:feature:repo-refresh mvn:org.apache.karaf.features/standard/3.0.0-SNAPSHOT/xml/features
例如2:feature:repo-refresh cellar
feature:repo-remove:移除;基本用法同上;移除全部的需要加上-u,
如feature:repo-remove -u karaf-cellar-3.0.0
feature:list:列出所有的可用的features(注意这个不是XML文件啦,是由注册过的features资源库提供的features,并且这个不一定安装过);Installed为x才是安装过的。
feature:list–o:按字母排列顺序显示
feature:list –i:展示所有安装了的features;
feature:install:安装features,需要指定要安的feature名(name或name/version);
如feature:install eventadmin或feature:install eventadmin/3.0.0
feature:install -v:查看安装的详情,具体安装了哪些feature或是bundle;
如feature:install -v eventadmin
默认情况下,如果新安装的feature里面的bundle以前已经安装过了,那么会覆盖掉以前所安装的,这样可能会影响到其它正在运行的程序;如果不想覆盖掉以前的安装可以加上-r,如feature:install -v -reventadmin;
当有一个bundle安装失败了,karaf会回滚,卸载在掉本次安装的所有bundle或feature;
如果不想要这种回滚,可以使用-c,这样即使失败失败了,已经成功的就不会卸载了。
feature:uninstall:卸载安装的feature,如feature:uninstall eventadmin
Feature热部署:通过直接往deploy目录下放置features XML文件即可;
Apache Karaf 提供了一个feature部署器;
当向deploy文件夹下放置XML文件时,部署器会做什么呢?
把features XML中的features注册成资源库如果把features的属性设置成"auto",部署器会自动install 这些features;
<?xml version="1.0" encoding="UTF-8"?>
<features name="my-features" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
<feature name="feature1" version="1.0" install="auto">
...
</feature>
<feature name="feature2" version="1.0" install="auto">
...
</feature>
<feature name="feature3" version="1.0">
...
</feature>
</features>