Java系列---Maven插件(与maven的生命周期相关)

一、Maven插件

各个插件的执行顺序一般是:1:clean、2:resources、3:compile、4:testResources、5:testCompile、6:test、7:jar、8:install。在图中标记的地方每一行都是由冒号分隔的,前半部分是对应的插件,后半部分是插件的执行目标也就是插件执行产生的结果。现在我们来看下上面的pom文件,我们如配置了maven-compiler-plugin这个插件,其它的插件没有配置,但最后项目构建成功,说明maven内置的各种插件,如果pom中没有配置就调用默认的内置插件,如果pom中配置了就调用配置的插件。

到此我们理解maven的构建过程或者有更多的人称是打包,就是由各种插件按照一定的顺序执行来完成项目的编译,单元测试、打包、布署的完成。各种插件的执行过程也就构成的maven的生命周期(lifecycle)。生命周期(lifecycle)各个阶段并不是独立的,可以单独执行如mvn clean,也可以一起执行如mvn clean install。而且有的mvn命令其是包括多个阶段的,如mvn compile其是包括了resources和compile两个阶段。下面分别来分析各个阶段需要的插件和输出的结果

1. maven-compiler-plugin

这个插件是把class文件、配置文件打成一个jar(war或其它格式)包。依赖包是不在jar里面的,需要建立lib目录,且jar和lib目录在同级目录。常用的打包插件有maven-jar-plugin、maven-assembly-plugin、maven-shade-plugin三种,下面分别介绍下各自己pom配置和使用特点。

<plugin>

<!-- 指定maven编译的jdk版本,如果不指定,maven3默认用jdk 1.5 maven2默认用jdk1.3 -->

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-compiler-plugin</artifactId>

<version>3.1</version>

<configuration>

<!-- 一般而言,target与source是保持一致的,但是,有时候为了让程序能在其他版本的jdk中运行(对于低版本目标jdk,源代码中不能使用低版本jdk中不支持的语法),会存在target不同于source的情况 -->

<source>1.8</source> <!-- 源代码使用的JDK版本 -->

<target>1.8</target> <!-- 需要生成的目标class文件的编译版本 -->

<encoding>UTF-8</encoding><!-- 字符集编码 -->

<skipTests>true</skipTests><!-- 跳过测试 -->

<verbose>true</verbose>

<showWarnings>true</showWarnings>

<fork>true</fork><!-- 要使compilerVersion标签生效,还需要将fork设为true,用于明确表示编译版本配置的可用 -->

<executable><!-- path-to-javac --></executable><!-- 使用指定的javac命令,例如:<executable>${JAVA_1_4_HOME}/bin/javac</executable> -->

<compilerVersion>1.3</compilerVersion><!-- 指定插件将使用的编译器的版本 -->

<meminitial>128m</meminitial><!-- 编译器使用的初始内存 -->

<maxmem>512m</maxmem><!-- 编译器使用的最大内存 -->

<compilerArgument>-verbose -bootclasspath ${java.home}\lib\rt.jar</compilerArgument><!-- 这个选项用来传递编译器自身不包含但是却支持的参数选项 -->

</configuration>

</plugin>

2. maven-jar-plugin

<plugins>

<plugin>

<artifactId>maven-jar-plugin</artifactId>

<executions>

<!-- monitor 包-jar -->

<execution>

<id>monitor</id>

<goals>

<goal>jar</goal>

</goals>

<phase>package</phase>

<configuration>

<classifier>monitor</classifier>

<includes>

<include>**/xx/xx/xx/xx/**</include>

​​​​​​​<include>**/xx/xx/xx/xx/**</include>

</includes>

</configuration>

</execution>

</executions>

</plugin>

编译时,配置非maven 指定的jar包路径

<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-compiler-plugin</artifactId>

<version>2.3.2</version>

<configuration>

<source>1.8</source>

<target>1.8</target>

<encoding>UTF-8</encoding>

<compilerArgs>

<arg>-extdirs</arg>

<arg>${project.basedir}/src/main/resources/lib/</arg>

</compilerArgs>

</configuration>

</plugin>

3. maven-dependency-plugin

<!-- 拷贝依赖包 -->

<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-dependency-plugin</artifactId>

<version>2.5.1</version>

<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>

4. maven-shade-plugin

所有的依赖包打入到可执行jar包,如果同级目录有其它可执行jar,依赖可能会产生冲突,且运行jar时,有时会出现SF、DSA、RSA文件冲突的提示,需要排除META-INF目录下的文件

将部分jar包添加或排除

<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-shade-plugin</artifactId>

<version>3.1.1</version>

<executions>

<execution>

<phase>package</phase>

<goals>

<goal>shade</goal>

</goals>

<configuration>

<artifactSet>

<excludes>

<exclude>jmock:*</exclude>

<exclude>*:xml-apis</exclude>

<exclude>org.apache.maven:lib:tests</exclude>

<exclude>log4j:log4j:jar:</exclude>

</excludes>

<includes>

<include>junit:junit</include>

</includes>

</artifactSet>

</configuration>

</execution>

</executions>

</plugin>

将依赖jar包内部资源添加或排除

<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-shade-plugin</artifactId>

<version>3.1.1</version>

<executions>

<execution>

<phase>package</phase>

<goals>

<goal>shade</goal>

</goals>

<configuration>

<filters>

<filter>

<artifact>junit:junit</artifact>

<includes>

<include>junit/framework/**</include>

<include>org/junit/**</include>

</includes>

<excludes>

<exclude>org/junit/experimental/**</exclude>

<exclude>org/junit/runners/**</exclude>

</excludes>

</filter>

<filter>

<artifact>*:*</artifact>

<excludes>

<exclude>META-INF/*.SF</exclude>

<exclude>META-INF/*.DSA</exclude>

<exclude>META-INF/*.RSA</exclude>

</excludes>

</filter>

</filters>

</configuration>

</execution>

</executions>

</plugin>

自动将所有不使用的类排除

<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-shade-plugin</artifactId>

<version>3.1.1</version>

<executions>

<execution>

<phase>package</phase>

<goals>

<goal>shade</goal>

</goals>

<configuration>

<minimizeJar>true</minimizeJar>

</configuration>

</execution>

</executions>

</plugin>

将依赖的类重命名并打包进来 (隔离方案)

<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-shade-plugin</artifactId>

<version>3.1.1</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>

修改包的后缀名

<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-shade-plugin</artifactId>

<version>3.1.1</version>

<executions>

<execution>

<phase>package</phase>

<goals>

<goal>shade</goal>

</goals>

<configuration>

<shadedArtifactAttached>true</shadedArtifactAttached>

<shadedClassifierName>jackofall</shadedClassifierName> <!-- Any name that makes sense -->

</configuration>

</execution>

</executions>

</plugin>

问题:Invalid signature file digest for Manifest main attributes

原因:有些jar包生成时,会 使用jarsigner生成文件签名(完成性校验),分为两个文件存放在META-INF目录下:

a signature file, with a .SF extension;

a signature block file, with a .DSA, .RSA, or .EC extension;

解决方案:生成 uber-jar时,将这些排除掉,不再进行完成性校验,如下所示:

<configuration>

<filters>

<filter>

<artifact>*:*</artifact>

<excludes>

<exclude>META-INF/*.SF</exclude>

<exclude>META-INF/*.DSA</exclude>

<exclude>META-INF/*.RSA</exclude>

</excludes>

</filter>

</filters>

</configuration>

较详细的版本

    <plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-shade-plugin</artifactId>

<version>2.4.3</version>

<executions>

<execution>

<phase>package</phase>

<goals>

<goal>shade</goal>

</goals>

<configuration>

<filters>

<filter>

<artifact>*:*</artifact>

<excludes>

<exclude>META-INF/*.SF</exclude>

<exclude>META-INF/*.DSA</exclude>

<exclude>META-INF/*.RSA</exclude>

</excludes>

</filter>

</filters>

<transformers>

<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>

<transformer

implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">

<resource>META-INF/spring.tooling</resource>

</transformer>

<transformer

implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">

<mainClass>com.xxx.xxxInvoke</mainClass>

</transformer>

</transformers>

<minimizeJar>true</minimizeJar>

<shadedArtifactAttached>true</shadedArtifactAttached>

</configuration>

</execution>

</executions>

</plugin>

5. maven-resources-plugin

resource插件的功能就是把项目需要的配置文件拷贝到指定的目当,默认是拷贝src\main\resources目录下的件到classes目录下,当然可以自己来配置源目录和输出目录。resources插件一般不单独执行,complie插件执行时会先调用resources插件

<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-resources-plugin</artifactId>

<version>2.6</version>

<executions>

<execution>

<id>copy-resources</id>

<!-- 在default生命周期的 validate阶段就执行resources插件的copy-resources目标 -->

<phase>validate</phase>

<goals>

<goal>copy-resources</goal>

</goals>

<configuration>

<!-- 指定resources插件处理资源文件到哪个目录下 -->

<outputDirectory>${project.build.outputDirectory}</outputDirectory>

<!-- 也可以用下面这样的方式(指定相对url的方式指定outputDirectory) <outputDirectory>target/classes</outputDirectory> -->

<!-- 待处理的资源定义 -->

<resources>

<resource>

<!-- 指定resources插件处理哪个目录下的资源文件 -->

<directory>src/main/${deploy.env}/applicationContext.xml</directory>

<!-- 指定不需要处理的资源 <excludes> <exclude>WEB-INF/*.*</exclude> </excludes> -->

<!-- 是否对待处理的资源开启过滤模式 (resources插件的copy-resources目标也有资源过滤的功能,这里配置的

这个功能的效果跟<build><resources><resource>下配置的资源过滤是一样的,只不过可能执行的阶段不一样, 这里执行的阶段是插件指定的validate阶段,<build><resources><resource>下的配置将是在resources插件的resources目标执行时起作用(在process-resources阶段)) -->

<filtering>false</filtering>

</resource>

</resources>

</configuration>

<inherited></inherited>

</execution>

</executions>

</plugin>

6. maven-assembly-plugin

这个插件可以把所有的依赖包打入到可执行jar包。但是该插件有个bug会缺失spring的xds文件,导致无法运行jar,同时如果同级目录还有其它可执行jar文件依赖可能会产生冲突。

<plugin>

<artifactId>maven-assembly-plugin</artifactId>

<configuration>

<descriptorRefs>

<descriptorRef>jar-with-dependencies</descriptorRef>

</descriptorRefs>

<archive>

<manifest>

<mainClass>com.xxx.xxxService</mainClass>

</manifest>

</archive>

</configuration>

<executions>

<execution>

<id>make-assembly</id>

<phase>package</phase>

<goals>

<goal>single</goal>

</goals>

</execution>

</executions>

</plugin>

7. maven-antrun-plugin

<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-antrun-plugin</artifactId>

<version>1.8</version>

<executions>

<execution>

<phase>install</phase>

<goals>

<goal>run</goal>

</goals>

<configuration>

<tasks>

<echo>Building 描述信息 START....</echo>

<!-- 删除目录 -->

<delete dir="target/dir"/>

<!-- 删除目录 -->

<mkdir dir="target/dir"/>

<!-- 复制目录文件 复制到-todir 要复制的目录-fileset -->

<copy todir="target/dir/xxx">

<fileset dir="target/classes/config"/>

</copy>

<!-- 删除文件 -->

<delete>

<fileset dir="target/xxx/lib/xxx" includes="xxx*.jar"/>

<fileset dir="target/xxx/lib/xxx" includes="xxx-*.jar"/>

</delete>

<!-- 将指定目录压缩ZIP -->

<copy todir="target/tempbuild/xxx">

<fileset dir="target/xxx"/>

</copy>

<tstamp>

<format property="current.date.time" pattern="yyyyMMddHHmmss"/>

</tstamp>

<zip destfile="target/xxx_${version}_${current.date.time}.zip">

<zipfileset dir="target/tempbuild"/>

</zip>

<checksum file="target/xxx_${version}_${current.date.time}.zip"

forceOverwrite="yes" algorithm="MD5" fileext=".MD5"></checksum>

<delete dir="target/tempbuild"/>

<echo>Building 描述信息 END</echo>

</tasks>

</configuration>

</execution>

</executions>

</plugin>

</plugins>

二、maven三种打包插件

第一种:可执行jar与依赖分开,依赖在lib目录里,需要jar和lib目录在同级目录,
优点:jar文件很小 
缺点:需要放置lib文件夹在平级目录

1            <plugin>
 2                <groupId>org.apache.maven.plugins</groupId>
 3                <artifactId>maven-jar-plugin</artifactId>
 4                <version>2.6</version>
 5                <configuration>
 6                    <archive>
 7                        <manifest>
 8                            <addClasspath>true</addClasspath>
 9                            <classpathPrefix>lib/</classpathPrefix>
10                            <mainClass>com.xxx.xxxService</mainClass>
11                        </manifest>
12                    </archive>
13                </configuration>
14            </plugin>
15            <plugin>
16                <groupId>org.apache.maven.plugins</groupId>
17                <artifactId>maven-dependency-plugin</artifactId>
18                <version>2.10</version>
19                <executions>
20                    <execution>
21                        <id>copy-dependencies</id>
22                        <phase>package</phase>
23                        <goals>
24                            <goal>copy-dependencies</goal>
25                        </goals>
26                        <configuration>
27                            <outputDirectory>${project.build.directory}/lib</outputDirectory>
28                        </configuration>
29                    </execution>
30                </executions>
31            </plugin>

第二种:把所有依赖打进同一个jar包里。
缺点:jar文件会比较大,同时该插件有个bug会缺失spring的xds文件,导致无法运行jar,同时如果同级目录还有其它可执行jar文件依赖可能会产生冲突
优点:方便快捷,打包完直接就能运行。

1            <plugin>
 2                <artifactId>maven-assembly-plugin</artifactId>
 3                <configuration>
 4                    <descriptorRefs>
 5                        <descriptorRef>jar-with-dependencies</descriptorRef>
 6                    </descriptorRefs>
 7                    <archive>
 8                        <manifest>
 9                            <mainClass>com.xxx.xxxService</mainClass>
10                        </manifest>
11                    </archive>
12                </configuration>
13                <executions>
14                    <execution>
15                        <id>make-assembly</id>
16                        <phase>package</phase>
17                        <goals>
18                            <goal>single</goal>
19                        </goals>
20                    </execution>
21                </executions>
22            </plugin>

第三种:所有依赖打到同一个jar文件里。
缺点:jar文件过大、如果同级目录有其它可执行jar,依赖可能会产生冲突
优点:不会有任何bug,直接打成可执行jar文件,最省事。

1            <plugin>
 2                <groupId>org.apache.maven.plugins</groupId>
 3                <artifactId>maven-shade-plugin</artifactId>
 4                <version>2.4.3</version>
 5                <executions>
 6                    <execution>
 7                        <phase>package</phase>
 8                        <goals>
 9                            <goal>shade</goal>
10                        </goals>
11                        <configuration>
12                            <filters>
13                                <filter>
14                                    <artifact>*:*</artifact>
15                                    <excludes>
16                                        <exclude>META-INF/*.SF</exclude>
17                                        <exclude>META-INF/*.DSA</exclude>
18                                        <exclude>META-INF/*.RSA</exclude>
19                                    </excludes>
20                                </filter>
21                            </filters>
22                            <transformers>
23                                <transformer
24                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
25                                    <resource>META-INF/spring.handlers</resource>
26                                </transformer>
27                                <transformer
28                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
29                                    <resource>META-INF/spring.schemas</resource>
30                                </transformer>
31                                <transformer
32                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
33                                    <resource>META-INF/spring.tooling</resource>
34                                </transformer>
35                                <transformer
36                                        implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
37                                    <mainClass>com.xxx.xxxInvoke</mainClass>
38                                </transformer>
39                            </transformers>
40                            <minimizeJar>true</minimizeJar>
41                            <shadedArtifactAttached>true</shadedArtifactAttached>
42                        </configuration>
43                    </execution>
44                </executions>
45            </plugin>

三、找不到主属清单原因

  1. 打包时jdk和jre区别设置,优选jdk

在项目上右键-->build path---->config build path 选择本机jdk不要jre

右键ruan as  ---> run configuartions指定jdk版本

  1. project栏 ---> clean 最粗暴的方式
  2. Maven clean
  3. Maven-jar-pluge打包插件指定 mainclass

来源:https://www.icode9.com/content-1-876651.html

(0)

相关推荐

  • 实用的jar包加密方案

    前言 jar包相信大家都很熟悉,是通过打包java工程而获得的产物,但是jar包是有一个致命的缺点的,那就是很容易被反编译,只需要使用jd-gui就可以很容易的获取到java源码. 如果你想要防止别人 ...

  • Maven项目管理工具:Maven自动化构建

    Maven自动化构建是一种方案,即当某个项目构建完成后(特别是有代码更新的情况下),所有依赖它的相关项目也应该开始构建过程,以确保这些项目的稳定运行. Maven的自动化构建主要通过如下两种方案实现: ...

  • 不错!SpringBoot发布Jar包优化瘦身指南!

    概要说明 随着Spring Boot的流行,大家体验到只需构建输出一个jar文件,然后只需一个java -jar命令就能部署运行应用的爽快.常见一些单体应用随着项目规模的扩展单个jar文件的大小越来越 ...

  • Maven项目管理工具:Maven生命周期(clean+site+default)

    在Maven出现之前,项目构建的生命周期就已经存在,开发人员每天都在对项目进行清理,编译,测试及部署,但由于没有统一的规范,不同公司甚至不同项目之间的构建的方式都不尽相同. Maven从大量项目和构建 ...

  • 教小老弟 快速掌握 maven插件

    老铁昨天下午问我什么时候讲讲Maven插件: 于是老田搞到大半夜终于写了一篇maven的插件,今天分享给大家. 想进一步详聊了请加我微信tj20120622,进群和大家一起聊技术. Maven 是一个 ...

  • Java并发编程实战(5)- 线程生命周期

    在这篇文章中,我们来聊一下线程的生命周期. 目录 概述 操作系统中的线程生命周期 Java中的线程生命周期 Java线程状态转换 运行状态和阻塞状态之间的转换 运行状态和无时限等待状态的切换 运行状态 ...

  • 太阳系新探索系列:火星拥有无懈可击的生命工程的结构

    太阳系新探索系列:火星拥有无懈可击的生命工程的结构

  • 【学术动态】“中国美学:传统与现代系列讲座”报道之二 ——“中国生命价值哲学与传统美学”

    2021年4月7日下午,由中国社会科学院哲学所美学室主办的2021年"中国美学:传统与现代系列讲座"第二期在哲学所902会议室举办.本次讲座邀请到了美学室的老前辈韩林德研究员主讲, ...

  • 《深入理解Java虚拟机》 Java对象的生命周期

    Java虚拟机运行时数据区 方法区:存储 类信息.常量.静态变量.即使编译器编译后的代码等数据,也有别名叫做非堆.  方法区其中有包含有 运行时常量池,用于存放编译期生成的各种字面量和符号引用.其中, ...

  • 停止公益 | RNAseq系列所有插件重新启动授权要求

    我们改变不了世界,但是可以改变自己. 中午到老友家吃饭,晚上和朋友去西园吃饭,都聊了两三个小时.知道我的人可能多少有了解,我个人是非常享受边吃饭边聊天,尤其是慢慢聊,随便聊的时间.所以,今天原本我心情 ...

  • NoiseAsh系列音乐插件 Rule Tec All Collection mac

    Rule Tec All Collection mac作为NoiseAsh系列音乐插件的一款实用的无源均衡工具,这款插件可用于专业混音和母带制作,具有平滑和音乐曲线的滤镜之间复杂的传奇互动,能够帮助大 ...

  • 「50集系列讲座」从建筑与生命的角度来解读行书造型

    光荣大地.微凉 中书汇书法学苑 为了配合中书汇年度精临大赛,切实提高大家的认知与训练水平,我们正展开系列讲座,强调深度和具体指导性.计划为50讲,这是第二十八讲--从建筑与生命的角度来解读行书造型. ...