最近使用karaf+Jetty使用feature碰到了很多問題

http://www.itpub.net/thread-1776847-1-1.html JPA資料

http://springsfeng.iteye.com/blog/1392658 feature參考

http://blog.csdn.net/caolaosanahnu/article/details/7933333

粗心導致排錯搞了兩天,太悲催了,Caused by: java.lang.ClassNotFoundException: org.eclipse.jetty.npn.NextProtoNego$ServerProvider的異常出現,是由於在karaf中npn-boot的版本設置錯誤了。。。。。。

set JAVA_OPTS=%JAVA_OPTS% -Djetty.home=%KARAF_BASE%/jetty -Xbootclasspath/p:npn-boot-${npn.boot.version}.jar



基於Karaf的項目離線打包與發佈

Karaf對OSGi Bundle的組織採用Pax的maven url方式,這也隱性的繼承了maven的特性,即,所有的依賴來自maven倉庫,在實際開發中,這大大的便利了項目結構的組織和維護,開發人員只要指明對某個bundle的maven依賴,karaf自動去選取和下載。但是,在基於karaf的項目部署時,項目或產品的發佈環境往往要求嚴格,不能夠隨意訪問遠程的maven倉庫;那提供一個本地maven倉庫?顯然這也不合理,本地maven倉庫的維護加重了維護的複雜性。本文主要就離線發佈karaf的需求實現進行探討。

Pax URL Mvn協議

在討論karaf的maven依賴加載與管理之前,我們先了解一下Pax URL項目的Mvn協議:

 

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. mvn-uri := 'mvn:' [ repository-url '!' ] group-id '/' artifact-id [ '/' [version] [ '/' [type] [ '/' classifier ] ] ] ]  
  2. repository-url := < rfc2396 uri > ; an url that points to a maven 2 repository  
  3. group-id := < maven groupId > ; group id of maven artifact  
  4. artifact-id := < maven artifactId > ; artifact id of maven artifact  
  5. version := < maven version > | 'LATEST' | range ; version of maven artifact  
  6. range := ( '[' | '(' ) version ',' version ( ')' | ']' )  
  7. type := < maven type> ; type of maven artifact  
  8. 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的示例如下:

 

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <metadata modelVersion="1.1.0">  
  3.   <groupId>org.ops4j.pax.web</groupId>  
  4.   <artifactId>pax-web-features</artifactId>  
  5.   <version>3.0.4-SNAPSHOT</version>  
  6.   <versioning>  
  7.     <snapshot>  
  8.       <timestamp>20131113.170334</timestamp>  
  9.       <buildNumber>2</buildNumber>  
  10.     </snapshot>  
  11.     <lastUpdated>20131113170334</lastUpdated>  
  12.     <snapshotVersions>  
  13.       <snapshotVersion>  
  14.         <extension>pom</extension>  
  15.         <value>3.0.4-20131113.170334-2</value>  
  16.         <updated>20131113170334</updated>  
  17.       </snapshotVersion>  
  18.       <snapshotVersion>  
  19.         <classifier>features</classifier>  
  20.         <extension>xml</extension>  
  21.         <value>3.0.4-20131113.170334-2</value>  
  22.         <updated>20131113170334</updated>  
  23.       </snapshotVersion>  
  24.       <snapshotVersion>  
  25.         <classifier>jettyconfig</classifier>  
  26.         <extension>xml</extension>  
  27.         <value>3.0.4-20131113.170334-2</value>  
  28.         <updated>20131113170334</updated>  
  29.       </snapshotVersion>  
  30.     </snapshotVersions>  
  31.   </versioning>  
  32. </metadata>  

 

 

2)如果version是SNAPSHOT版本,則採用與maven一致的策略來解析SNAPSHOT版本;

3)如果type未指定,默認值爲JAR;

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

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

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

 

Settings.xml

如果有必要且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

Local repository

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

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

Repositories

Maven倉庫的解析順序如下:

  1. 在配置參數中查找
  2. 在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通過CM(config admin)服務對Pax URL Mvn協議處理進行參數配置,具體的配置是位於${karaf.home}/etc下的

org.ops4j.pax.url.mvn.cfg文件:

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. #  
  2. # If set to true, the following property will not allow any certificate to be used  
  3. # when accessing Maven repositories through SSL  
  4. #  
  5. #org.ops4j.pax.url.mvn.certificateCheck=  
  6.    
  7. #  
  8. # Path to the local Maven settings file.  
  9. # The repositories defined in this file will be automatically added to the list  
  10. # of default repositories if the 'org.ops4j.pax.url.mvn.repositories' property  
  11. # below is not set.  
  12. # The following locations are checked for the existence of the settings.xml file  
  13. #   * 1. looks for the specified url  
  14. #   * 2if not found looks for ${user.home}/.m2/settings.xml  
  15. #   * 3if not found looks for ${maven.home}/conf/settings.xml  
  16. #   * 4if not found looks for ${M2_HOME}/conf/settings.xml  
  17. #  
  18. #org.ops4j.pax.url.mvn.settings=  
  19.    
  20. #  
  21. # Path to the local Maven repository which is used to avoid downloading  
  22. # artifacts when they already exist locally.  
  23. # The value of this property will be extracted from the settings.xml file  
  24. # above, or defaulted to:  
  25. #     System.getProperty( "user.home" ) + "/.m2/repository"  
  26. #  
  27. #org.ops4j.pax.url.mvn.localRepository=  
  28.    
  29. #  
  30. # Default this to false. It's just weird to use undocumented repos  
  31. #  
  32. org.ops4j.pax.url.mvn.useFallbackRepositories=false  
  33.    
  34. #  
  35. # Uncomment if you don't wanna use the proxy settings  
  36. # from the Maven conf/settings.xml file  
  37. #  
  38. # org.ops4j.pax.url.mvn.proxySupport=false  
  39.    
  40. #  
  41. # Disable aether support by default.  This ensure that the defaultRepositories  
  42. # below will be used  
  43. #  
  44. #org.ops4j.pax.url.mvn.disableAether=true  
  45.    
  46. #  
  47. # Comma separated list of repositories scanned when resolving an artifact.  
  48. # Those repositories will be checked before iterating through the  
  49. #    below list of repositories and even before the local repository  
  50. # A repository url can be appended with zero or more of the following flags:  
  51. #    @snapshots  : the repository contains snaphots  
  52. #    @noreleases : the repository does not contain any released artifacts  
  53. #  
  54. # The following property value will add the system folder as a repo.  
  55. #  
  56. #org.ops4j.pax.url.mvn.defaultRepositories=  
  57.    
  58. # Use the default local repo (e.g.~/.m2/repository) as a "remote" repo  
  59. org.ops4j.pax.url.mvn.defaultLocalRepoAsRemote=false  
  60.    
  61. #  
  62. # Comma separated list of repositories scanned when resolving an artifact.  
  63. # The default list includes the following repositories containing releases:  
  64. #    http://repo1.maven.org/maven2  
  65. #    http://repository.apache.org/content/groups/snapshots-group  
  66. #    http://svn.apache.org/repos/asf/servicemix/m2-repo  
  67. #    http://repository.springsource.com/maven/bundles/release  
  68. #    http://repository.springsource.com/maven/bundles/external  
  69. # To add repositories to the default ones, prepend '+' to the list of repositories  
  70. # to add.  
  71. # A repository url can be appended with zero or more of the following flags:  
  72. #    @snapshots  : the repository contains snaphots  
  73. #    @noreleases : the repository does not contain any released artifacts  
  74. #    @id=reponid : the id for the repository, just like in the settings.xml this is optional but recomendet  
  75. #  
  76. # The default list doesn't contain any repository containing snapshots as it can impact the artifacts resolution.  
  77. # You may want to add the following repositories containing snapshots:  
  78. #    http://repository.apache.org/content/groups/snapshots-group@id=apache@snapshots@noreleases  
  79. #    http://oss.sonatype.org/content/repositories/snapshots@id=sonatype.snapshots.deploy@snapshots@norelease  
  80. #    http://oss.sonatype.org/content/repositories/ops4j-snapshots@id=ops4j.sonatype.snapshots.deploy@snapshots@noreleases  
  81. #  
  82. org.ops4j.pax.url.mvn.repositories= \  
  83.     http://repo1.maven.org/maven2@id=central, \  
  84.     http://repository.springsource.com/maven/bundles/release@id=spring.ebr, \  
  85.     file:${karaf.home}/${karaf.default.repository}@id=system.repository, \  
  86.     file:${karaf.data}/kar@id=kar.repository@multi  

 

下面我們來看一下如何通過調整此配置文件,使得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發佈程序即可實現離線部署。

具體配置調整如下:

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. # Path to the local Maven settings file.  
  2. # The repositories defined in this file will be automatically added to the list  
  3. # of default repositories if the 'org.ops4j.pax.url.mvn.repositories' property  
  4. # below is not set.  
  5. # The following locations are checked for the existence of the settings.xml file  
  6. #   * 1. looks for the specified url  
  7. #   * 2if not found looks for ${user.home}/.m2/settings.xml  
  8. #   * 3if not found looks for ${maven.home}/conf/settings.xml  
  9. #   * 4if not found looks for ${M2_HOME}/conf/settings.xml  
  10. #  
  11. <span style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; list-style: none outside none; word-break: normal; word-wrap: break-word; color: rgb(255, 102, 0);">org.ops4j.pax.url.mvn.settings=</span></span>  
  12.    
  13. #  
  14. # Path to the local Maven repository which is used to avoid downloading  
  15. # artifacts when they already exist locally.  
  16. # The value of this property will be extracted from the settings.xml file  
  17. # above, or defaulted to:  
  18. #     System.getProperty( "user.home" ) + "/.m2/repository"  
  19. #  
  20. <span style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; list-style: none outside none; word-break: normal; word-wrap: break-word; color: rgb(255, 102, 0);">org.ops4j.pax.url.mvn.localRepository=file:${karaf.home}/${karaf.default.repository}@id=system.repository@snapshots</span></span>  
  21.    
  22. # Use the default local repo (e.g.~/.m2/repository) as a "remote" repo  
  23. <span style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; list-style: none outside none; word-break: normal; word-wrap: break-word; color: rgb(255, 102, 0);">org.ops4j.pax.url.mvn.defaultLocalRepoAsRemote=true</span></span>  
  24.    
  25. #  
  26. # Comma separated list of repositories scanned when resolving an artifact.  
  27. # The default list includes the following repositories:  
  28. #    http://repo1.maven.org/maven2@id=central  
  29. #    http://repository.apache.org/content/groups/snapshots-group@id=apache@snapshots@noreleases  
  30. #    http://repository.springsource.com/maven/bundles/release@id=spring.ebr  
  31. #    http://oss.sonatype.org/content/repositories/snapshots@id=sonatype.snapshots.deploy@snapshots@norelease  
  32. #    http://oss.sonatype.org/content/repositories/ops4j-snapshots@id=ops4j.sonatype.snapshots.deploy@snapshots@noreleases  
  33. #    file:${karaf.home}/${karaf.default.repository}@id=system.repository  
  34. #    file:${karaf.data}/kar@id=kar.repository@multi  
  35. # To add repositories to the default ones, prepend '+' to the list of repositories  
  36. # to add.  
  37. # A repository url can be appended with zero or more of the following flags:  
  38. #    @snapshots  : the repository contains snapshots  
  39. #    @noreleases : the repository does not contain any released artifacts  
  40. #    @id=repository.id : the id for the repository, just like in the settings.xml this is optional but recommended  
  41. #  
  42. <span style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; list-style: none outside none; word-break: normal; word-wrap: break-word; color: rgb(255, 102, 0);">org.ops4j.pax.url.mvn.repositories= \  
  43.     file:${karaf.home}/${karaf.default.repository}@id=system.repository@snapshots, \  
  44.     file:${karaf.data}/kar@id=kar.repository@multi</span></span>  

 

 

在此模式下,Pax URL Mvn優先檢查system倉庫,如果不存在,則檢查${user.home}/.m2下的配置,如果沒有settings.xml和repository目錄,則加載依賴失敗。當system庫下不存在org.apache.servicemix.specs.activation-api-1.1-1.9.0.jar時,運行日誌如下:

46 -
org.ops4j.pax.url.mvn - 1.6.0 | Resolving
[mvn:org.apache.servicemix.specs/org.apache.servicemix.specs.activation-api-1.1/1.9.0]
46 -
org.ops4j.pax.url.mvn - 1.6.0 | Using manager SimpleLocalRepositoryManager with
priority 0 for D:\Projects\karaf\assemblies\apache-karaf\target\assembly\system
46 - org.ops4j.pax.url.mvn - 1.6.0 | Using connector
WagonRepositoryConnector with priority 0 for file:/C:/Users/xxxx/.m2/repository/
46 -
org.ops4j.pax.url.mvn - 1.6.0 | Using connector WagonRepositoryConnector with
priority 0 for file:D:/Projects/karaf/assemblies/apache-karaf/target/assembly/system/
46 - org.ops4j.pax.url.mvn - 1.6.0 | Error resolving
artifactorg.apache.servicemix.specs:org.apache.servicemix.specs.activation-api-1.1:jar:1.9.0:Could
not find artifact
org.apache.servicemix.specs:org.apache.servicemix.specs.activation-api-1.1:jar:1.9.0
in defaultlocal (file:/C:/Users/xxxx/.m2/repository/)

 

通過此方案,如果發佈包中的system目錄包含了系統運行所需的所有依賴,則karaf將不再尋求從遠程倉庫加載依賴,從而實現離線部署。

 

通過上述方案實現karaf離線部署的同時產生了新的問題,如何確保system目錄包含所有的依賴同時又不包含無用的冗餘依賴?這個問題可以通過karaf-maven-plugin獲得解決。下面來看一下配置:

  1. <plugin>  
  2.                 <groupId>org.apache.karaf.tooling</groupId>  
  3.                 <artifactId>karaf-maven-plugin</artifactId>  
  4.                 <executions>  
  5.                     <execution>  
  6.                         <id>install-kar</id>  
  7.                         <phase>compile</phase>  
  8.                         <goals>  
  9.                             <goal>install-kars</goal>  
  10.                         </goals>  
  11.                     </execution>  
  12.                     <execution>  
  13.                         <id>features-add-to-repo</id>  
  14.                         <phase>generate-resources</phase>  
  15.                         <goals>  
  16.                             <span style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; list-style: none outside none; word-break: normal; word-wrap: break-word; color: rgb(255, 102, 0);"><goal>features-add-to-repository</goal></span></span>  
  17.                         </goals>  
  18.                         <configuration>  
  19.                             <descriptors>  
  20.                                 <<span style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; list-style: none outside none; word-break: normal; word-wrap: break-word; color: rgb(0, 0, 255);">descriptor>mvn:org.apache.karaf.features/standard/${karaf.version}/xml/features</descriptor>  
  21.                                 <descriptor>mvn:org.apache.karaf.features/spring/${karaf.version}/xml/features</descriptor></span></span>  
  22.                                 ……                            
  23.                             </descriptors>  
  24.                             <features>  
  25.                                 <span style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; list-style: none outside none; word-break: normal; word-wrap: break-word; color: rgb(0, 0, 255);"><feature>http</feature>     
  26.                                 <feature>spring</feature></span></span>  
  27.                                 …  
  28.                             </features>  
  29.                             <span style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; list-style: none outside none; word-break: normal; word-wrap: break-word; color: rgb(128, 0, 128);"><repository>target/assembly/system</repository></span></span>  
  30.                         </configuration>  
  31.                     </execution>  
  32.                     <execution>  
  33.                         <id>package</id>  
  34.                         <goals>  
  35.                             <goal>instance-create-archive</goal>  
  36.                         </goals>  
  37.                     </execution>  
  38.                 </executions>                 
  39.             </plugin>  

 

通過此配置,系統在打包時,自動將karaf的standard feature庫中的http feature及其依賴和spring feature庫中的spring feature及其依賴下載到system目錄中一起打包發佈。

結論

 

通過上述方案,我們即可實現基於Karaf的項目自動打包、測試及發佈。


發佈了190 篇原創文章 · 獲贊 7 · 訪問量 62萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章