写点什么

Maven实战(十)——Maven 3,是时候升级了

2011 年 7 月 27 日

去年 10 月份 Apache Maven 发布了 3.0 正式版,而在上个月的 22 号, Eclipse 基金会宣布了 Eclipse 3.7(Indigo)的发布,该版本 Eclipse 最大的新特性之一就是集成了 Maven。下载 Eclipse IDE for Java Developers 版本的用户会发现,Eclipse 已经能够自动识别 Maven 项目了。Indigo 中内置的 Maven 版本是 3.0.2,这在一定程度上说明 Maven 3 已经非常稳定了。不过我相信一定还有很多 Maven 2 用户在犹豫是否升级,本文会介绍一些 Maven 3 最重要的特性,旨在帮助读者扫除疑虑,尽早享受 Maven 3 所能带来的各种便利。

确保兼容性

在升级软件的时候,兼容性显然是首先要考虑的问题,如果原本在 Maven 2 下能成功构建的项目,在 Maven 3 下立刻就失败了,而且难以简单修复,那显然是不可接受的。 好在 Maven 用户大可打消这一顾虑,Maven 3 自设计之初就一直考虑与 Maven 2 的兼容性,这不仅是指兼容 Maven 2 的核心,还包括大量的 org.apache.maven.plugins 与 org.codehaus.mojo 插件。虽然由于某些插件代码的特殊性,无法做到 100% 完全的兼容,但已经基本不会遇到问题了。

如果你还有担心,那可以先仔细阅读官方发布的 Maven 3.x 兼容性笔记 Maven 3.x 插件兼容性列表。这两份文档记录的兼容性问题主要涉及的是一些应当被弃用的特性,并且都给出了 Maven 3 下的解决方案。

改进性能

Maven 3 的性能较之于 Maven 2 是有了很大的进步的,这体现在内存占用的减少和构建时间的减少两个方面。特别是 Maven 3 引入的并行构建特性,能够分析项目模块之间的依赖关系,然后并行地构建那些相互间没有依赖关系的模块,从而充分利用如今普遍的多核 CPU 资源。

以下两条命令分别表示用 4 个线程构建,以及根据 CPU 核数每个核分配 1 个线程进行构建:

复制代码
$ mvn -T 4 clean install
$ mvn -T 1C clean install

Maven 的提交者之一 Anders Hammar 在其文章迁移到Maven 3 的十大理由中介绍了一个简单的实验,分别用Maven 2.2.1,Maven 3.0.2(单线程),和Maven 3.0.2(4 线程)构建同样的包含32 个模块的Maven 源代码,得到了如下的结果:

Table 1. 用"mvn package"构建 Maven SCM trunk(32 个模块) 时间 / 内存 Maven 2.2.1 3:20/53M Maven 3.0.2(单线程) 3:15/27M Maven 3.0.2(4 线程) 2:26/28M 可以看到 Maven 3 下内存的占用减少了近一半!而开启并行构建后,时间的节省也是非常可观的。而项目越大,这种性能的改进就越为明显。如果你的开发环境没有充裕的内存,而你的项目又非常大,那光内存节省这一条就足以让你立刻转向 Maven 3 了。

改进模块间依赖解析

Maven 2 中一个比较令人头疼的问题是,当你在构建一个多模块项目的时候,为了使前面的模块能在后面模块 classpath 中生效,你必须将其 install 到本地仓库中之后,Maven 才能解析使用。几乎所有 Maven 2 用户或早或晚都遇到了这个困惑,“为什么我已经 mvn clean package 了模块 A,可构建模块 B 的时候还是无法看到 A 的更新呢?”这个问题在 Maven 3 中得以解决了,在构建多模块项目的时候,Maven 3 会从反应堆(reactor)中解析模块间依赖,也就是说只要模块 A 执行了 package,那模块 B 就能根据相对路径找到并解析使用 A 生成的 jar 文件。

提倡最佳实践

刚从 Maven 2 转到 Maven 3 的用户很可能会发现执行构建的时候命令行会打印很多如下的警告:

复制代码
[WARNING] 'build.plugins.plugin.version' for org.apache.maven.plugins:maven-javadoc-plugin is missing.
[WARNING] It is highly recommended to fix these problems because they threaten the stability of your build.

大部分如下的警告是因为用户在配置插件或者依赖的时候没有指定版本,无法保证构建的可重现性,从而为构建引入了潜在的风险。这样的警告是一种既保持兼容性,又提倡最佳实践而做出的权衡。类似的改进还包括弃用 profile.xml 特性、明确分离项目依赖和插件依赖等等。

改进日志输出

这是一个很微小的改进,却突显了 Maven 开发者对 Maven 用户的关怀,我个人非常喜欢这点改进。简单得来说,Maven 3 的构建日志更容易阅读了。插件的输出之间都有空行隔开,每个被运行插件的版本、目标、以及所处模块的 artifactId 都得以清晰显示。当构建出现错误的时候,这样的输出能帮助用户更快地找到问题所在。

站点(注意!)

站点这一特性是 Maven 2 的核心,但是在 Maven 3 中,该特性被完全移到了 maven-site-plugin 中,这就导致了相关的配置也需要转移。Maven 2 中与站点相关的配置是在 POM 的 reporting 元素下的,如:

复制代码
<project>
...
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.7</version>
</plugin>
</plugins>
</reporting>
</project>

在 Maven 3 中,所有站点相关的配置都应该出现在 maven-site-plugin 下面:

复制代码
<project>
...
<build>
...
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>3.0-beta-3</version>
<configuration>
<reportPlugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.7</version>
</plugin>
</reportPlugins>
</configuration>
</plugin>
</plugins>
</build>
</project>

小结与致谢

本文从兼容性、新特性、性能改进、以及重要细节等方面全面介绍了 Maven 3。Maven 3 是 Maven 从成熟走向巅峰的标志,如果你还未升级,我强烈建议你至少尝试一下,Maven 的安装是非常简单的,只需要下载一个 zip 包、解压、然后设置简单的环境变量即可,马上去下载吧

由于能力及精力所限,我已经很难再写更多既不重复又符合很多读者口味的 Maven 文章,因此暂且计划将该专栏告一段落。我衷心感谢张凯峰的策划和编辑,感谢读者的支持,另外也感谢我的家人,特别是我三岁的女儿,那些给写稿的时间本该属于她们。最后,我还是会持续关心 Maven 的发展,有机会也一定会分享更多的经验和心得。

2011 年 7 月 27 日 08:0416206

评论

发布
暂无评论
发现更多内容

年末了,放个大招,力软.net/java新产品附赠服务器,不容错过

力软.net/java开发平台

Java .net 服务器

NoahTenet诺亚信条软件系统APP开发

开發I852946OIIO

系统开发

爆赞!P8架构师总结29篇多线程与高并发+设计模式核心笔记

Java架构追梦

Java 学习 架构 面试 多线程高并发

差距不止一点点!Github星标51K的性能优化文档也太香了

程序员小毕

Java 程序员 性能优化 JVM 设计模式

MySQL为Null会导致5个问题,个个致命!

王磊

MySQL MySQL使用

Java多线程编程核心技术

田维常

多线程

公安警务报警系统,二维码一键定位报警

t13823115967

二维码定位报警系统开发 微警务 二维码定位

测开之函数进阶· 第6篇《闭包》

清菡

测试开发

送你一份迷你书,全面了解如何做好大促技术备战

京东智联云开发者

DevOps

母鸡下蛋实例:多线程通信生产者和消费者wait/notify和condition/await/signal条件队列

叫练

多线程与高并发 Wait lock 线程互斥 await

Spring cloud Gateway(二) 一个Http请求的流程解析

Java 网关

阿里面试:Mybatis中方法和SQL是怎么关联起来的呢?

田维常

mybatis

如何使用mock应对测试所需随机数据

华为云开发者社区

测试 数据 Mock

SpringCloudGateway(一) 概览

Java SpringcloudGateway

智慧社区综合应用平台搭建,社区管理解决方案

t13823115967

智慧社区管理平台开发 智慧平安社区平台建设

CKLC挖矿矿机系统开发案例介绍

系统开发咨询1357O98O718

CKLC挖矿矿机系统软件开发 CKLC挖矿矿机系统开发 CKLC挖矿矿机APP系统开发

通达同城快递设计方案

garlic

架构师训练营第 1 期

RPC Demo(二) 基于 Zookeeper 的服务发现

Java zookeeper RPC 服务发现

IPFS云算力挖矿系统开发详解案例及源码

系统开发咨询1357O98O718

云算力挖矿系统开发详解 云算力APP系统软件开发 云算力模式系统开发源码 云算力软件系统开发定制

智慧警务大数据可视化分析平台建设解决方案

WX13823153201

LeetCode题解:239. 滑动窗口最大值,二叉堆,JavaScript,详细注释

Lee Chen

算法 LeetCode 前端进阶训练营

令数字起舞,让自然微笑:TECH4ALL的2020启示录

脑极体

图解HTTP权威指南(三)| Web服务器对HTTP请求的处理和响应

李先生

DevOps 运维 HTTP SRE

AAAI 2021论文:利用深度元学习对城市销量进行预测(附论文下载)

京东智联云开发者

数据库 大数据 时序预测

技术干货 | 六分钟学会使用 HBuilder 引入构建 mPaaS 小程序

蚂蚁集团移动开发平台 mPaaS

小程序 uni-app mPaaS

重新发现科技与人文的互动

脑极体

为了搞清楚类加载,竟然手撸JVM!

小傅哥

JVM 小傅哥 类加载 生命周期 加载机制

5G与4G的差别及应用

anyRTC开发者

人工智能 android AI 5G WebRTC

分享一个普通程序员的“沪漂”六年的历程以及感想

程序员老猫

回忆录 经历 年终总结 沪漂 上海买房

IPFS分布式存储矿机系统APP软件开发

开發I852946OIIO

系统开发

跨年巨作!13万字!腾讯高工纯手写“JDK源码笔记”直接带你飙向实战

比伯

Java 编程 架构 面试 计算机

2021年,算法还“香”吗?

2021年,算法还“香”吗?

Maven实战(十)——Maven 3,是时候升级了-InfoQ