Apache Karaf離線打包

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構件

協議要點

  1. 如果版本(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>  
  1. 如果version是SNAPSHOT版本,則採用與maven一致的策略來解析SNAPSHOT版本;

  2. 如果type未指定,默認值爲JAR;

  3. 如果指定了一個type但沒有指定version,則必須爲version留有佔位即:mvn:groups/artifact//type

  4. Pax URL從0.3.0版本開始支持類別Classifier,如果類別classifier未指定,則不啓用類別;

  5. 如果指定了類別,但沒有指定版本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:

  1. 查找配置參數
  2. 如果未找到,查找 ${user.home}/.m2/settings.xml
  3. 如果未找到,查找 ${maven.home}/conf/settings.xml
  4. 如果未找到,查找 ${M2_HOME}/conf/settings.xml

Maven本地倉庫的查找

Maven本地倉庫的查找順序如下:

  1. 查找配置參數定義;
  2. 如果未找到,在settings.xml中進行查找
  3. 如果未找到,默認認爲倉庫位於${user.home}/.m2/repository.

遠端Maven倉庫的解析

Maven倉庫的解析順序如下:

  1. 在配置參數中查找
  2. 在settings.xml中查找

如果配置參數中 org.ops4j.pax.url.mvn.repositories 的值以'+'開始,則來自settings.xml中的倉庫地址也將附加到此配置的倉庫列表中。

設定倉庫包含release/snapshot

可以在參數配置的倉庫URL中通過添加如下標識來指定倉庫所含有的構件類型(不區分大小寫):

啓用snapshots — 添加 @snapshots
禁用releases — 添加 @noreleases

示例如下:

默認倉庫

在某些情況下,通過默認倉庫配置,可以防止用戶配置對下載構件造成影響。如果對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的項目自動打包、測試及發佈。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章