maven-assembly-plugin的使用

本文主要介绍maven-assembly-plugin插件的使用

简介

The Assembly Plugin for Maven is primarily intended to allow users to aggregate the project output along with its dependencies, modules, site documentation, and other files into a single distributable archive.

中文翻译为:Maven的Assembly Plugin主要用于允许用户将项目输出及其依赖项,模块,站点文档和其他文件聚合到一个可分发的归档中。参考官网

简单来说,maven-assembly-plugin 就是用来帮助打包用的,比如说打出一个什么类型的包,包里包括哪些内容等等。

目前至少支持以下打包类型:

  • zip
  • tar
  • tar.gz (or tgz)
  • tar.bz2 (or tbz2)
  • tar.snappy
  • tar.xz (or txz)
  • jar
  • dir
  • war

默认情况下,打jar包时,只有pom.xml文件中定义的build/resources下的文件资源会被打包到jar中,并且文件名是${artifactId}-${version}.jar

若要在maven中使用maven-assembly-plugin插件,一般情况下需要三步:

  • 你需要定义一个Assembly Descriptor文件
  • 在pom.xml文件中配置maven-assembly-plugin插件
  • 在你的项目上运行mvn assembly:single

使用

引用插件

首先需要添加插件声明:

<plugin>  
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>2.4</version>
    <executions>
        <execution>
            <id>make-assembly</id>
            <!-- 绑定到package生命周期阶段上 -->
            <phase>package</phase>
            <goals>
                <goal>single</goal>
            </goals>
        </execution>  
    </executions>
</plugin> 

目前官网只给出了一个有意义的goal,详见官网Goals说明。对于assembly:single的主要作用有两个:将插件绑定到maven生命周期上;能够直接从命令行进行调用,可参考官网对assembly:single的介绍。

一般情况下,我们使用该插件主要用于打包阶段使用,所以关于execution的配置基本保持不变。

Descriptor文件

插件引入后,还需要指定一个Assembly Descriptor文件。如下:

<plugin>  
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>2.4</version>
    <configuration>
        <descriptorRefs><!-- 内置配置 -->
            <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
    </configuration>
    <executions>
        <execution>
            <id>make-assembly</id>
            <phase>package</phase>
            <goals>
                <goal>single</goal>
            </goals>
        </execution>  
    </executions>
</plugin> 

或者自定义的Assembly Descriptor文件:

<plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>2.3</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>

由上两种配置可知Assembly Descriptor文件主要有两种:内置的Assembly Descriptor文件及自定义的Assembly Descriptor文件。该文件主要用于描述所打包的文件的具体内容。

Descriptor文件中同时包含component元素,component 可以用于多个assembly descriptor之间共享。关于component的定义及component的用法,可参考官网assembly文件的componentDescriptors元素,及Component使用

内置的Assembly Descriptor

内置Descriptor文件主要有四种:

  • bin 类似于默认打包,会将bin目录下的文件打到包中
  • jar-with-dependencies 会将所有依赖都解压打包到生成物中
  • src 只将源码目录下的文件打包
  • project 将整个project资源打包

由于内置的Descriptor文件功能单一,无法满足日常的打包需求,所以一般不常用,这里仅简单介绍。

自定义Assembly Descriptor

一般来说,内置的assembly descriptor都不满足需求,这个时候就需要写自己的assembly descriptor的实现了。先从一个最简单的开始:

<assembly>
    <id>assembly</id>
    <formats>
        <format>jar</format>
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>
    <fileSets>
        <fileSet>
            <directory>${project.build.directory}/classes</directory>
            <outputDirectory>/</outputDirectory>
        </fileSet>
    </fileSets>
</assembly>

这个定义很简单:

  • format:指定打包类型
  • includeBaseDirectory:指定是否包含打包层目录(比如finalName是output,当值为true,所有文件被放在output目录下,否则直接放在包的根目录下)
  • fileSets:指定要包含的文件集,可以定义多个fileSet
  • directory:指定要包含的目录
  • outputDirectory:指定当前要包含的目录的目的地

若要使用这个assembly descriptor,需要在pom.xml文件如下配置:

<configuration>
    <finalName>demo</finalName> 
    <descriptors>
        <descriptor>package.xml</descriptor>
    </descriptors>
    <outputDirectory>${project.build.directory}/dist/</outputDirectory>
</configuration>

打包后会生成一个demo-assembly .jar 文件在目录 target/dist下,其中demo来自finalName,assembly 来自assembly descriptor中的id,其中的内容和默认的打包出来的jar类似。

如果只想有finalName,则在configuration元素下增加配置:

<appendAssemblyId>false</appendAssemblyId>
添加文件

上面演示了添加所有编译后的资源,同样的可以增加其他资源,例如想添加当前工程目录下的某个文件 b.txt ,在assembly descriptor的assembly结点下增加:

<files>  
    <file>  
        <source>b.txt</source>  
        <outputDirectory>/</outputDirectory>  
    </file>  
</files> 

这里用到了 files 元素类型,可以想象 fileSets 下的结点都是针对文件夹的;files 下的结点都是针对文件的。

也可以改变打包后的文件名,例如上面的 b.txt ,希望打包后的名字为 b.txt.bak, 只需要在file 里添加以下配置 :

<destName>b.txt.bak</destName> 
排除文件

在fileSet里可以使用includes 和 excludes来更精确的控制哪些文件要添加,哪些文件要排除。

例如要排除某个目录下所有的java文件:

<fileSet>  
    <directory>src/main/java/</directory>
    <outputDirectory>/</outputDirectory>
    <excludes>
        <exclude>**/*.java</exclude>  
    </excludes>
</fileSet> 

或者某个目录下只想包含文件:

<fileSet>
    <directory>target/classes</directory>
    <outputDirectory>/conf</outputDirectory>
    <includes>
        <include>META-INF/**</include>
        <include>**/*.properties</include>
        <include>**/*.xml</include>
    </includes>
</fileSet>
添加依赖

如果想把一些依赖库打到包里,可以用 dependencySets 元素,例如最简单的,把当前工程的所有依赖都添加到包里:

<dependencySets>
    <dependencySet>
        <outputDirectory>/</outputDirectory>
    </dependencySet>
</dependencySets>

在assembly下添加以上配置,则当前工程的依赖和工程本身生成的jar都会被打包进来。

如果要排除工程自身生成的jar,则可以在dependencySet元素下添加:

<useProjectArtifact>false</useProjectArtifact>

或者这样:

<dependencySet>
    <outputDirectory>/lib</outputDirectory>
    <scope>runtime</scope>
    <excludes>
        <exclude>${project.groupId}:${project.artifactId}</exclude>
    </excludes>
</dependencySet>

unpack参数可以控制依赖包是否在打包进来时是否解开,例如解开所有包,添加以下配置:

<unpack>true</unpack>

和 fileSet 一样,可以使用 excludes 和 includes 来更详细的控制哪些依赖需要打包进来;另外 useProjectAttachments,useTransitiveDependencies,useTransitiveFiltering等参数可以对间接依赖、传递依赖进行控制。

其他选项
  • moduleSets:当有子模块时候用
  • repositories:想包含库的时候用
  • containerDescriptorHandlers:可以进行一些合并,定义ArtifactHandler之类的时候可以用,(可以参考:说明
  • componentDescriptors:如上所述,可以包含一些componentDescriptor定义,这些定义可以被多个assembly共享
archive用法

上面已经看到了一些Assembly Plugin本身的配置,例如 finalName, outputDirectory, appendAssemblyId和descriptors等,除了这些还有其他的一些可配置参数,参见:single,其中某些参数会覆盖在assembly descriptor中的参数。有一个比较有用的参数是:archive,它的详细配置在:archive

下面介绍一些archive的用法。

指定Main-Class

archive的一个重要用处就是配置生成的MANIFEST.MF文件。默认会生成一个MANIFEST.MF文件,不过这个文件默认值没什么意义。如果想指定生成jar的Main-Class,可以如下配置:

<archive>  
    <manifest>  
        <mainClass>demo.DemoMain</mainClass>  
    </manifest>  
</archive>
添加MANIFEST项

除了可以指定Main-Class外,还可以添加任意项。要添加项,可以使用如下配置:

<archive>  
    <manifest>
        <mainClass>com.tale.Application</mainClass>
        <classpathPrefix>lib/</classpathPrefix>
        <addClasspath>true</addClasspath>
    </manifest>
    <manifestEntries>
        <!-- 在Class-Path下添加配置文件的路径 -->
        <Class-Path>resources/</Class-Path>
    </manifestEntries>
</archive>
指定MANIFEST.MF文件

还可以直接指定MANIFEST.MF文件。如下:

<archive>
    <manifestFile>META-INF/MANIFEST.MF</manifestFile>
</archive>

当然,archive的用法,可参考另一个maven插件:maven-jar-plugin。

收藏

这里放两个经典descriptor文件,以做参考:

<assembly>
    <id>assembly</id>
    <formats>
        <format>tar.gz</format>
    </formats>
    <includeBaseDirectory>true</includeBaseDirectory>
    <fileSets>
        <fileSet>
            <directory>src/main/assembly/bin</directory>
            <outputDirectory>bin</outputDirectory>
            <lineEnding>unix</lineEnding>
            <fileMode>0755</fileMode>
        </fileSet>
        <fileSet>
            <directory>src/main/assembly/conf</directory>
            <outputDirectory>conf</outputDirectory>
        </fileSet>
        <fileSet>
            <directory>target/classes</directory>
            <outputDirectory>conf</outputDirectory>
            <includes>
                <include>META-INF/**</include>
                <include>*.xml</include>
                <include>*.properties</include>
            </includes>
        </fileSet>
    </fileSets>
    <dependencySets>
        <dependencySet>
            <outputDirectory>/lib</outputDirectory>
        </dependencySet>
    </dependencySets>
</assembly>

代码出处点这里。这里是打成tar.gz包,同三个文件夹组成:

  • conf:包含所有的配置文件
  • bin:包含系统的角本文件
  • lib:包含所有jar包文件

另一个来自github:

<assembly>
    <id>customAssembly</id>
    <!-- dir -->
    <formats>
        <format>dir</format>
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>
    <fileSets>
        <fileSet>
            <directory>src/main/resources/</directory>
            <outputDirectory>/resources</outputDirectory>
        </fileSet>
        <fileSet>
            <directory>src/main/plugins/</directory>
            <outputDirectory>/plugins</outputDirectory>
        </fileSet>
        <fileSet>
            <directory>bin/</directory>
            <outputDirectory>/</outputDirectory>
        </fileSet>
    </fileSets>
    <dependencySets>
        <dependencySet>
            <outputDirectory>/lib</outputDirectory>
            <scope>runtime</scope>
            <excludes>
                <exclude>${project.groupId}:${project.artifactId}</exclude>
            </excludes>
        </dependencySet>
        <dependencySet>
            <outputDirectory>/</outputDirectory>
            <includes>
                <include>${project.groupId}:${project.artifactId}</include>
            </includes>
        </dependencySet>
    </dependencySets>
</assembly>

来源点这里,这里是打成dir,主要内容如下 :

  • lib:包含除了自身的所有jar包
  • resources:包含项目中的配置及资源文件
  • 其他角本文件及自身jar包存放在根目录

本文链接:

https://blog.wfyvv.com/archives/25.html
1 + 5 =
快来做第一个评论的人吧~