Maven-Profile


Introduction to Build Profiles

Apache Maven 2.0 竭盡全力確保生成可移植的構建. 這意味着: 允許在POM內的構建配置, 避免所有文件系統的引用(在繼承\依賴) , 並且更嚴重地依賴本地倉庫來存儲支持該功能的元數據.

然而, 有時移植性不是完全可行的. 在某些特定情況下, 插件可能需要使用本地文件系統路徑來配置. 在其他情況下, 可能需要一個稍微有點不同的依賴設置, 且該工程的名字可能需要稍微調整一下. 在其他時候, 你可能甚至需要根據檢測到的構建環境, 在構建生命周期中包含一整個插件.

針對這些情況, maven 2.0 介紹了構建配置文件的概念(build profile).  配置文件通過使用POM中的元素子集來指定(增加一個額外的section), 在多種情況下被觸發. 配置文件在構建時修改POM, 並且為變量設置不同的目標環境(例如, 在開發, 測試和產品環境中的數據庫服務器路徑). 這樣, 配置文件很容易導致不同成員產生不同的構建結果. 然而, 使用得當, 可在保留工程可移植性的同時, 使用配置文件. 這也將最少化使用 –f 操作的次數, 該操作允許用戶創建其他不同參數或配置的POM, 且更加可維護, 畢竟一個工程只能有一個POM.

What are the different types of profile? Where is each defined?

類型 定義位置 路徑
Per Project 項目級 POM pom.xml
Per User 用戶級 Maven-settings %USER_HOME%/.m2/settings.xml
Global 全局 global Maven-settings ${maven.home}/conf/settings.xml
Profile descriptor project basedir profiles.xml

How can a profile be triggered? How does this vary according to the type of profile being used?

一個配置文件可通過以下方式激活:

  • Explicitly   顯式使用命令控制台輸入
  • Through Maven settings   通過 maven 的設置
  • Based on environment variables   基於環境變量(用戶\系統變量)
  • OS settings  操作系統的配置(如, windows family)
  • Present or missing files  現在\缺失 文件

Details on profile activation

0. 在 pom.xml文件中定義profile

image

 

1. 使用 –P 選項 來顯式設置

該選項有一個參數列表: 用逗號分隔的 profile-ids.  當指定該選項時, 在參數中指定的profile將會被激活, 除了已被激活配置或 settings.xml的<activeProfiles> section激活的profiles之外.

mvn groupId:artifactId:goal -P profile-1,profile-2

image

image

image

運行結果是在目標目錄下, 產生了兩個文件, 它們的內容一樣.

image

2. Maven setting中的 <activeProfiles>

該節中包含一個<activeProfile>元素列表, 每個包含了一個profile-id.

在<activeProfiles>標簽下列出的 profiles將會默認地在每次工程使用它時被激活.

image

Maven的 settings.xml 文件可以在 %USER_HOME%/.m2 目錄下找到. 如果不存在,則需要創建一個.

3. 環境變量激活

profile可根據檢測出的生成環境的狀態, 自動觸發. 這些觸發在<profile>下的<activation>一節中定義. 當前, 該檢測僅限於JDK版本的前綴匹配\ 系統屬性是否存在 或一個系統屬性的值.

(1) 當JDK的版本號以"1.4"開頭時, 下例中的配置將被觸發.

image

(2) Maven 2.1中也可以使用范圍. 下例中表示版本 1.3, 1.4, 1.5.

注意, 右閉區間, 如: ,1.5], 也不代表包含所有的1.5版本, 因為很多情況下會有額外的 "patch release", 例如, _05就不能包含在這個區間里了.

image

(3) 系統屬性 debug, 無論取何值, 都會觸發下例.

image

(4) 系統屬性 enviroment 取值為test時...

image

注意, 為了觸發上例, 需要以下命令:

  1. mvn groupId:artifactId:goal -Denvironment=test

4. 操作系統的設置

image

5. 現存\缺失的文件激活

當文件缺失時, 就會激活:

image

 

上述配置設好后, 可使用 mvn test 來查看 test profile 的結果. 而不是顯式的使用-p選項.

image

6. 卸載一個profile

  1. mvn groupId:artifactId:goal -P !profile-1,!profile-2

可以用來卸載 activeByDefault 或者 通過激活配置 來激活的 profile.

Which areas of a POM can be customized by each type of profile? Why?

我們已經討論了在哪里指定 profile, 以及如何激活它們. 而你可以在一個profile里指定什么將會非常有用. 因為涉及 profile配置的其他方面, 這個答案並不簡單.

依據你選擇的配置profile的方式, 你可以獲得不同的POM配置.

Profiles in external files

最嚴格意義上來說, 在外置文件(比如 setting.xml 或 profiles.xml)中定義的profile是不可移植的. 任何看似有高機率改變構建結果的東西, 都會被限制在POM中的嵌入profiles. 像倉庫列表之類的東西可以簡單地作為一個准許工程的存儲庫, 並且不會改變構建的輸出. 因此, 你只可能在settings.xml中修改 <repositories><pluginRepositories>節, 再加上一個額外的<properties>節.

<properties>節允許你指定 自由格式的 鍵值對, 包含在POM的插補過程中. 這允許你通過格式${profile.provided.path} 指定一個插件配置.

Profiles in POMs

另一方面, 如果你的profiles可以合理地在pofile內部定義, 你可以有更多的選擇. 代價就是你只能修改那個工程和它的子模塊. 因為這些profiles 是內嵌定義的, 所以可以更好地保持可移植性. 因此, 你可以添加更多信息, 而避免了這些信息對其他用戶不可用的風險.

在POM中定義profiles可以修改以下元素:

  • <repositories>
  • <pluginRepositories>
  • <dependencies>
  • <plugins>
  • <properties> (not actually available in the main POM, but used behind the scenes)
  • <modules>
  • <reporting>
  • <dependencyManagement>
  • <distributionManagement>
  • a subset of the <build> element, which consists of:
    • <defaultGoal>
    • <resources>
    • <testResources>
    • <finalName>

POM elements outside <profiles>

我們不允許修改 POM-profiles 之外的一些pom 元素. 因為這些運行時修改不會在POM部署到資源系統時分發, 造成個人的工程構建完全不同於其他人的. 另一個原因是POM信息有時會被父POM復用.

外部文件存儲, 比如settings.xml和profiles.xml, 也不支持 POM-profiles之外的元素.  當有效的POM文件被部署到一個遠程資源庫時, 任何人都可以獲取它的信息, 並且直接用來構建一個maven工程. 現在,假設我們可以在對一個構建非常重要的 dependencies 中設置 profiles,  或者其他除POM-profiles之外的元素. 那么最可能的是我們不希望其他人能從資源庫中使用POM, 甚至 構建它.  我們也會考慮如何共享settingx.xml.  注意到太多要配置的文件是一件十分困擾的事, 而且難以維護.  底線就是, 既然這是構建數據, 它就應該放在POM中.  maven 2 的一個目標就是將所有運行一個構建必須的信息都統一到一個文件中, 或者文件層次結構, 這就是POM.

Profile Pitfalls

隱患.

我們已經提到過, 添加profiles到你的構建中可能會破壞工程的可移植性. 我們更是強調了那些 profiles可能破壞工程移植性的情景.然而 , 重申這些點是值得的, 這是部分討論, 關於使用profiles時要避免的隱患.

在使用profiles時, 有兩個主要問題領域需要記住. 第一個是外部屬性, 通常在插件配置中使用. 這造成了你工程的移植風險. 另一個, 更微妙的領域, 是一個自然的profiles的不完整規范(Incomplete Specification of a Natural Profile Set).

External Properties

外部屬性定義, 是指那些在pom.xml之外定義的屬性值,但又不是定義在一個其內部相關的profile中.  在POM中, 屬性的最常見用法是插件配置. 沒有屬性, 固然可能打破項目的可移植性, 但這也可能導致構建失敗. 例如, 在一個定義在settings.xml中的profile中指定一個appserver paths, 可能導致你的集成測試插件發生失敗, 當團隊中另一個沒有相似settings.xml的用戶企圖去構建時.

下面是一個web應用工程的pom片段:

image

在你自己的本地${user.home}/.m2/settings.xml中:

image

當你構建 集成測試 生命周期階段時, 你的集成測試將會通過. 因為你提供的路徑允許該測試插件安裝和測試該web應用.

然而, 當你的同事嘗試去構建 集成測試時, 他的構建會徹底失敗, 因為它不能處理插件配置參數<appserverPath>, 或者更糟地, 警告該參數${appserver.home}的值是無效的.

慶幸的是, 你的工程現在還沒有移植. 在你的pom.xml中內聯該profile, 可以幫助緩和該問題. 但明顯的缺點是, 每個工程層次(允許繼承影響)現在必須指定該信息. 因為maven提供對工程繼承的良好支持, 可以把這類配置放到團隊級POM或類似的POM中的<pluginManagement>節中, 然后簡單地繼承路徑.

另外, 不那么具有吸引力的答案是開發環境的標准化. 然而, 這往往會損害 maven能提供的生產率.

Incomplete Specification of a Natural Profile Set

image

image

這個profile看起來很像上一個例子中的. 有一點很重要的不同: 有一個面向開發環境的, 一個新的profile, 名為 appserverConfig-dev-2, 被添加了, 並且它有一個激活section, 將會在系統屬性 env=dev-2時激活.

所以, 執行:

  1. mvn -Denv=dev-2 integration-test

將會成功構建, 應用appserverConfig-dev-2 proflie.

當執行:

  1. mvn -Denv=dev integration-test

也會成功構建, 應用了appserverConfig-dev profile.

然而 , 執行:

  1. mvn -Denv=production integration-test

不會成功構建. 為什么? 因為, ${appserver.home}的值不會是一個有效的路徑, 部署和測試你的web應用無法進行. 我們在編寫profiles時還沒有考慮env=production的情況. 這樣不完整的規范意味着, 我們已經成功地根據開發環境來限制了有效的目標環境. 你的同事, 也有可能是你的manager, 將不會看到這個笑話. 當你創建profiles來處理這些類似的情況時, 一定要解決所有的target集.

用戶特定的配置文件可以以類似的方式來進行.

How can I tell which profiles are in effect during a build?

確定活動的profiles, 將幫助用戶了解在一次構建過程中, 哪些特定的profiles已經被執行了. 我們可以使用maven help plugin來查詢一次構建過程中哪些profiles是生效的.

  1. mvn help:active-profiles

假設, 分別在pom.xml和settings.xml中配置profile如下:

image

image

執行以下命令:

  1. mvn help:active-profiles

image

  1. mvn help:active-profiles -Denv=dev

image

image

 

image

image

 

總結=.=

感覺我翻譯得不好 =,= 理解上有點困難...所以梳理一下...

profile可以看作是pom的一部分. 簡單來說, profile支持定義一系列的配置信息, 然后在不同的環境中, 可以自動觸發不同的配置. 比如, 在windows下是一套配置, 在linux下是另一套配置.

可以選擇在多個地方定義 profile. 在不同地方定義, 作用范圍不同. 針對某個項目的配置, 可以寫在 pom.xml中. 針對某個用戶的配置, 可以在用戶目錄下的 .m2目錄下的 setting.xml 文件中定義. 針對全局的配置, 可以在maven安裝目錄下的 conf目錄中的 setting.xml 文件中定義.

profile中能定義的配置信息與所處位置相關. 如果是在settings.xml中, 是全局意義的, 只能定義一些相對而言作用范圍較廣的配置, 比如<repositories>, <pluginRepositories>, <properties>.  定義在<properties>中的鍵值對可以在pom.xml中使用.

如果是在pom.xml中, 可以根據項目的不同來定義不同的細節配置信息. 主要有: <repositories>, <pluginRepositories>, <dependencies>, <plugins>, <properties>, <dependencyManagement>, <distributionManagement>, <build>下的子元素.

profile有多種不同的激活方式. 1) 在profile的<activation>下, 將<activeByDefault>元素的值設為true, 就表示沒有指定其他profile為激活狀態時, 默認激活該profile.   2) 在settings.xml中使用<activeProfiles>指定自動激活的profile名. 這樣的profile在所有情況下都處於激活狀態. 3) 顯式命令使用-p選項,指定profile.  4) 根據不同的環境來激活, 如jdk版本, 操作系統, 系統屬性, 5) 根據文件是否存在來激活.

可以使用 mvn help: active-Profiles來查看處於激活狀態的profiles.

Reference

http://maven.apache.org/guides/introduction/introduction-to-profiles.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM