使用maven-assembly-plugin如何打包多模塊項(xiàng)目
maven-assembly-plugin打包多模塊項(xiàng)目
概述
maven-assembly-plugin 是目前maven項(xiàng)目中最常用的打包工具,它便利、配置簡(jiǎn)單,因此可以滿足我們大部分的需求。
實(shí)際開發(fā)過程中大部分Maven項(xiàng)目都是多模塊的,因?yàn)楣ぷ餍枰?,?duì)其進(jìn)行了研究與嘗試,目前可以將多模塊按照自己需求打包到一起。
1. 需求
項(xiàng)目本身代碼非常復(fù)雜,最深可以到三層模塊,即GrandFather -> Parent -> child,要求打包后的結(jié)構(gòu)如下:
????
目錄的含義不
再追溯,下面直接將打包方法。
2. 打包流程
2.1 新建打包模塊
Maven多模塊打包在一起時(shí),需要新建一個(gè)專門用于打包的模塊,該模塊不需要有任何Java代碼,只需要配置一些最終形成的環(huán)境即可。但是該模塊有一個(gè)非常重要的要求: 該模塊必須是整個(gè)項(xiàng)目最后一個(gè)進(jìn)行打包的。
可以通過配置pom.xml中加載模塊的順序來控制,最后配置進(jìn)入的即最后進(jìn)行打包的:
本人項(xiàng)目比較復(fù)雜,最終配置的打包是在tools子模塊下的tools-package模塊中進(jìn)行配置。
2.2 配置打包模塊
根據(jù)最終生成的路徑需求,將所有的相關(guān)路徑及一些命令、配置文件等按照要求在打包模塊中實(shí)現(xiàn),放在resources目錄即可。
注:該項(xiàng)目中不需要任何Java代碼
2.3 配置打包模塊的pom.xml
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>2.4.1</version> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> <configuration> <finalName>xxxxx</finalName> <descriptors> <descriptor>src/main/resources/assemble/assemble.xml</descriptor> </descriptors> </configuration> </execution> </executions> </plugin> </plugins> </build>
2.4 配置其他模塊打包方式
因?yàn)轫?xiàng)目中使用的SpringBoot,SpringBoot也提供了一種打包方式:spring-boot-maven-plugin,這種方式打包時(shí)會(huì)將該項(xiàng)目中所有依賴的包(包括靜態(tài)文件)統(tǒng)一打包至一個(gè)jar中,這個(gè)不是我們項(xiàng)目的需求,我們的需求是將所有的jar包(包括第三方及當(dāng)前項(xiàng)目的jar包)都放在lib目錄,且是單獨(dú)存在。
因此需要將其他模塊的打包配置修改,修改分為兩步:
1)不再使用spring-boot-maven-plugin進(jìn)行打包,即將其從pom.xml中刪除;
2)在pom.xml文件中使用maven-jar-plugin進(jìn)行打包,該打包如何配置請(qǐng)參考文章(待定)。
2.5 配置assemble.xml文件
assemble.xml文件中描述了具體如何打包,該打包過程和實(shí)際需求關(guān)系密切
<?xml version='1.0' encoding='UTF-8'?> <assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> <id>${project.version}</id> <formats> <format>tar.gz</format> </formats> <includeBaseDirectory>true</includeBaseDirectory> <moduleSets> <moduleSet> <useAllReactorProjects>true</useAllReactorProjects> <includes> <include>xxx.xx.x:base1</include> <include>xxx.xx.x:base2</include> <include>xxx.xx.x:base3</include> <include>xxx.xx.x:base4</include> </includes> <binaries> <outputDirectory>lib</outputDirectory> <unpack>false</unpack> </binaries> </moduleSet> </moduleSets> <fileSets> <fileSet> <directory>src/main/resources/bin</directory> <outputDirectory>bin</outputDirectory> </fileSet> <fileSet> <directory>src/main/resources/conf</directory> <outputDirectory>conf</outputDirectory> </fileSet> <fileSet> <directory>src/main/resources/docs</directory> <outputDirectory>docs</outputDirectory> </fileSet><fileSet> <directory>src/main/resources/keys</directory> <outputDirectory>keys</outputDirectory> </fileSet> <fileSet> <includes> <include>README.md</include> </includes> <outputDirectory></outputDirectory> </fileSet> </fileSets> <dependencySets> <dependencySet> <unpack>false</unpack> <useProjectArtifact>true</useProjectArtifact> <outputDirectory>lib</outputDirectory> <scope>provided</scope> </dependencySet> <dependencySet> <unpack>false</unpack> <useProjectArtifact>true</useProjectArtifact> <outputDirectory>lib</outputDirectory> <scope>system</scope> </dependencySet> <dependencySet> <unpack>false</unpack> <useProjectArtifact>true</useProjectArtifact> <outputDirectory>lib</outputDirectory> <scope>runtime</scope> </dependencySet> </dependencySets> </assembly>
具體的配置參數(shù)可以查看 https://maven.apache.org/plugins/maven-assembly-plugin/assembly.html
本人在實(shí)驗(yàn)過程中重點(diǎn)是處理了dependencySet這個(gè)配置:
<dependencySets> <dependencySet> <unpack>false</unpack> <useProjectArtifact>true</useProjectArtifact> <outputDirectory>lib</outputDirectory> <scope>provided</scope> </dependencySet> <dependencySet> <unpack>false</unpack> <useProjectArtifact>true</useProjectArtifact> <outputDirectory>lib</outputDirectory> <scope>system</scope> </dependencySet> <dependencySet> <unpack>false</unpack> <useProjectArtifact>true</useProjectArtifact> <outputDirectory>lib</outputDirectory> <scope>runtime</scope> </dependencySet> </dependencySets>
請(qǐng)配置上上述三個(gè)部分,要不然總是會(huì)缺少一些依賴包打不進(jìn)來,Mark一下,很重要!
使用maven-assembly-plugin插件來定制化打包
簡(jiǎn)單的說,maven-assembly-plugin 就是用來幫助打包用的,比如說打出一個(gè)什么類型的包,包里包括哪些內(nèi)容等等。
目前至少支持以下打包類型:
zip
tar
tar.gz
tar.bz2
jar
dir
war
默認(rèn)情況下,打jar包時(shí),只有在類路徑上的文件資源會(huì)被打包到j(luò)ar中,并且文件名是${artifactId}-${version}.jar,下面看看怎么用maven-assembly-plugin插件來定制化打包。
首先需要添加插件聲明:
<plugin> ? ? <groupId>org.apache.maven.plugins</groupId> ? ? <artifactId>maven-assembly-plugin</artifactId> ? ? <version>2.4</version> ? ? <executions> ? ? ? ? <execution> ? ? ? ? ? ? <!-- 綁定到package生命周期階段上 --> ? ? ? ? ? ? <phase>package</phase> ? ? ? ? ? ? <goals> ? ? ? ? ? ? ? ? <!-- 綁定到package生命周期階段上 --> ? ? ? ? ? ? ? ? <goal>single</goal> ? ? ? ? ? ? </goals> ? ? ? ? </execution> ? ? </executions> </plugin>
使用內(nèi)置的Assembly Descriptor
要使用maven-assembly-plugin,需要指定至少一個(gè)要使用的assembly descriptor 文件。默認(rèn)情況下,maven-assembly-plugin內(nèi)置了幾個(gè)可以用的assembly descriptor:
bin
: 類似于默認(rèn)打包,會(huì)將bin目錄下的文件打到包中;jar-with-dependencies
: 會(huì)將所有依賴都解壓打包到生成物中;src
:只將源碼目錄下的文件打包;project
: 將整個(gè)project資源打包。
要查看它們的詳細(xì)定義,可以到maven-assembly-plugin-2.4.jar里去看,例如對(duì)應(yīng) bin 的assembly descriptor 如下:
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" ? ? xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ? ? xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> ? ? <id>bin</id> ? ? <formats> ? ? ? ? <format>tar.gz</format> ? ? ? ? <format>tar.bz2</format> ? ? ? ? <format>zip</format> ? ? </formats> ? ? <fileSets> ? ? ? ? <fileSet> ? ? ? ? ? ? <directory>${project.basedir}</directory> ? ? ? ? ? ? <outputDirectory>/</outputDirectory> ? ? ? ? ? ? <includes> ? ? ? ? ? ? ? ? <include>README*</include> ? ? ? ? ? ? ? ? <include>LICENSE*</include> ? ? ? ? ? ? ? ? <include>NOTICE*</include> ? ? ? ? ? ? </includes> ? ? ? ? </fileSet> ? ? ? ? <fileSet> ? ? ? ? ? ? <directory>${project.build.directory}</directory> ? ? ? ? ? ? <outputDirectory>/</outputDirectory> ? ? ? ? ? ? <includes> ? ? ? ? ? ? ? ? <include>*.jar</include> ? ? ? ? ? ? </includes> ? ? ? ? </fileSet> ? ? ? ? <fileSet> ? ? ? ? ? ? <directory>${project.build.directory}/site</directory> ? ? ? ? ? ? <outputDirectory>docs</outputDirectory> ? ? ? ? </fileSet> ? ? </fileSets> </assembly>
自定義Assembly Descriptor
一般來說,內(nèi)置的assembly descriptor都不滿足需求,這個(gè)時(shí)候就需要寫自己的assembly descriptor的實(shí)現(xiàn)了。先從一個(gè)最簡(jiǎn)單的定義開始:
<?xml version='1.0' encoding='UTF-8'?> <assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" ? ? xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ? ? xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 ? ? ? ? ? ? ? ? ? ? ? http://maven.apache.org/xsd/assembly-1.1.0.xsd"> ? ? <id>demo</id> ? ? <formats> ? ? ? ? <format>jar</format> ? ? </formats> ? ? <includeBaseDirectory>false</includeBaseDirectory> ? ? <fileSets> ? ? ? ? <fileSet> ? ? ? ? ? ? <directory>${project.build.directory}/classes</directory> ? ? ? ? ? ? <outputDirectory>/</outputDirectory> ? ? ? ? </fileSet> ? ? </fileSets> </assembly>
這個(gè)定義很簡(jiǎn)單:
format
:指定打包類型;includeBaseDirectory
:指定是否包含打包層目錄(比如finalName是output,當(dāng)值為true,所有文件被放在output目錄下,否則直接放在包的根目錄下);fileSets
:指定要包含的文件集,可以定義多個(gè)fileSet;directory
:指定要包含的目錄;outputDirectory
:指定當(dāng)前要包含的目錄的目的地。
要使用這個(gè)assembly descriptor,需要如下配置:
<configuration> ? ? ? <finalName>demo</finalName> ? ? ? <descriptors> ? ? ? ? <!--描述文件路徑--> ? ? ? ? <descriptor>assemblies/demo.xml</descriptor> ? ? ? </descriptors> ? ? ? <outputDirectory>output</outputDirectory> </configuration>?
最后會(huì)生成一個(gè)demo-demo.jar 文件在目錄 output 下,其中前一個(gè)demo來自finalName,后一個(gè)demo來自assembly descriptor中的id,其中的內(nèi)容和默認(rèn)的打包出來的jar類似。
如果只想有finalName,則增加配置:
<appendAssemblyId>false</appendAssemblyId> ?
添加文件
上面演示了添加所有編譯后的資源,同樣的可以增加其他資源,例如想添加當(dāng)前工程目錄下的某個(gè)文件 b.txt ,在assembly descriptor的assembly結(jié)點(diǎn)下增加
<files> ? ? <file> ? ? ? ? <source>b.txt</source> ? ? ? ? <outputDirectory>/</outputDirectory> ? ? </file> </files>
這里用到了 files 元素類型,可以想象 fileSets 下的結(jié)點(diǎn)都是針對(duì)文件夾的;files 下的結(jié)點(diǎn)都是針對(duì)文件的。
也可以改變打包后的文件名,例如上面的 b.txt ,希望打包后的名字為 b.txt.bak, 只需要在file 里添加以下配置 :
<destName>b.txt.bak</destName>
排除文件
在 fileSet 里可以使用 includes 和 excludes 來更精確的控制哪些文件要添加,哪些文件要排除。
例如要排除某個(gè)目錄下所有的txt文件:
<fileSet> ? ? ? <directory>${project.build.directory}/classes</directory> ? ? ? <outputDirectory>/</outputDirectory> ? ? ? <excludes> ? ? ? ? ? <exclude>**/*.txt</exclude> ? ? ? </excludes> ? </fileSet>
或者某個(gè)目錄下只想 .class 文件:
<fileSet> ? ? <directory>${project.build.directory}/classes</directory> ? ? <outputDirectory>/</outputDirectory> ? ? <includes> ? ? ? ? <include>**/*.class</include> ? ? </includes> </fileSet>
添加依賴
如果想把一些依賴庫打到包里,可以用 dependencySets 元素,例如最簡(jiǎn)單的,把當(dāng)前工程的所有依賴都添加到包里:
<dependencySets> ? ? <dependencySet> ? ? ? ? <outputDirectory>/</outputDirectory> ? ? </dependencySet> </dependencySets>
在assembly下添加以上配置,則當(dāng)前工程的依賴和工程本身生成的jar都會(huì)被打包進(jìn)來。
如果要排除工程自身生成的jar,則可以添加
<useProjectArtifact>false</useProjectArtifact>
unpack參數(shù)可以控制依賴包是否在打包進(jìn)來時(shí)是否解開,例如解開所有包,添加以下配置:
<unpack>true</unpack>
和 fileSet 一樣,可以使用 excludes 和 includes 來更詳細(xì)的控制哪些依賴需要打包進(jìn)來;另外 useProjectAttachments,useTransitiveDependencies,useTransitiveFiltering等參數(shù)可以對(duì)間接依賴、傳遞依賴進(jìn)行控制。
其他選項(xiàng)
moduleSets
:當(dāng)有子模塊時(shí)候用;repositories
:想包含庫的時(shí)候用;containerDescriptorHandlers
:可以進(jìn)行一些合并,定義ArtifactHandler之類的時(shí)候可以用,(可以參考:說明);componentDescriptors
:如上所述,可以包含一些componentDescriptor定義,這些定義可以被多個(gè)assembly共享。
Assembly Plugin更多配置
上面已經(jīng)看到了一些Assembly Plugin本身的配置,例如 finalName, outputDirectory, appendAssemblyId 和 descriptors 等,除了這些還有其他的一些可配置參數(shù),參見:single,其中某些參數(shù)會(huì)覆蓋在assembly descriptor 中的參數(shù)。有一個(gè)比較有用的參數(shù)是: archive,它的詳細(xì)配置在:archive。
下面介紹一些archive的用法。
指定Main-Class
archive的一個(gè)重要用處就是配置生成的MANIFEST.MF文件。默認(rèn)會(huì)生成一個(gè)MANIFEST.MF文件,不過這個(gè)文件默認(rèn)值沒什么意義。如果想指定生成jar的Main-Class,可以如下配置:
<archive> ? ? ? <manifest> ? ? ? ? ? <mainClass>demo.DemoMain</mainClass> ? ? ? </manifest> ? </archive>
下面來看一個(gè)項(xiàng)目中實(shí)際配置的文件:
pom文件:
<plugin> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <groupId>org.apache.maven.plugins</groupId> ? ? ? ? ? ? ? ? ? ? ? ?? ? ? <artifactId>maven-assembly-plugin</artifactId> ? ? ? ? ? ? ? ? ? ? ? ? ? <version>${maven-assembly-plugin.version}</version> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <configuration> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ? ? ? ? <descriptors> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ? ? ? ? ? ? <descriptor>package.xml</descriptor> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </descriptors> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </configuration> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <executions> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <execution> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ? ? ? ? ? ? <id>make-assembly</id> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <phase>package</phase> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <goals> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ? ? ? ? ? ? ? ? <goal>single</goal> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ? ? ? ? ? ? </goals> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </execution> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </executions> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? </plugin> ?
assembly descriptor 文件:
<assembly> ? ? <id>${assembly-id}</id> ? ? <!-- 最終打包成一個(gè)用于發(fā)布的war文件 --> ? ? <formats> ? ? ? ? <format>${assembly-format}</format> ? ? </formats> ? ? <fileSets> ? ? ? ? <!-- 把項(xiàng)目公用的配置文件,打包進(jìn)zip文件的config目錄 --> ? ? ? ? <fileSet> ? ? ? ? ? ? <directory>${project.basedir}/src/main/resources/base</directory> ? ? ? ? ? ? <outputDirectory>WEB-INF/classes</outputDirectory> ? ? ? ? </fileSet> ? ? ? ? <!-- 把項(xiàng)目環(huán)境的配置文件,打包進(jìn)zip文件的config目錄 --> ? ? ? ? <fileSet> ? ? ? ? ? ? <directory>${project.basedir}/src/main/resources/${env}</directory> ? ? ? ? ? ? <outputDirectory>WEB-INF/classes</outputDirectory> ? ? ? ? </fileSet> ? ? ? ? <!-- 打包項(xiàng)目自己編譯出來的jar文件 --> ? ? ? ? <fileSet> ? ? ? ? ? ? <directory>${project.build.directory}</directory> ? ? ? ? ? ? <outputDirectory>WEB-INF/lib</outputDirectory> ? ? ? ? ? ? <includes> ? ? ? ? ? ? ? ? <include>*.jar</include> ? ? ? ? ? ? </includes> ? ? ? ? </fileSet> ? ? ? ? <!-- 打包項(xiàng)目依賴的jar文件 --> ? ? ? ? <fileSet> ? ? ? ? ? ? <directory>${project.build.directory}</directory> ? ? ? ? ? ? <outputDirectory>/</outputDirectory> ? ? ? ? ? ? <includes> ? ? ? ? ? ? ? ? <include>WEB-INF/lib/*.jar</include> ? ? ? ? ? ? </includes> ? ? ? ? </fileSet> ? ? </fileSets> </assembly>
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java實(shí)現(xiàn)銀行賬戶管理子系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)銀行賬戶管理子系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05spring?boot只需兩步優(yōu)雅整合activiti示例解析
這篇文章主要主要來教大家spring?boot優(yōu)雅整合activiti只需兩步就可完成測(cè)操作示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助祝大家多多進(jìn)步2022-03-03java中struts2實(shí)現(xiàn)文件上傳下載功能
這篇文章主要介紹了java中struts2實(shí)現(xiàn)文件上傳下載功能的方法,以實(shí)例形式分析了struts2文件上傳下載功能的實(shí)現(xiàn)技巧與相關(guān)問題,具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2016-05-05基于Java實(shí)現(xiàn)的大樂透號(hào)碼生成器工具類
大樂透是中國(guó)體育彩票的一種玩法,是國(guó)家體育總局體彩中心為適應(yīng)市場(chǎng)發(fā)展需要。本文為大家準(zhǔn)備了一個(gè)大樂透號(hào)碼生成器工具類,感興趣的可以了解一下2022-08-08