Maven常见错误解决方案以及常用技巧

常用的高级玩法:
(1)使用-选项时,和后面的参数之间可以不要空格。而使用–选项时,和后面的参数之间必须有空格。

mvn help:describe -Dcmd=compiler:compile
mvn install --define maven.test.skip=true

(2)显示版本信息参数“-V”和“-v”有区别

mvn -V clean package  # --show-version 显示版本信息后继续执行Maven其他目标
mvn -v	#-version 显示版本信息。

用途:当想让Maven版本信息出现在构建输出的开始处,你应该使用-V选项。如果你正在持续构建环境里运行Maven,并且你需要知道特定构建使用了哪个Maven版本,-V选项就可以派上用场。

(3)离线模式下的运行
阻止通过网络更新插件或依赖:

-o  # --offline 离线模式工作,该参数可以阻止通过网络更新插件或依赖。

(4)加密密码
下面的命令允许你使用Maven加密密码,然后存储到Maven settings文件里:

-emp,--encrypt-master-password <password> 加密主安全密码
-ep,--encrypt-password <password>  加密服务器密码

(5)多模块执行过程中的失败处理
下面的选项控制,在多模块项目构建的中间阶段,Maven如何应对构建失败:

-fae, --fail-at-end 仅影响构建结果,允许不受影响的构建继续(跳过失败的模块,编译到最后再报错)
-ff, --fail-fast 遇到构建失败就停下来
-fn,--fail-never 无论项目结果如何,构建从不失败

解析:-fn 和 -fae选项对于使用持续集成工具(例如Hunson、Jenkins)的多模块构建非常有用。 -ff 选项对于运行交互构建的开发者非常有用,因为开发者在开发周期中想得到快速的反馈。

(6)配置Maven本身日志输出

-e, --errors 产生执行错误相关消息

-X, --debug 产生执行调试信息

-q, --quiet 仅仅显示错误

解析:只有出现错误或问题,-q 选项才打印一条消息。-X 选项会打印大量的调试日志消息,这个选项主要被Maven开发者和Maven插件开发者用来诊断在开发过程中碰到的Maven代码问题。如果你想诊断依赖或路径问题,-X 选项也非常有用。如果你是Maven开发者,或者你需要诊断Maven插件的一个错误,那么-e选项就会派上用场。如果你想报告Maven或Maven插件的一个未预料到的问题,你应该传递-X 和 -e命令行选项。

(7)用批处理方式运行Maven
要在批处理模式下运行Maven,使用下面的选项:

-B, --batch-mode 在非交互(批处理)模式下运行

如果你需要在非交互、持续集成环境下运行Maven,必须要使用批处理模式。在非交互模式下运行,当Mven需要输入时,它不会停下来接受用户的输入,而是使用合理的默认值。

(8)依赖的下载和验证
下面的命令行选项会影响Maven和远程仓库的交互以及Maven如何验证下载的构件:

-C, --strict-checksums 如果校验码不匹配的话,构建失败

-c, --lax-checksums 如果校验码不匹配的话,产生告警

-U, --update-snapshots 在远程仓管更新发布版本或快照版本时,强制更新。

如果你关注安全,你就想带 -C选项运行Maven。Maven仓库为每个存储在仓库里的构件维护一个MD5 和 SHA1 校验码。如果构件的校验码不匹配下载的构件,Maven默认被配置成告警终端用户。如果传递-C 选项,当遇到带着错误校验码的构件,会引起Maven构建失败。如果你想确保Maven检查所有快照依赖的最新版本,-U选项非常有用。

(9)控制插件更新
下面的命令行选项告诉Maven,它将如何从远程仓库更新(或不更新)Maven插件:

-npu,--no-plugin-updates 对任何相关的注册插件,不进行最新检查。使用该选项使Maven表现出稳定行为,该稳定行为基于本地仓库当前可用的所有插件版本。

-cpu, --check-plugin-updates 对任何相关的注册插件,强制进行最新检查。强制Maven检查Maven插件的最新发布版本,即使在你的项目POM里明确规定了Maven插件版本,还是会强制更新。

-up, --update-plugins cpu的同义词.

下面的命令行选项影响Maven从远处仓库下载插件的方式:

-npr, --no-plugin-registry 对插件版本不使用~/.m2/plugin-registry.xml  里的配置。

-npr 命令行选项告诉Maven不要参考插件注册表。欲了解关于插件注册表的更多信息,去这里:http://maven.apache.org/guides/introduction/introduction-to-plugin-registry.html.

(10)非递归构建(只运行当前目录下的项目)
有时,你只想运行Maven构建,而不陷入项目子模块的构建。通过使用下面的命令行选项:

-N, --non-recursive 阻止Maven构建子模块。仅仅构建当前目录包含的项目

运行该命令行选项使Maven只为当前目录下的项目执行生命周期中的目标或步骤。

(11)执行时指定特定的文件
运行时指定pom.xml文件pom-demo.xml:

-f pom-demo.xml		# --file <file> 强制使用备用的POM文件

运行时指定settings.xml文件settings-demo.xml:

-s settings-demo.xml		# --settings <arg> 用户配置文件的备用路径

运行时指定全局配置文件settings.xml文件settings-global.xml:

-gs settings-global.xml		# --global-settings <file> 全局配置文件的备用路径

(12)裁剪反应堆

-am, --also-make 同时构建所列模块的依赖模块。必须和-pl同时使用。如 mvn -pl test -am ,将同时构建test的依赖模块。

-amd, --also-make-dependents 同时构建依赖于所列模块的模块。必须和-pl同时使用。如 mvn -pl test -amd ,将同时构建所有依赖test的模块。

-pl, --projects <arg> 构建指定的模块,模块间用逗号分隔。可以用来切割大型maven项目,达到急速构建的目的。

-rf, --resume-from <arg> 让反应堆从指定的模块开始构建。通俗点说就是指定从哪个模块开始构建。编译失败后,接着编译。

详细用法请参考:http://books.sonatype.com/mvnref-book/reference/_using_advanced_reactor_options.html
https://books.sonatype.com/mvnref-book/reference/running-sect-options.html

(13)常用Maven 内置变量

${basedir} 项目根目录(即pom.xml文件所在目录)
${project.build.directory} 构建目录,缺省为target目录
${project.build.outputDirectory} 构建过程输出目录,缺省为target/classes
${project.build.finalName} 产出物名称,缺省为${project.artifactId}-${project.version}
${project.packaging} 打包类型,缺省为jar
${project.xxx} 当前pom文件的任意节点的内容
${env.xxx} 获取系统环境变量。例如,"env.PATH"指代了$path环境变量(在Windows上是%PATH%)。
${settings.xxx} 指代了settings.xml中对应元素的值。例如:<settings><offline>false</offline></settings>通过 ${settings.offline}获得offline的值。
Java System Properties: 所有可通过java.lang.System.getProperties()访问的属性都能在POM中使用,例如 ${JAVA_HOME}

(14)关于坐标
<主版本>.<次版本>.<增量版本>-<限定符>、
其中主版本主要表示大型架构变更,次版本主要表示特性的增加,增量版本主要服务于bug修复,而限定符如alpha、beta等等是用来表示里程碑。当然不是每个项目的版本都要用到这些4个部分,根据需要选择性的使用即可。

(15)帮助规划坐标:Classifier
classifier可能是最容易被忽略的Maven特性,classifier可以是指定任意字符串,用于拼接在GAV之后来确定生成的文件内容,例如:包含源代码、包含javadoc、类文件等。最常用的装配插件:maven-assembly-plugin

例如:json-lib-2.2.2-jdk15.jar

<dependency>  
    <groupId>net.sf.json-lib</groupId>   
    <artifactId>json-lib</artifactId>   
    <version>2.2.2</version>  
    <classifier>jdk15</classifier>    
</dependency>

例如:json-lib-2.2.2-jdk15-javadoc.jar

<dependency>  
    <groupId>net.sf.json-lib</groupId>   
    <artifactId>json-lib</artifactId>   
    <version>2.2.2</version>  
    <classifier>jdk15-javadoc</classifier>    
</dependency> 

但是一定要注意classifier的位置:

<dependency>  
    <groupId>net.sf.json-lib</groupId>   
    <artifactId>json-lib</artifactId>   
    <classifier>jdk15-javadoc</classifier>  
    <version>2.2.2</version>   
</dependency>

生成出来的文件名:json-lib-jdk15-javadoc-2.2.2.jar

(16)POM文件重构技巧
一般情况,随着项目越做越久,越做越大,往往依赖关系就会变的复杂,就会引入用不到的依赖,需要重构。

  1. 当前模块与父模块使用同样的groupId和version时,就可以将和元素删除
  2. 使用标签properties提取相同版本号为变量。模块越多,潜在的重复就越多,重构就越有必要。
  3. 对插件指定groupId和version。例如:缺少指定groupId和version时:Maven默认是官方插件;缺少指定version时,Maven会默认使用最新版本(Maven2会使用最新的版本,包括SNAPSHOT,而Maven 3则只使用最新的非SNAPSHOT版本)。

那么如何知道哪些依赖是用到的,哪些是用不到的呢??
Maven官方还提供了一个非常有用的Maven Dependency Plugin来帮助我们分析项目中哪些依赖配置应该删除,那些依赖配置应该增加。

mvn dependency:analyze
[INFO] --- maven-dependency-plugin:2.1:analyze (default-cli) @ sample-bar ---
[WARNING] Used undeclared dependencies found:
[WARNING]    org.springframework:spring-context:jar:2.5.6:compile
[WARNING] Unused declared dependencies found:
[WARNING]    org.springframework:spring-core:jar:2.5.6:compile
[WARNING]    org.springframework:spring-beans:jar:2.5.6:compile
[INFO] ------------------------------------------------------------------------

解析:
第一部分:Used undeclared dependencies 是指那些在项目中直接使用到的,但没有在POM中配置的依赖,所以,应该在POM中显式的声明和指定。 例如:上面输出的org.springframework:spring-context:jar:2.5.6,是已经配置的依赖引入的(也就是依赖的依赖),这就存在一定的风险,因为对于传递性依赖的变化比较模糊,当这种变化造成构建失败时,就很难找到原因了。
第二部分:Unused declared dependencies,这表示那些我们配置了,但并未直接使用的依赖。需要注意的时,对于这些依赖,我们不该直接简单地删除。由于dependency:analyze只分析编译主代码和测试代码使用的依赖,一些执行测试和运行时的依赖它发现不了,因此还需要人工分析。通常情况,Unused declared dependencies 还是能帮助我们发现一些无用的依赖配置。

  1. 消除多模块依赖配置重复。使用继承机制以及dependencyManagement元素解决多个模块使用共同依赖的问题。
    父模块中配置dependencies时,所有子模块都自动继承,虽然达到了统一依赖的问题,但是对于某些子模块用不到的依赖,也会直接继承。
    父模块中配置dependencyManagement只会影响现有依赖的配置,但不会引入依赖。例如:
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactid>junit</artifactId>
      <version>4.8.2</version>
      <scope>test</scope>
    
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值