Maven打包

任何一個Maven項目都需要定義POM元素packaging(如果不寫則默認值為jar)。顧名思義,該元素決定了項目的打包方式。實際的情形中,如果你不聲明該元素,Maven會幫你生成一個JAR包;如果你定義該元素的值為war,那你會得到一個WAR包;如果定義其值為POM(比如是一個父模塊),那什么包都不會生成。你不需要了解具體的打包細節,你所需要做的就是告訴Maven,”我是個什么類型的項目“,這就是約定優于配置的力量。


為了更好的理解Maven的默認打包方式,我們不妨來看看簡單的聲明背后發生了什么,對一個jar項目執行mvn package操作,會看到如下的輸出:

--- maven-jar-plugin:2.3.1:jar (default-jar) @ git-demo ---
Building jar: /home/juven/git_juven/git-demo/target/git-demo-1.2-SNAPSHOT.jar

相比之下,對一個war項目執行mvn package操作,輸出是這樣的:

--- maven-war-plugin:2.1:war (default-war) @ webapp-demo ---
Packaging webapp
Assembling webapp [webapp-demo] in [/home/juven/git_juven/webapp-demo/target/webapp-demo-1.0-SNAPSHOT]
Processing war project
Copying webapp resources [/home/juven/git_juven/webapp-demo/src/main/webapp]
Webapp assembled in [90 msecs]
Building war: /home/juven/git_juven/webapp-demo/target/webapp-demo-1.0-SNAPSHOT.war

對應于同樣的package生命周期階段,Maven為jar項目調用了maven-jar-plugin,為war項目調用了maven-war-plugin,換言之,packaging直接影響Maven的構建生命周期。了解這一點非常重要,特別是當你需要自定義打包行為的時候,你就必須知道去配置哪個插件。一個常見的例子就是在打包war項目的時候排除某些web資源文件,這時就應該配置maven-war-plugin如下:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <version>2.1.1</version>
    <configuration>
      <webResources>
        <resource>
          <directory>src/main/webapp</directory>
          <excludes>
            <exclude>**/*.jpg</exclude>
          </excludes>
        </resource>
      </webResources>
    </configuration>
  </plugin>

自定義格式包
實際的軟件項目常常會有更復雜的打包需求,例如我們可能需要為客戶提供一份產品的分發包,這個包不僅僅包含項目的字節碼文件,還得包含依賴以及相關腳本文件以方便客戶解壓后就能運行,此外分發包還得包含一些必要的文檔。這時項目的源碼目錄結構大致是這樣的:

pom.xml
src/main/java/
src/main/resources/
src/test/java/
src/test/resources/
src/main/scripts/
src/main/assembly/
README.txt

除了基本的pom.xml和一般Maven目錄之外,這里還有一個src/main/scripts/目錄,該目錄會包含一些腳本文件如run.sh和run.bat,src/main/assembly/會包含一個assembly.xml,這是打包的描述文件,稍后介紹,最后的README.txt是份簡單的文檔。

我們希望最終生成一個zip格式的分發包,它包含如下的一個結構:

bin/
lib/
README.txt

其中bin/目錄包含了可執行腳本run.sh和run.bat,lib/目錄包含了項目JAR包和所有依賴JAR,README.txt就是前面提到的文檔。

描述清楚需求后,我們就要搬出Maven最強大的打包插件:maven-assembly-plugin。它支持各種打包文件格式,包括zip、tar.gz、tar.bz2等等,通過一個打包描述文件(該例中是src/main/assembly.xml),它能夠幫助用戶選擇具體打包哪些文件集合、依賴、模塊、和甚至本地倉庫文件,每個項的具體打包路徑用戶也能自由控制。如下就是對應上述需求的打包描述文件src/main/assembly.xml:

<assembly>
  <id>bin</id>
  <formats>
    <format>zip</format>
    <format>war</format>
  </formats>
  <dependencySets>
    <dependencySet>
      <useProjectArtifact>true</useProjectArtifact>
      <outputDirectory>lib</outputDirectory>
    </dependencySet>
  </dependencySets>
  <fileSets>
    <fileSet>
      <outputDirectory>/</outputDirectory>
      <includes>
        <include>README.txt</include>
      </includes>
    </fileSet>
    <fileSet>
      <directory>src/main/scripts</directory>
      <outputDirectory>/bin</outputDirectory>
      <includes>
        <include>run.sh</include>
        <include>run.bat</include>
      </includes>
    </fileSet>
  </fileSets>
</assembly>
  • 首先這個assembly.xml文件的id對應了其最終生成文件的classifier。
  • 其次formats定義打包生成的文件格式,這里是zip。因此結合id我們會得到一個名為hello-world-1.0-bin.zip的文件。(假設artifactId為hello-world,version為1.0)??梢酝瑫r指定多個打包格式。
  • dependencySets用來定義選擇依賴并定義最終打包到什么目錄,這里我們聲明的一個depenencySet默認包含所有所有依賴,而useProjectArtifact表示將項目本身生成的構件也包含在內,最終打包至輸出包內的lib路徑下(由outputDirectory指定)。
  • fileSets允許用戶通過文件或目錄的粒度來控制打包。這里的第一個fileSet打包README.txt文件至包的根目錄下,第二個fileSet則將src/main/scripts下的run.sh和run.bat文件打包至輸出包的bin目錄下。更多配置參考這里

最后,我們需要配置maven-assembly-plugin使用打包描述文件,并綁定生命周期階段使其自動執行打包操作:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-assembly-plugin</artifactId>
  <version>2.2.1</version>
  <configuration>
    <descriptors>
      <descriptor>src/main/assembly/assembly.xml</descriptor>
    </descriptors>
  </configuration>
  <executions>
    <execution>
      <id>make-assembly</id>
      <phase>package</phase>
      <goals>
        <goal>single</goal>
      </goals>
    </execution>
  </executions>
</plugin>

運行mvn clean package之后,我們就能在target/目錄下得到名為hello-world-1.0-bin.zip的分發包了。


要點:
默認打包插件:對應于同樣的package生命周期階段,Maven為jar項目調用了maven-jar-plugin,為war項目調用了maven-war-plugin。
定制化打包插件:maven-assembly-plugin支持定制化打包方式,通過一個打包描述文件src/main/assembly.xml。運行mvn clean package之后,就能在target目錄下得到所打的包。


參考:
http://www.infoq.com/cn/news/2011/06/xxb-maven-9-package
http://www.lxweimin.com/p/14bcb17b99e0

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,948評論 18 139
  • Spring Boot 參考指南 介紹 轉載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,958評論 6 342
  • maven打包生成普通jar時,只會包含工程下源碼編譯結果,不包含pom.xml里依賴的jar,如需加入項目依賴的...
    Sx_Ren閱讀 21,505評論 0 4
  • 說明 非web項目中經常遇到需要將工程打包成一個可執行jar包(通過在命令行執行java命令進行啟動)的情況。一個...
    我相信你愛過gg閱讀 1,006評論 0 4
  • 說明 非web項目中經常遇到需要將工程打包成一個可執行jar包(通過在命令行執行java命令進行啟動)的情0000...
    200cc閱讀 27,003評論 0 19