maven之打包插件(maven-assembly-plugin,maven-shade-plugin与maven-assembly-plugin)

一. 介绍

maven提供的打包插件有如下三种:

plugin function
maven-jar-plugin maven 默认打包插件,用来创建 project jar
maven-shade-plugin 用来打可执行包,executable(fat) jar
 maven-assembly-plugin  支持定制化打包方式,例如 apache 项目的打包方式

每种打包方式都具有自己的应用场景。

二. 打包准备

1). 需要设定文件的编码格式(如果不设定,将会以系统的默认编码进行处理)与JDK版本版本变量,代码如下:

<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
    </properties>

2). 需要确定依赖的scope:默认的scope包括如下

scope 说明
compile 默认的范围;如果没有提供一个范围,那该依赖的范围就是编译范围。编译范围依赖在所有的classpath 中可用,同时它们也会被打包
provided 依赖只有在当JDK 或者一个容器已提供该依赖之后才使用。例如, 如果你开发了一个web 应用,你可能在编译 classpath 中需要可用的Servlet API 来编译一个servlet,但是你不会想要在打包好的WAR 中包含这个Servlet API;这个Servlet API JAR 由你的应用服务器或者servlet 容器提供。已提供范围的依赖在编译classpath (不是运行时)可用。它们不是传递性的,也不会被打包。
 runtime  依赖在运行和测试系统的时候需要,但在编译的时候不需要。比如,你可能在编译的时候只需要JDBC API JAR,而只有在运行的时候才需要JDBC驱动实现。
 test  test范围依赖 在一般的编译和运行时都不需要,它们只有在测试编译和测试运行阶段可用
 system  system范围依赖与provided 类似,但是你必须显式的提供一个对于本地系统中JAR 文件的路径。这么做是为了允许基于本地对象编译,而这些对象是系统类库的一部分。这样的构件应该是一直可用的,Maven 也不会在仓库中去寻找它。如果你将一个依赖范围设置成系统范围,你必须同时提供一个 systemPath 元素。注意该范围是不推荐使用的(你应该一直尽量去从公共或定制的 Maven 仓库中引用依赖)

3) maven的build:

    build分为两种:

    a.  base build(既为project的子元素)

<build>
    <defaultGoal>install</defaultGoal>
    <directory>${basedir}/target</directory>
    <finalName>${artifactId}-${version}</finalName>
    <filters>
        <filter>filters/filter1.properties</filter>
    </filters>
    ...
</build> 

上述例子中:

defaultGoal:执行build任务时,如果没有指定目标,将使用的默认值,上述例子犹如 mvn install.

directory:build目标文件的存放目录,默认在${basedir}/target目录;

finalName:build目标文件的文件名,默认情况下为${artifactId}-${version};

    b. 指定一个特定的resource位置。例如

<build>
    ...
    <resources>
         <resource>
            <targetPath>META-INF/plexus</targetPath>
            <filtering>false</filtering>
            <directory>${basedir}/src/main/plexus</directory>
            <includes>
                <include>configuration.xml</include>
            </includes>
            <excludes>
                <exclude>**/*.properties</exclude>
            </excludes>
         </resource>
    </resources>
    <testResources>
        ...
    </testResources>
    ...
</build>  

1、resources:一个resource元素的列表,每一个都描述与项目关联的文件是什么和在哪里;
2、targetPath:指定build后的resource存放的文件夹。该路径默认是basedir。通常被打包在JAR中的resources的目标路径为META-INF;
3、filtering:true/false,表示为这个resource,filter是否激活。
4、directory:定义resource所在的文件夹,默认为${basedir}/src/main/resources;
5、includes:指定作为resource的文件的匹配模式,用*作为通配符;
6、excludes:指定哪些文件被忽略,如果一个文件同时符合includes和excludes,则excludes生效;
7、testResources:定义和resource类似,但只在test时使用,默认的test resource文件夹路径是${basedir}/src/test/resources,test resource不被部署。

 

c. plugins,如下代码所示:

<build>
    ...
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.0</version>
            <extensions>false</extensions>
            <inherited>true</inherited>
            <configuration>
                <classifier>test</classifier>
            </configuration>
            <dependencies>...</dependencies>
            <executions>...</executions>
        </plugin>
    </plugins>
</build>  

除了groupId:artifactId:version标准坐标,plugin还需要如下属性:
1、extensions:true/false,是否加载plugin的extensions,默认为false;
2、inherited:true/false,这个plugin是否应用到该POM的孩子POM,默认true;
3、configuration:配置该plugin期望得到的properies,如上面的例子,我们为maven-jar-plugin的Mojo设置了classifier属性;如果你的POM有一个parent,它可以从parent的build/plugins或者pluginManagement集成plugin配置。

 

三. maven-jar-plugin插件

(备注以下内容引自https://www.ibm.com/developerworks/cn/java/j-5things13/index.html)

该插件为pom默认的打包插件。

使用 Maven 构建一个 JAR 文件比较容易:只要定义项目包装为 “jar”,然后执行包装生命周期阶段即可。但是定义一个可执行 JAR 文件却比较麻烦。采取以下步骤可以更高效:

  1. a. 在您定义可执行类的 JAR 的 MANIFEST.MF 文件中定义一个 main 类。(MANIFEST.MF 是包装您的应用程序时 Maven 生成的。)
  2. b. 找到您项目依赖的所有库。
  3. c. 在您的 MANIFEST.MF 文件中包含那些库,便于您的应用程序找到它们。

您可以手工进行这些操作,或者要想更高效,您可以使用两个 Maven 插件帮助您完成:maven-jar-plugin 和 maven-dependency-plugin

01.指定manfestFile位置:具体配置如下:

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <version>3.0.2</version>
        <configuration>
          <archive>
            <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
          </archive>
        </configuration>
        ...
      </plugin>
    </plugins>
  </build>
  ...
</project>

02. 使用maven-jar-plugin 修改 MANIFEST.MF文件,具体代码如下:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <classpathPrefix>lib/</classpathPrefix>
                <mainClass>com.mypackage.MyClass</mainClass>
            </manifest>
        </archive>
    </configuration>
</plugin>

所有 Maven 插件通过一个 <configuration> 元素公布了其配置,在本例中,maven-jar-plugin 修改它的 archive 属性,特别是存档文件的 manifest 属性,它控制 MANIFEST.MF 文件的内容。包括 3 个元素:

  • addClassPath:将该元素设置为 true 告知 maven-jar-plugin 添加一个 Class-Path 元素到 MANIFEST.MF 文件,以及在 Class-Path 元素中包括所有依赖项。
  • classpathPrefix:如果您计划在同一目录下包含有您的所有依赖项,作为您将构建的 JAR,那么您可以忽略它;否则使用 classpathPrefix 来指定所有依赖 JAR 文件的前缀。在清单 1 中,classpathPrefix 指出,相对存档文件,所有的依赖项应该位于 “lib” 文件夹。
  • mainClass:当用户使用 lib 命令执行 JAR 文件时,使用该元素定义将要执行的类名。上述可以通过是用maven-dependency-plugin将依赖包添加进去

maven-dependency-plugin:

当您使用这 3 个元素配置好了 MANIFEST.MF 文件之后,下一步是将所有的依赖项复制到 lib 文件夹。为此,使用 maven-dependency-plugin。代码如下:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>copy</id>
            <phase>install</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <outputDirectory>
                  ${project.build.directory}/lib
                </outputDirectory>
            </configuration>
        </execution>
    </executions>
</plugin>

maven-dependency-plugin 有一个 copy-dependencies,目标是将您的依赖项复制到您所选择的目录。本例中,我将依赖项复制到 build 目录下的 lib 目录(project-home/target/lib)。

将您的依赖项和修改的 MANIFEST.MF 放在适当的位置后,您就可以用一个简单的命令启动应用程序:

java -jar jarfilename.jar

四. maven-shade-plugin

(备注:以下内容参考:https://www.jianshu.com/p/7a0e20b30401

                                   https://gist.github.com/yangl/830e7338faf460bc5acc0442c6f6c132)

通过 maven-shade-plugin 生成一个 uber-jar,它包含所有的依赖 jar 包。也可以使用该插件解决包冲突问题。用法如下:

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>3.1.0</version>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>shade</goal>
            </goals>
            <configuration>
              <relocations>
                <relocation>
                  <pattern>org.codehaus.plexus.util</pattern>
                  <shadedPattern>org.shaded.plexus.util</shadedPattern>
                  <excludes>
                    <exclude>org.codehaus.plexus.util.xml.Xpp3Dom</exclude>
                    <exclude>org.codehaus.plexus.util.xml.pull.*</exclude>
                  </excludes>
                </relocation>
              </relocations>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
  ...
</project>

上面的配置将 org.codehaus.plexus.util jar 包重命名为 org.shaded.plexus.util。

第二个例子:

     <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>1.3.3</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <outputFile>../target/ddstutorial.jar</outputFile>
                            <transformers>
                                <transformer
                                        implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
                                <transformer
                                        implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>
                                        XX.XXX.XXX.XXX.XXXMainclass
                                    </mainClass>
                                </transformer>
                                <transformer
                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                                    <resource>META-INF/spring.handlers</resource>
                                </transformer>
                                <transformer
                          i              implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                                    <resource>META-INF/spring.schemas</resource>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

上述列子中:注意transformer标签:主要作用为了防止classes/resource标签出现重叠,而导致混乱,引入了transfirner标签:其主要包括:

1. org.apache.maven.plugins.shade.resource.ManifestResourceTransformer(重复的main不被合并):

2. org.apache.maven.plugins.shade.resource.ApacheLicenseResourceTransformer(例如可以避免META-INF/read.me被合并)

3.org.apache.maven.plugins.shade.resource.AppendingTransformer(例如META-INF/spring.handlers与META-INF/spring.schemas)如下代码所示

  <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                  <resource>META-INF/spring.handlers</resource>
   </transformer>
  <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
        <resource>META-INF/spring.schemas</resource>
    </transformer>

五. maven-assembly-plugin

  

将相关文件打包一起分发出去,常见的例如apache的分发包以及常用的zip等包信息。配置说明: 

  <plugin>
               <artifactId>maven-assembly-plugin</artifactId>
                <version>3.1.0</version>
                <configuration>
                    <outputDirectory>D:/testfolder</outputDirectory>
                  <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                      <archive>
                         <manifest>  <mainClass>mainclass</mainClass>
                         </manifest>
                     </archive>
                </configuration>

                 <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

        </plugins>

若需要将按照一定的目录进行发布的话,需要配置对应的assembly配置信息:配置信息内容如下:

<?xml version="1.0"?>

-<assembly xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/ASSEMBLY/2.0.0">

<id>bin</id>

-<formats>

<format>zip</format>

</formats>

-<dependencySets>

-<dependencySet>

<useProjectArtifact>true</useProjectArtifact>

<outputDirectory>lib</outputDirectory>

</dependencySet>

</dependencySets>

-<fileSets>

-<fileSet>

<outputDirectory>${file.separator}</outputDirectory>

-<includes>

<include>README.txt</include>

</includes>

</fileSet>

-<fileSet>

<directory>src/main/resources</directory>

<outputDirectory>${file.separator}bin</outputDirectory>

-<includes>

<include>start.sh</include>

<include>start.bat</include>

</includes>

</fileSet>

-<fileSet>

<directory>logs</directory>

<outputDirectory>${file.separator}logs</outputDirectory>

</fileSet>

-<fileSet>

<directory>datas</directory>

<outputDirectory>${file.separator}datas</outputDirectory>

</fileSet>

-<fileSet>

<directory>doc</directory>

<outputDirectory>${file.separator}doc</outputDirectory>

</fileSet>

</fileSets>

</assembly>

在POM中加入如下配置:

<plugin>
               <artifactId>maven-assembly-plugin</artifactId>
                <version>3.1.0</version>
                <configuration>
                    <outputDirectory>D:/testfolder</outputDirectory>
                    <descriptors>
                       <descriptor>assembly.xml</descriptor>
                    </descriptors>
                      <archive>
                         <manifest>
                              <mainClass>XXXXMainClass</mainClass>
                         </manifest>
                     </archive>
                </configuration>
            </plugin>

自此,介绍完毕

时间: 2024-08-01 13:08:49

maven之打包插件(maven-assembly-plugin,maven-shade-plugin与maven-assembly-plugin)的相关文章

maven 父子项目 聚合与继承 生命周期 打包插件 依赖打包 jar pom war

maven 父子关系   父项目中打包方式必须是pom  如 <packaging>pom</packaging>,父项目中使用<modules><module>msite-base</module></modules>指定子项目 子项目中使用 <parent>指定,子项目继承父项目的大部分属性 父项目 <project xmlns="http://maven.apache.org/POM/4.0.0&qu

Zsh(oh-my-zsh)的Maven自动提示插件(zsh-maven-complection)

1.有关插件的小故事(story) 我一直使用Zsh作为日常Shell工具,确切来说是oh-my-zsh,关于zsh我专门写过一篇博客我最喜爱的工具-oh-my-zsh. 从一年前我开始放弃Windows专用Linux(Ubuntu)作为开发环境,其中强大的Shell最吸引我的最主要因素:关于Linux之前也写过一篇博文我是如何在Linux(Ubuntu)上工作的?. 这个插件的主页:https://github.com/juven/maven-bash-completion 说起这个插件得从认

maven的eclipse插件运行不正常如何解决

最近重新开始搞java源代码的分析工具,其中用到了eclipse的jdt来直接分析java源代码.用maven添加了org.eclipse.jdt.core包之后,发现代码写完之后不能运行,有一些依赖无法找到.搜索了下貌似是因为从maven中央仓库下载的jdt和其依赖包都有小版本号,导致maven的依赖管理找不到这写包了(都不知道为什么能够下载下来,却不能加入到依赖中).具体情况的描述,和这里的相同. 找了半天,发现maven的eclipse有个很强大的功能,就是把eclipse目录中的插件都安

maven/gradle 打包后自动上传到nexus仓库

前提: nexus的相关repository必须设置允许redeploy,参考下图:   maven项目: pom.xml中增加以下节点: <distributionManagement> <repository> <id>nexus-3rd</id> <url>http://localhost:8081/nexus/content/repositories/thirdparty/</url> </repository>

Maven 集成Tomcat插件

国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私募机构九鼎控股打造,九鼎投资是在全国股份转让系统挂牌的公众公司,股票代码为430719,为"中国PE第一股",市值超1000亿元.  ------------------------------------------------------------------------------

mac os maven 项目打包

问题描述 mac os maven 项目打包 平时都在wins上开发,maven打包项目没有问题,现在移到mac os上开发,mvn package打包后,发现每个目录下都多处以"._"开头的文件,例如总目录下有 a,b两个文件夹,则打出来以后多出._a,._b两个文件,有人遇到过吗?是不是maven在mac os上使用有一些不同 解决方案 有人知道吗.....

用maven进行install的时候报错Error injecting: org.apache.maven.plugin.install.InstallMojo

问题描述 ------------------------------------------------------- T E S T S-------------------------------------------------------There are no tests to run.Results :Tests run: 0, Failures: 0, Errors: 0, Skipped: 0[INFO] [INFO] --- maven-war-plugin:2.1.1:w

新建maven环境,没有junit:jar:3.8.1 ,但是maven自己是依赖这个版本的

问题描述 新建maven环境,没有junit:jar:3.8.1 ,但是maven自己是依赖这个版本的 新建了maven环境 打包的时候报Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:2.6:resources (default-resources) on project wostore: Execution default-resources of goal org.apache.maven.plu

Maven实战. 2.2在基于UNIX的系统上安装Maven

2.2在基于UNIX的系统上安装Maven Maven是跨平台的,它可以在任何一种主流的操作系统上运行.本节将介绍如何在基于UNIX的系统(包括Linux.Mac OS以及FreeBSD等)上安装Maven. 2.2.1下载和安装 首先,与在Windows上安装Maven一样,需要检查JAVA_HOME环境变量以及Java命令,这里对细节不再赘述.命令如下:juven@juvenubuntu:~$ echo $JAVA_HOME juven@juvenubuntu:~$ javaversi