layout | title | tags | date | categories |
---|---|---|---|---|
post
|
Apache Karaf構建動態模塊化應用(6)--Karaf離線打包發佈
|
osgi karaf maven
|
2015-08-04 12:15:45
|
osgi java
|
概述
在使用Apache Karaf進行實際打包發佈時,基於Maven的自動依賴環境可能會制約產品的打包發佈。因爲出於安全要求,要部署運行的環境往往不能 隨意訪問遠程的Maven倉庫,這時就需要將產品運行所需要的所有Feature及Bundle等進行離線打包。
Karaf對OSGi Bundle的組織採用Pax的 maven url 方式,這也隱性的繼承了maven的特性,即,所有的依賴來自maven倉庫, 在實際開發中,這大大的便利了項目結構的組織和維護,開發人員只要指明對某個bundle的maven依賴,karaf自動去選取和下載。
本文對之前寫的一篇博客進行了簡單整理,作爲本系列的一部分。
Pax URL Mvn協議
在討論karaf的maven依賴加載與管理之前,我們先了解一下Pax URL項目的Mvn協議:
mvn-uri := 'mvn:' [ repository-url '!' ] group-id '/' artifact-id [ '/' [version] [ '/' [type] [ '/' classifier ] ] ] ]
repository-url := < rfc2396 uri > ; an url that points to a maven 2 repository
group-id := < maven groupId > ; group id of maven artifact
artifact-id := < maven artifactId > ; artifact id of maven artifact
version := < maven version > | 'LATEST' | range ; version of maven artifact
range := ( '[' | '(' ) version ',' version ( ')' | ']' )
type := < maven type> ; type of maven artifact
classifier := < maven classifier> ; maven artifact classifier
假設項目需要依賴Pax Web的service-0.2.0-SNAPSHOT.jar,對應的Mvn協議示例如下:
- mvn:org.ops4j.pax.web.bundles/service
- mvn:org.ops4j.pax.web.bundles/service/LATEST
- mvn:org.ops4j.pax.web.bundles/service/0.2.0-SNAPSHOT
- mvn:http://repository.ops4j.org/maven2!org.ops4j.pax.web.bundles/service/0.2.0
- mvn:file://c:/localRepo!org.ops4j.pax.web.bundles/service/0.2.0 # 從目錄中加載
- mvn:org.ops4j.pax.web/pax-web-features/3.0.4-SNAPSHOT/xml/features # 標識pax-web-features-3.0.4-SNAPSHOT-features.xml構件
協議要點
- 如果版本(version)未指定,將使用默認值“LATEST”,並從可用的Maven元數據(metadata)中解析最新的版本,maven metadata的示例如下:
<?xml version="1.0" encoding="UTF-8"?>
<metadata modelVersion="1.1.0">
<groupId>org.ops4j.pax.web</groupId>
<artifactId>pax-web-features</artifactId>
<version>3.0.4-SNAPSHOT</version>
<versioning>
<snapshot>
<timestamp>20131113.170334</timestamp>
<buildNumber>2</buildNumber>
</snapshot>
<lastUpdated>20131113170334</lastUpdated>
<snapshotVersions>
<snapshotVersion>
<extension>pom</extension>
<value>3.0.4-20131113.170334-2</value>
<updated>20131113170334</updated>
</snapshotVersion>
<snapshotVersion>
<classifier>features</classifier>
<extension>xml</extension>
<value>3.0.4-20131113.170334-2</value>
<updated>20131113170334</updated>
</snapshotVersion>
</snapshotVersions>
</versioning>
</metadata>
-
如果version是SNAPSHOT版本,則採用與maven一致的策略來解析SNAPSHOT版本;
-
如果type未指定,默認值爲JAR;
-
如果指定了一個type但沒有指定version,則必須爲version留有佔位即:mvn:groups/artifact//type
-
Pax URL從0.3.0版本開始支持類別Classifier,如果類別classifier未指定,則不啓用類別;
-
如果指定了類別,但沒有指定版本version或類型type,則必須未版本和(或)類型留有佔位,即:
mvn:groups/artifact///classifier
或
mvn:groups/artifact/version//classifier
或
mvn:groups/artifact//type/classifier
版本範圍
從0.2.0版本開始,Pax URL Mvn支持版本範圍,示例如下
- [1.2.3, 4.5.6) — 1.2.3 <= x < 4.5.6
- [1.2.3, 4.5.6] — 1.2.3 <= x <= 4.5.6
- (1.2.3, 4.5.6) — 1.2.3 < x < 4.5.6
- (1.2.3, 4.5.6] — 1.2.3 < x <= 4.5.6
mvn協議的參數配置
可以通過兩種方式來配置Mvn協議:1)通過OSGi CM;2)通過框架/系統變量。通過CM配置的參數具有高優先級。
參數名稱 | 描述 |
---|---|
org.ops4j.pax.url.mvn.certificateCheck | optional; true/false if the SSL certificate check should be done. Default false. |
org.ops4j.pax.url.mvn.globalUpdatePolicy | optional; 控制遠程maven倉庫的更新策略,maven通過本地POM的時間戳比對爲依據。可選的策略包括:always, daily (default), interval:X (where X is an integer in minutes) or never. |
org.ops4j.pax.url.mvn.localRepository | optional; 指向本地倉庫目錄的路徑 |
org.ops4j.pax.url.mvn.repositories | optional; 以逗號分隔的倉庫URL列表 |
org.ops4j.pax.url.mvn.defaultRepositories | optional; 以逗號分隔的默認倉庫URL列表 |
org.ops4j.pax.url.mvn.settings | optional; 指向maven settings.xml的路徑 |
org.ops4j.pax.url.mvn.proxySupport | optional; true/false if the proxy support is enabled . Default true. |
Maven Settings配置查找
如果有必要且maven settings.xml可用,Pax URL Mvn按如下步驟查找settings.xml:
- 查找配置參數
- 如果未找到,查找 ${user.home}/.m2/settings.xml
- 如果未找到,查找 ${maven.home}/conf/settings.xml
- 如果未找到,查找 ${M2_HOME}/conf/settings.xml
Maven本地倉庫的查找
Maven本地倉庫的查找順序如下:
- 查找配置參數定義;
- 如果未找到,在settings.xml中進行查找
- 如果未找到,默認認爲倉庫位於${user.home}/.m2/repository.
遠端Maven倉庫的解析
Maven倉庫的解析順序如下:
- 在配置參數中查找
- 在settings.xml中查找
如果配置參數中 org.ops4j.pax.url.mvn.repositories 的值以'+'開始,則來自settings.xml中的倉庫地址也將附加到此配置的倉庫列表中。
設定倉庫包含release/snapshot
可以在參數配置的倉庫URL中通過添加如下標識來指定倉庫所含有的構件類型(不區分大小寫):
啓用snapshots — 添加 @snapshots
禁用releases — 添加 @noreleases
示例如下:
- http://repository.ops4j.org ; 默認不包含任何標識,只查找releases, 不包括snapshots
- http://repository.ops4j.org/mvn-snapshots@snapshots ; 同時在此倉庫查找releases和snapshots
- http://repository.ops4j.org/mvn-snapshots@snapshots@noreleases ; 僅查找snapshots,
不查找releases
默認倉庫
在某些情況下,通過默認倉庫配置,可以防止用戶配置對下載構件造成影響。如果對org.ops4j.pax.url.mvn.defaultRepositories 進行了設置,則Pax URL Mvn首先檢查此參數設定的默認倉庫列表,如果未找到,則繼續查找本地倉庫和其它在 org.ops4j.pax.url.mvn.repositories 中配置的倉庫。
Karaf中Maven倉庫處理策略的配置
默認倉庫處理策略
Karaf通過 OSGi CM(config admin) 服務對Pax URL Mvn協議處理進行參數配置,具體的配置是位於${karaf.home}/etc
下的 org.ops4j.pax.url.mvn.cfg
文件:
#org.ops4j.pax.url.mvn.certificateCheck=
#org.ops4j.pax.url.mvn.settings=
#org.ops4j.pax.url.mvn.localRepository=
org.ops4j.pax.url.mvn.useFallbackRepositories=false
# org.ops4j.pax.url.mvn.proxySupport=false
org.ops4j.pax.url.mvn.defaultRepositories=\
file:${karaf.home}/${karaf.default.repository}@id=system.repository@snapshots, \
file:${karaf.data}/kar@id=kar.repository@multi@snapshots, \
file:${karaf.base}/${karaf.default.repository}@id=child.system.repository@snapshots
# Use the default local repo (e.g.~/.m2/repository) as a "remote" repo
#org.ops4j.pax.url.mvn.defaultLocalRepoAsRemote=false
org.ops4j.pax.url.mvn.repositories= \
http://repo1.maven.org/maven2@id=central, \
http://repository.springsource.com/maven/bundles/release@id=spring.ebr.release, \
http://repository.springsource.com/maven/bundles/external@id=spring.ebr.external, \
http://zodiac.springsource.com/maven/bundles/release@id=gemini, \
http://repository.apache.org/content/groups/snapshots-group@id=apache@snapshots@noreleases, \
https://oss.sonatype.org/content/repositories/snapshots@id=sonatype.snapshots.deploy@snapshots@noreleases, \
https://oss.sonatype.org/content/repositories/ops4j-snapshots@id=ops4j.sonatype.snapshots.deploy@snapshots@noreleases, \
http://repository.springsource.com/maven/bundles/external@id=spring-ebr-repository@snapshots@noreleases
下面我們來看一下如何通過調整此配置文件,使得Karaf不再依賴遠程Maven倉庫和本地Maven倉庫,讓Karaf發佈包隨意離線部署成爲現實。
首先我們來看一下在org.ops4j.pax.url.mvn.repositories配置中存在兩個指向目錄路徑的倉庫URL,即:
file:${karaf.home}/${karaf.default.repository}@id=system.repository
和
file:${karaf.data}/kar@id=kar.repository@multi。file:${karaf.home}/${karaf.default.repository}@id=system.repository
實際指向的是karaf安裝目錄下的 system目錄(也可以根據需要自行調整,karaf.default.repository
參數位於etc/system.properties 文件中);
file:${karaf.data}/kar@id=kar.repository@multi
實際指向的是karaf安裝目錄下的 data/kar 目錄。
離線處理策略
通過禁用其他倉庫URL,只啓用這兩個位置倉庫,則karaf發佈程序即可實現離線部署。
上面的org.ops4j.pax.url.mvn.cfg
文件按下面具體配置進行調整:
org.ops4j.pax.url.mvn.settings=
org.ops4j.pax.url.mvn.localRepository=file:${karaf.home}/${karaf.default.repository}@id=system.repository@snapshots
org.ops4j.pax.url.mvn.defaultLocalRepoAsRemote=true
org.ops4j.pax.url.mvn.repositories= \
file:${karaf.home}/${karaf.default.repository}@id=system.repository@snapshots, \
file:${karaf.data}/kar@id=kar.repository@multi
此模式下,Pax URL Mvn優先檢查system倉庫,如果不存在,則檢查${user.home}/.m2下的配置,如果沒有settings.xml和repository目錄,則加載依賴失敗。
在實際部署時,確保system倉庫包含所有依賴的bundle即可。
通過此方案,如果發佈包中的system目錄包含了系統運行所需的所有依賴,則karaf將不再尋求從遠程倉庫加載依賴,從而實現離線部署。
離線依賴自動打包
通過上述方案實現karaf離線部署的同時產生了新的問題,如何確保system目錄包含所有的依賴同時又不包含無用的冗餘依賴?
這個問題可以通過karaf-maven-plugin提供的 features-add-to-repository 目標獲得解決。在打包部署時,系統自動將Feature裏的Bundle打包到system目錄下。 下面來看一下配置:
<plugin>
<groupId>org.apache.karaf.tooling</groupId>
<artifactId>karaf-maven-plugin</artifactId>
<executions>
<execution>
<id>install-kar</id>
<phase>compile</phase>
<goals>
<goal>install-kars</goal>
</goals>
</execution>
<execution>
<id>features-add-to-repo</id>
<phase>generate-resources</phase>
<goals>
features-add-to-repository
</goals>
<configuration>
<descriptors>
<descriptor>mvn:org.apache.karaf.features/standard/${karaf.version}/xml/features</descriptor>
<descriptor>mvn:org.apache.karaf.features/spring/${karaf.version}/xml/features</descriptor>
……
</descriptors>
<features>
<feature>http</feature>
<feature>spring</feature>
…
</features>
<repository>target/assembly/system</repository>
</configuration>
</execution>
<execution>
<id>package</id>
<goals>
<goal>instance-create-archive</goal>
</goals>
</execution>
</executions>
</plugin>
通過此配置,系統在打包時,自動將karaf的standard feature庫中的http feature及其依賴和spring feature庫中的spring feature及其依賴下載到system目錄中一起打包發佈。
結論
通過上述方案,我們即可實現基於Karaf的項目自動打包、測試及發佈。