Maven权威指南中文版

更新时间:2023-04-19 18:49:02 阅读量: 实用文档 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

Maven权威指南

来源: 241c40f5f705cc17552709d2/maven‐book/reference_zh/public‐book

Authors

Tim O'Brien (Sonatype, Inc.) , John Casey (Sonatype, Inc.) , Brian Fox (Sonatype, Inc.) , Bruce Snyder () , Jason Van Zyl (Sonatype, Inc.) , Juven Xu ()

Chapter 1. 介绍 Apache Maven

1.1. Maven... 它是什么?

1.2. 约定优于配置(Convention Over Configuration)

1.3. 一个一般的接口

1.4. 基于Maven插件的全局性重用

1.5. 一个“项目”的概念模型

1.6. Maven是Ant的另一种选择么?

1.7. 比较Maven和Ant

1.8. 总结

虽然网络上有许多Maven的参考文章,但是没有一篇单独的,编写规范的介绍Maven 的文字,它需要是一本细心编排的入门指南和参考手册。我们做的,正是试图提供这样的,包含许多使用参考的文字。

1.1. Maven... 它是什么?

如何回答这个问题要看你怎么看这个问题。绝大部分Maven用户都称Maven是一个"构建工具":一个用来把源代码构建成可发布的构件的工具。构建工程师和项目经理会说Maven是一个更复杂的东西:一个项目管理工具。那么区别是什么?像Ant 这样的构建工具仅仅是关注预处理,编译,打包,测试和分发。像 Maven 这样的一个项目管理工具提供了构建工具所提供功能的超集。除了提供构建的功能,Maven还可以生成报告,生成Web站点,并且帮助推动工作团队成员间的交流。

一个更正式的Apache Maven的定义: Maven是一个项目管理工具,它包含了一个项目对象模型 (Project Object Model),一组标准集合,一个项目生命周期(Project Lifecycle),一个依赖管理系统(Dependency Management System),和用来运行定义在生命周期阶段(phase)中插件(plugin)目标(goal)的逻辑。当你使用Maven的时候,你用一个明确定义的项目对象模型来描述你的项目,然后 Maven 可以应用横切的逻辑,这些逻辑来自一组共享的(或者自定义的)插件。

别让Maven是一个"项目管理"工具的事实吓跑你。如果你只是在找一个构建工具,Maven能做这个工作。事实上,本书的一些章节将会涉及使用Maven来构建和分发你的项目。

1.2. 约定优于配置(Convention Over Configuration)

约定优于配置是一个简单的概念。系统,类库,框架应该假定合理的默认值,而非要求提供不必要的配置。流行的框架如Ruby on Rails和 EJB3 已经开始坚持这些原则,以对像原始的 EJB 2.1 规范那样的框架的配置复杂度做出反应。一个约定优于配置的例子就像 EJB3 持久化,将一个特殊的Bean持久化,你所需要做的只是将这个类标注为@Entity。框架将会假定表名和列名是基于类名和属性名。系统也提供了一些钩子,当有需要的时候你可以重写这些名字,但是,在大部分情况下,你会发现使用框架提供的默认值会让你的项目运行的更快。

Maven通过给项目提供明智的默认行为来融合这个概念。在没有自定义的情况下,源代码假定是在${basedir}/src/main/java,资源文件假定是在${basedir}/src/main/resources。测试代码假定是在${basedir}/src/test。项目假定会产生一个 JAR 文件。Maven 假定你想要把编译好的字节码放到${basedir}/target/classes并且在${basedir}/target创建一个可分发的 JAR 文件。虽然这看起来无关紧要,但是想想大部分基于 Ant 的构建必须为每个子项目定义这些目录。 Maven 对约定优于配置的应用不仅仅是简单的目录位置,Maven 的核心插件使用了一组通用的约定,以用来编译源代码,打包可分发的构件,生成 web 站点,还有许多其他的过程。 Maven 的力量来自它的"武断",它有一个定义好的生命周期和一组知道如何构建和装配软件的通用插件。如果你遵循这些约定,Maven 只需要几乎为零的工作——仅仅是将你的源代码放到正确的目录,Maven 将会帮你处理剩下的事情。

使用“遵循约定优于配置”系统的一个副作用是用户可能会觉得他们被强迫使用一

种特殊的方法。当然 Maven 有一些核心观点不应该被怀疑,但是其实很多默认行为还是可配置的。例如项目源码的资源文件的位置可以被自定义,JAR 文件的名字可以被自定义,在开发自定义插件的时候,几乎任何行为可以被裁剪以满足你特定的环境需求。如果你不想遵循约定,Maven 也会允许你自定义默认值来适应你的需求。

1.3. 一个一般的接口

在 Maven 为构建软件提供一个一般的接口之前,每个单独的项目都专门有人来管理一个完全自定义的构建系统。开发人员必须在开发软件之外去学习每个他们要参与的新项目的构建系统的特点。在2001年,构建一个项目如Turbine和构建另外一个项目如Tomcat,两者方法是完全不同的。如果一个新的进行静态源码分析的源码分析工具面世了,或者如果有人开发了一个新的单元测试框架,每个人都必须放下手头的工作去想办法使这个新东西适应每个项目的自定义构建环境。如何运行单元测试?世界上有一千种不同的答案。构建环境由无数无休止的关于工具和构建程序的争论所描述刻画。Maven 之前的时代是低效率的时代,是“构建工程师”的时代。

现在,大部分开源开发者已经或者正在使用 Maven 来管理他们新的软件项目。这种转变不仅仅是开发人员从一种构建工具转移到另外一种构建工具,更是开发人员开始为他们的项目采用一种一般的接口。随着软件系统变得越来越模块化,构建系统变得更复杂,而项目的数量更是如火箭般飞速上升。在 Maven 之前,当你想要从 Subversion 签出一个项目如Apache ActiveMQ或Apache ServiceMix,然后从源码进行构建,你需要为每个项目留出一个小时来理解给它的构建系统。这个项目需要构建什么?需要现在什么类库?把类库放哪里?构建中我该运行什么目标?最好的情况下,理解一

个新项目的构建需要几分钟,最坏的情况下(例如 Jakarta 项目的旧的 Servlet API 实现),一个项目的构建特别的困难,以至于花了几个小时以后,新的贡献者也只能编辑源码和编译项目。现在,你只要签出源码,然后运行:mvn install。虽然 Maven 有很多优点,包括依赖管理和通过插件重用一般的构建逻辑,但它成功的最核心原因是它定义了构建软件的一般的接口。每当你看到一个使用 Maven 的项目如Apache Wicket,你就可以假设你能签出它的源码然后使用mvn install构建它,没什么好争论的。你知道点火开关在哪里,你知道油门在右边,刹车在左边。

1.4. 基于Maven插件的全局性重用

Maven 的核心其实不做什么实际的事情,除了解析一些 XML 文档,管理生命周期与插件之外,它什么也不懂。Maven 被设计成将主要的职责委派给一组 Maven 插件,这些插件可以影响 Maven 生命周期,提供对目标的访问。绝大多数 Maven 的动作发生于 Maven 插件的目标,如编译源码,打包二进制代码,发布站点和其它构建任务。你从 Apache 下载的 Maven 不知道如何打包 WAR 文件,也不知道如何运行单元测试,Maven 大部分的智能是由插件实现的,而插件从 Maven 仓库获得。事实上,第一次你用全新的 Maven 安装运行诸如mvn install命令的时候,它会从中央 Maven 仓库下载大部分核心 Maven 插件。这不仅仅是一个最小化 Maven 分发包大小的技巧,这种方式更能让你升级插件以给你项目的构建提高能力。Maven 从远程仓库获取依赖和插件的这一事实允许了构建逻辑的全局性重用。

Maven Surefire 插件是负责运行单元测试的插件。从版本 1.0 发展到目前广泛使用的在 JUnit 基础上增加了 TestNG 测试框架支持的版本。这种发展并没有破坏向后兼容性,如果你使用之前 Surefire 插件编译运行你的 JUnit 3 单元测试,然后你升级到了最新版本的 Surefire 插件,你的测试仍然能成功运行。但是,我们又获得了新的功能,如果你想使用 TestNG 运行单元测试,那么感谢 Surefire 插件的维护者,你已经可以使用 TestNG 了。你也能运行支持注解的 JUnit 4 单元测试。不用升级Maven 安装或者新装任何软件,你就能获得这些功能。更重要的是,除了 POM 中一个插件的版本号,你不需要更改你项目的任何东西。

这种机制不仅仅适用于 Surefire 插件,项目使用 Compiler 插件进行编译,通过 Jar 插件变成 JAR 文件,还有一些插件生成报告,运行 JRuby 和 Groovy 的代码,以及一些用来向远程服务器发布站点的插件。Maven 将一般的构建任务抽象成插件,同时这些插件得到了很好的维护以及全局的共享,你不需要从头开始自定义你项目的构建系统然后提供支持。你完全可以从 Maven 插件获益,这些插件有人维护,可以从远程仓库下载到。这就是基于 Maven 插件的全局性重用。

1.5. 一个“项目”的概念模型

Maven 维护了一个项目的模型,你不仅仅需要把源码编译成字节码,你还需要开发软件项目的描述信息,为项目指定一组唯一的坐标。你要描述项目的的属性。项目的许可证是什么?谁开发这个项目,为这个项目做贡献?这个项目依赖于其它什么项目没有?Maven不仅仅是一个“构建工具”,它不仅仅是在类似于 make 和 Ant 的工具的基础上的改进,它是包含了一组关于软件项目和软件开发的语义规则的平台。这个基于每一个项目定义的模型实现了如下特征:

依赖管理

由于项目是根据一个包含组标识符,构件标识符和版本的唯一的坐标定义的。

项目间可以使用这些坐标来声明依赖。

远程仓库

和项目依赖相关的,我们可以使用定义在项目对象模型(POM)中的坐标来创

建 Maven 构件的仓库。

全局性构建逻辑重用

插件被编写成和项目模型对象(POM)一起工作,它们没有被设计成操作某一

个已知位置的特定文件。一切都被抽象到模型中,插件配置和自定义行为都在

模型中进行。

工具可移植性/集成

像 Eclipse,NetBeans,和 InteliJ 这样的工具现在有共同的地方来找到项目的信息。在 Maven 出现之前,每个 IDE 都有不同的方法来存储实际上是自

定义项目对象模型(POM)的信息。Maven 标准化了这种描述,而虽然每个 IDE 仍然继续维护它的自定义项目文件,但这些文件现在可以很容易的由模型生成。

便于搜索和过滤构件

像 Nexus 这样的工具允许你使用存储在 POM 中的信息对仓库中的内容进行

索引和搜索。

Maven 为软件项目的语义一致性描述的开端提供了一个基础。

1.6. Maven是Ant的另一种选择么?

当然,Maven 是 Ant 的另一种选择,但是Apache Ant继续是一个伟大的,被广泛使用的工具。它已经是多年以来 Java 构建的统治者,而你很容易的在你项目的Maven 构建中集成 Ant 构建脚本。这是 Maven 项目一种很常见的使用模式。而另一方面,随着越来越多的开源项目转移到 Maven 用它作为项目管理平台,开发人员开始意识到 Maven 不仅仅简化了构建管理任务,它也帮助鼓励开发人员的软件项目使用通用的接口。Maven 不仅仅是一个工具,它更是一个平台,当你只是将 Maven 考虑成 Ant 的另一种选择的时候,你是在比较苹果和橘子。“Maven”包含了很多构建工具以外的东西。

有一个核心观点使得所有的关于 Maven 和. Ant, Maven 和 Buildr, Maven 和Grandle 的争论变得无关紧要。Maven并不是完全根据你构建系统的机制来定义的,它不是为你构建的不同任务编写脚本,它提倡一组标注,一个一般的接口,一个生命周期,一个标准的仓库格式,一个标准的目录布局,等等。它当然也不太在意 POM 的格式正好是 XML 还是 YAML 还是 Ruby。它比这些大得多,Maven 涉及的比构建工具本身多得多。当本书讨论 Maven 的时候,它也设计到支持 Maven 的软件,系统和标准。Buildr,Ivy,Gradle,所有这些工具都和 Maven 帮助创建的仓库格式交互,而你可以很容易的使用如 Nexus 这样的工具来支持一个完全由 Buildr 编写的构建。Nexus 将在本书后面介绍。

虽然 Maven 是很多类似工具的另一个选择?但社区需要向前发展,就要看清楚技术是资本经济中不友好的竞争者之间持续的、零和的游戏。这可能是大企业之前相互关联的方式,但是和开源社区的工作方式没太大关系。“谁是胜利者?Ant 还是 Maven”这个大标题没什么建设性意义。如果你非要我们来回答这个问题,我们会很明确的说作为构建的基本技术,Maven 是 Ant 的更好选择;同时,Maven 的边界在持续的移动,Maven 的社区也在持续的是试图找到新的方法,使其更通用,互操作性更好,更易协同工作。Maven 的核心财产是声明性构建,依赖管理,仓库管理,基于插件的高度和重用,但是当前,和开源社区相互协作以降低”企业级构建“的低效率这个目标来比,这些想法的特定实现没那么重要。

1.7. 比较Maven和Ant

虽然上一节应该已经让你确信本书的作者没有兴趣挑起 Apache Ant 和 Apache Maven 之间的争执,但是我们认识到许多组织必须在 Apache Ant 和 Apache Maven 之间做一个选择。本节我们对比一下这两个工具。

Ant 在构建过程方面十分优秀,它是一个基于任务和依赖的构建系统。每个任务包含一组由 XML 编码的指令。有copy任务和javac任务,以及jar任务。在你使用 Ant 的时候,你为 Ant 提供特定的指令以编译和打包你的输出。看下面的例子,一个简单的build.xml文件:

Example 1.1. 一个简单的 Ant build.xml 文件

simple example build file

description="compile the source " >

description="generate the distribution" >

description="clean up" >

在这个简单的 Ant 例子中,你能看到,你需要明确的告诉 Ant 你想让它做什么。有一个包含javac任务的编译目标用来将src/main/java的源码编译至

target/classes目录。你必须明确告诉 Ant 你的源码在哪里,结果字节码你想存储在哪里,如何将这些字节码打包成 JAR 文件。虽然最近有些进展以帮助 Ant 减少程序,但一个开发者对 Ant 的感受是用 XML 编写程序语言。

用 Maven 样例与之前的 Ant 样例做个比较。在 Maven 中,要从 Java 源码创建一个 JAR 文件,你只需要创建一个简单的pom.xml,将你的源码放在${basedir}/src/main/java,然后从命令行运行mvn install。下面的样例Maven pom.xml文件能完成和之前 Ant 样例所做的同样的事情。

Example 1.2. 一个简单的 Maven pom.xml

4.0.0

org.sonatype.mavenbook

my-project

1.0

这就是你pom.xml的全部。从命令行运行mvn install会处理资源文件,编译源代码,运行单元测试,创建一个 JAR ,然后把这个 JAR 安装到本地仓库以为其它项目提供重用性。不用做任何修改,你可以运行mvn site,然后在target/site目录找到一个index文件,这个文件链接了 JavaDoc 和一些关于源代码的报告。诚然,这是一个最简单的样例项目。一个只包含源代码并且生成一个 JAR 的项目。一个遵循 Maven 的约定,不需要任何依赖和定制的项目。如果我们想要定制行为,我们的pom.xml的大小将会增加,在最大的项目中,你能看到一个非常复杂的 Maven POM 的集合,它们包含了大量的插件定制和依赖声明。但是,虽然你项目的 POM 文

件变得增大,它们包含的信息与一个差不多大小的基于 Ant 项目的构建文件的信息是完全不同的。Maven POM 包含声明:“这是一个 JAR 项目”,“源代码在

src/main/java目录”。Ant 构建文件包含显式的指令:“这是一个项目”,“源代码在src/main/java ”,“针对这个目录运行 javac ”,“把结果放到target/classes ”,“从……创建一个 JAR ”,等等。Ant 必须的过程必须是显式的,而 Maven 有一些“内置”的东西使它知道源代码在哪里,如何处理它们。

该例中 Ant 和 Maven 的区别是:

Apache Ant

?Ant 没有正式的约定如一个一般项目的目录结构,你必须明确的告诉 Ant 哪里去找源代码,哪里放置输出。随着时间的推移,非正式的约定出现

了,但是它们还没有在产品中模式化。

?Ant 是程序化的,你必须明确的告诉 Ant 做什么,什么时候做。你必须告诉它去编译,然后复制,然后压缩。

?Ant 没有生命周期,你必须定义目标和目标之间的依赖。你必须手工为每个目标附上一个任务序列。

Apache Maven

?Maven 拥有约定,因为你遵循了约定,它已经知道你的源代码在哪里。

它把字节码放到target/classes,然后在target生成一个 JAR

文件。

?Maven 是声明式的。你需要做的只是创建一个 pom.xml 文件然后将源代码放到默认的目录。Maven 会帮你处理其它的事情。

?Maven 有一个生命周期,当你运行mvn install的时候被调用。这条命令告诉 Maven 执行一系列的有序的步骤,直到到达你指定的生命周

期。遍历生命周期旅途中的一个影响就是,Maven 运行了许多默认的

插件目标,这些目标完成了像编译和创建一个 JAR 文件这样的工作。Maven 以插件的形式为一些一般的项目任务提供了内置的智能。如果你想要编写运行单元测试,你需要做的只是编写测试然后放到${basedir}/src/test/java,添加一个对于 TestNG 或者 JUnit 的测试范围依赖,然后运行mvn test。如果你想要部署一个 web 应用而非 JAR ,你需要做的是改变你的项目类型为 war ,然后把你文档根目录置为${basedir}/src/main/webapp。当然,你可以用 Ant 做这些事情,但是你将需要从零开始写这些指令。使用 Ant ,你首先需要确定 JUnit JAR 文件应该放在哪里,然后你需要创建一个包含这个 JUnit JAR 文件的 classpath ,然后告诉 Ant 它应该从哪里去找测试源代码,编写一个目标来编译测试源代码为字节码,使用 JUnit 来执行单元测试。

没有诸如 antlibs 和 lvy 等技术的支持(即使有了这些支持技术),Ant 给人感觉是自定义的程序化构建。项目中一组高效的坚持约定的 Maven POM ,相对于 Ant 的配置文件,只有很少的 XML 。Maven 的另一个优点是它依靠广泛公用的 Maven 插件。所有人使用 Maven Surefire 插件来运行单元测试,如果有人添加了一些针对新的测试框架的支持,你可以仅仅通过在你项目的 POM 中升级某个特定插件的版本来获得新的功能。

使用 Maven 还是 Ant 的决定不是非此即彼的,Ant 在复杂的构建中还有它的位置。如果你目前的构建包含一些高度自定义的过程,或者你已经写了一些 Ant 脚本通过一种明确的方法完成一个明确的过程,而这种过程不适合 Maven 标准,你仍然可以在Maven 中用这些脚本。作为一个 Maven 的核心插件, Ant 还是可用的。自定义的插件可以用 Ant 来实现,Maven 项目可以配置成在生命周期中运行 Ant 的脚本。

1.8. 总结

我们刻意的使这篇介绍保持得简短。我们略述了一些Maven定义的要点,它们合起来是什么,它是基于什么改进的,同时介绍了其它构建工具。下一章将深入一个简单的项目,看 Maven 如何能够通过最小数量的配置来执行典型的任务。

Chapter 2. 安装和运行Maven

2.1. 验证你的Java安装

2.2. 下载Maven

2.3. 安装Maven

2.3.1. 在Mac OSX上安装Maven

2.3.2. 在Microsoft Windows上安装Maven

2.3.3. 在Linux上安装Maven

2.3.4. 在FreeBSD或OpenBSD上安装Maven

2.4. 验证Maven安装

2.5. Maven安装细节

2.5.1. 用户相关配置和仓库

2.5.2. 升级Maven

2.6. 获得Maven帮助

2.7. 使用Maven Help插件

2.7.1. 描述一个Maven插件

2.8. 关于Apache软件许可证

本章包含了在许多不同平台上安装Maven的详细指令。我们会介绍得尽可能详细以减少安装过程中可能出现的问题,而不去假设你已经熟悉安装软件和设置环境变量。本章的唯一前提是你已经安装了恰当的JDK。如果你仅仅对安装感兴趣,读完下载Maven 和安装Maven后,你就可以直接去看本书其它的部分。如果你对Maven安装的细节感兴趣,本章将会给你提供一个简要的介绍,以及Apache软件许可证,版本2.0的介绍。

2.1. 验证你的Java安装

尽管Maven可以运行在Java 1.4上,但本书假设你在至少Java 5上运行。尽管使用你操作系统上最新的稳定版本的JDK。本书的例子在Java 5或者Java 6上都能运行。

% java -version

java version "1.6.0_02"

Java(TM) SE Runtime Environment (build 1.6.0_02-b06)

Java HotSpot(TM) Client VM (build 1.6.0_02-b06, mixed mode, sharing)

Maven能在所有的验证过的Java TM兼容的JDK上工作,也包括一些未被验证JDK

实现。本书的所有样例是基于Sun官方的JDK编写和测试的。如果你正在使用Linux,你可能需要自己下载Sun的JDK,并且确定JDK的版本(运行java -version)。目前Sun已经将Java开源,因此这种情况将来有希望得到改进,将来很有可能Sun JRE和JDK会被默认安装在Linux上。但直到现在为止,你还是需要自己去下载。

2.2. 下载Maven

你可以从Apache Maven项目的web站点下载Maven:

241c40f5f705cc17552709d2/download.

当你下载Maven的时候,确认你选择了最新版本的Apache Maven。本书书写的时候最新版本是Maven 2.0.9 。如果你不熟悉Apache软件许可证,你需要在使用产品之前去熟悉该许可证的条款。更多的关于Apache软件许可证的信息可以Section 2.8, “关于Apache软件许可证”找到。

2.3. 安装Maven

操作系统之间有很大的区别,像Mac OSX 和微软的Windows,而且不同版本Windows之间也有微妙的差别。幸运的是,在所有操作系统上安装Maven的过程,相对来说还是比较直接的。下面的小节概括了在许多操作系统上安装Maven的最佳实践。

2.3.1. 在Mac OSX上安装Maven

你可以从241c40f5f705cc17552709d2/download下载Maven的二进制版本。下载最新的,下载格式最方便你使用的版本。找个地方存放它,并把存档文件解开。如果你把存档文件解压到 /usr/local/maven-2.0.9 ;你可能会需要创建一个符号链接,那样就能更容易使用,当你升级Maven的时候也不再需要改变环境变量。

/usr/local % ln -s maven-2.0.9 maven

/usr/local % export M2_HOME=/usr/local/maven

/usr/local % export PATH=${M2_HOME}/bin:${PATH}

将Maven安装好后,你还需要做一些事情以确保它正确工作。你需要将它的bin目录(该例中为/usr/local/maven/bin)添加到你的命令行路径下。你还需要设置

M2_HOME环境变量,其对应值为Maven的根目录(该例中为/usr/local/maven)。

Note

在OSX Tiger和OSX Leopard上安装指令是相同的。有报告称Maven 2.0.6正和XCode的预览版本一起发布。如果你安装了XCode,从命令行运行mvn检查一下它是否可用。 XCode把Maven安装在了/usr/share/maven。我们强烈建议安装最新版本的Maven 2.0.9,因为随着Maven 2.0.9的发布很多bug被修正了,还有很多改进。

你还需要把M2_HOME和PATH写到一个脚本里,每次登陆的时候运行这个脚本。把下面的几行加入到.bash_login。

export M2_HOME=/usr/local/maven

export PATH=${M2_HOME}/bin:${PATH}

一旦你把这几行加入到你的环境中,你就可以在命令行运行Maven了。

Note

这些安装指令假设你正运行bash。

2.3.2. 在Microsoft Windows上安装Maven

在Windows上安装Maven和在Mac OSX上安装Maven十分类似,最主要的区别在于安装位置和设置环境变量。在这里假设Maven安装目录是c:\Program

Files\maven-2.0.9,但是,只要你设置的正确的环境变量,把Maven安装到其它目录也一样。当你把Maven解压到安装目录后,你需要设置两个环境变量——PATH 和M2_M2_HOME。设置这两个环境变量,键入下面的命令:

C:\Users\tobrien > set M2_HOME=c:\Program Files\maven-2.0.9

C:\Users\tobrien > set PATH=%PATH%;%M2_HOME%\bin

在命令行设置环境变量后,你可以在当前会话使用Maven,但是,除非你通过控制面板把它们加入系统变量,你将需要每次登陆系统的时候运行这两行命令。你应该在Microsoft Windows中通过控制面板修改这两个变量。

2.3.3. 在Linux上安装Maven

遵循Section 2.3.1, “在Mac OSX上安装Maven”的步骤,在Linux机器上安装Maven。

2.3.4. 在FreeBSD或OpenBSD上安装Maven

遵循Section 2.3.1, “在Mac OSX上安装Maven”的步骤,在FreeBSD或者OpenBSD机器上安装Maven。T

2.4. 验证Maven安装

当Maven安装完成后,你可以检查一下它是否真得装好了,通过在命令行运行mvn -v。如果Maven装好了,你应该能看到类似于下面的输出。

$ mvn -v

Maven 2.0.9

如果你看到了这样的输出,那么Maven已经成功安装了。如果你看不到,而且你的操作系统找不到mvn命令,那么确认一下PATH和M2_HOME环境变量是否已经正确设置了。

2.5. Maven安装细节

Maven的下载文件只有大概1.5 MiB,它能达到如此苗条的大小是因为Maven的内核被设计成根据需要从远程仓库获取插件和依赖。当你开始使用Maven,它会开始下载插件到本地仓库中,就像Section 2.5.1, “用户相关配置和仓库”所描述的那样。对此你可能比较好奇,让我们先很快的看一下Maven的安装目录是什么样子。

/usr/local/maven $ ls -p1

LICENSE.txt

NOTICE.txt

README.txt

bin/

boot/

conf/

lib/

LICENSE.txt包含了Apache Maven的软件许可证。Section 2.8, “关于Apache 软件许可证”会详细描述该许可证。NOTICE.txt包含了一些Maven依赖的类库所需要的通告及权限。README.txt包含了一些安装指令。bin/目录包含了运行Maven的mvn脚本。boot/目录包含了一个负责创建Maven运行所需要的类装载器的JAR 文件(classwords-1.1.jar)。conf/目录包含了一个全局的settings.xml文件,该文件用来自定义你机器上Maven的一些行为。如果你需要自定义Maven,更通常的做法是覆写~/.m2目录下的settings.xml文件,每个用户都有对应的这个目录。lib/目录有了一个包含Maven核心的JAR文件(maven-2.0.9-uber.jar)。

2.5.1. 用户相关配置和仓库

当你不再仅仅满足于使用Maven,还想扩展它的时候,你会注意到Maven创建了一些本地的用户相关的文件,还有在你home目录的本地仓库。在~/.m2目录下有:

~/.m2/settings.xml

该文件包含了用户相关的认证,仓库和其它信息的配置,用来自定义Maven的行为。

~/.m2/repository/

该目录是你本地的仓库。当你从远程Maven仓库下载依赖的时候,Maven在

你本地仓库存储了这个依赖的一个副本。

Note

在Unix(和OSX)上,可以用 ~ 符号来表示你的home目录,(如~/bin表示

/home/tobrien/bin)。在Windows上,我们仍然使用 ~ 来表示你的home目录。在Windows XP上,你的home目录是C:\Documents and Settings\tobrien,在Windows Vista上,你的home目录是C:\Users\tobrien。从现在开始,你应该能够理解这种路径表示,并翻译成你操作系统上的对应路径。

2.5.2. 升级Maven

如果你遵循Section 2.3.1, “在Mac OSX上安装Maven”和Section 2.3.3, “在Linux上安装Maven”,在Mac OSX或者Unix机器上安装了Maven。那么把Maven 升级成较新的版本是很容易的事情。只要在当前版本Maven

(/usr/local/maven-2.0.9)旁边安装新版本的Maven

(/usr/local/maven-2.future),然后将符号链接/usr/local/maven从

/usr/local/maven-2.0.9改成/usr/local/maven-2.future即可。你已经将

M2_HOME环境变量指向了/usr/local/maven,因此你不需要更改任何环境变量。

如果你在Windows上安装了Maven,将Maven解压到c:\Program

Files\maven-2.future,然后更新你的M2_HOME环境变量。

2.6. 获得Maven帮助

虽然本书的目的是作为一本全面的参考手册,但是仍然会有一些主题我们会不小心遗漏,一些特殊情况和技巧我们也覆盖不到。Maven的核心十分简单,它所做的工作其实都交给插件了。插件太多了,以至于不可能在一本书上全部覆盖。你将会碰到一些本书没有涉及的问题,碰到这种情况,我们建议你在下面的地址去寻找答案。

241c40f5f705cc17552709d2

你首先应该看看这里,Maven的web站点包含了丰富的信息及文档。每个插

件都有几页的文档,这里还有一系列“快速开始”的文档,它们是本书内容的十分有帮助的补充。虽然Maven站点包含了大量信息,它同时也可能让你迷惑沮丧。

那里提供了一个自定义的Google搜索框,以用来搜索已有的Maven站点信息,它能比通用的Google搜索提供更好的结果。

Maven User Mailing List

Maven用户邮件列表是用户问问题的地方。在你问问题之前,你可以先搜索一下之前的讨论,有可能找到相关问题。问一个已经问过的问题,而不先查一下

该问题是否存在了,这种形式不太好。有很多有用的邮件列表归档浏览器,我

们发现Nabble最有用。你可以在这里浏览邮件列表:

241c40f5f705cc17552709d2/Maven---Users-f178。你也可以按照这里

的指令来加入用户邮件列表:241c40f5f705cc17552709d2/mail-lists。

241c40f5f705cc17552709d2

Sonatype维护了一个本书的在线副本,以及其它Maven相关的指南。Note

除去一些专门的Maven贡献者所做的十分优秀的工作,Maven web站点组织的比较糟糕,有很多不完整的,甚至有时候有些误导人的文档片段。在整个Maven社区里,插件文档的一般标准十分缺乏,一些插件的文档十分的丰富,但是另外一些连基本的使用命令都没有。通常你最好是在用户邮件列表里面去搜索下解决方案。

2.7. 使用Maven Help插件

本书中,我们将会介绍Maven插件,讲述Maven项目对象模型(POM)文件,settings 文件,还有profile。有些时候,你需要一个工具来帮助你理解一些Maven使用的模型,以及某个插件有什么可用的目标。Maven Help插件能让你列出活动的Maven Profile,显示一个实际POM(effective POM),打印实际settings(effective settings),或者列出Maven插件的属性。

Note

如果想看一下POM和插件的概念性介绍,参照第三章:一个简单的Maven项目。Maven Help 插件有四个目标。前三个目标是—— active-profiles,

effective-pom和effective-settings —— 描述一个特定的项目,它们必须在项目的目录下运行。最后一个目标—— describe ——相对比较复杂,展示某个插件或者插件目标的相关信息。

help:active-profiles

列出当前构建中活动的Profile(项目的,用户的,全局的)。

help:effective-pom

显示当前构建的实际POM,包含活动的Profile。

help:effective-settings

打印出项目的实际settings, 包括从全局的settings和用户级别settings继

承的配置。

help:describe

描述插件的属性。它不需要在项目目录下运行。但是你必须提供你想要描述插

件的 groupId 和 artifactId。

2.7.1. 描述一个Maven插件

一旦你开始使用Maven,你会花很多时间去试图获得Maven插件的信息:插件如何

工作?配置参数是什么?目标是什么?你会经常使用help:describe目标来获取这

些信息。通过plugin参数你可以指定你想要研究哪个插件,你可以传入插件的前缀(如help插件就是maven-help-plugin),或者可以是

groupId:artifact[:version],这里 version 是可选的。比如,下面的命令使用help 插件的describe目标来输出 Maven Help 插件的信息。

$ mvn help:describe -Dplugin=help

...

Group Id: org.apache.maven.plugins

Artifact Id: maven-help-plugin

Version: 2.0.1

Goal Prefix: help

Description:

The Maven Help plugin provides goals aimed at helping to make sense out of

the build environment. It includes the ability to view the effective

POM and settings files, after inheritance and active profiles

have been applied, as well as a describe a particular plugin goal to give usage information.

...

通过设置plugin参数来运行describe目标,输出为该插件的Maven坐标,目标

前缀,和该插件的一个简要介绍。尽管这些信息非常有帮助,你通常还是需要了解更多的详情。如果你想要 Help 插件输出完整的带有参数的目标列表,只要运行带有参数full的help:describe目标就可以了,像这样:

$ mvn help:describe -Dplugin=help -Dfull

...

Group Id: org.apache.maven.plugins

Artifact Id: maven-help-plugin

Version: 2.0.1

Goal Prefix: help

Description:

The Maven Help plugin provides goals aimed at helping to make sense out of

the build environment. It includes the ability to view the effective

POM and settings files, after inheritance and active profiles

have been applied, as well as a describe a particular plugin goal to give usage

information.

Mojos:

===============================================

Goal: 'active-profiles'

===============================================

Description:

Lists the profiles which are currently active for this build.

Implementation: org.apache.maven.plugins.help.ActiveProfilesMojo Language: java

Parameters:

-----------------------------------------------

[0] Name: output

Type: java.io.File

Required: false

Directly editable: true

Description:

This is an optional parameter for a file destination for the output of this mojo...the

listing of active profiles per project.

-----------------------------------------------

[1] Name: projects

Type: java.util.List

Required: true

Directly editable: false

Description:

This is the list of projects currently slated to be built by Maven.

-----------------------------------------------

This mojo doesn't have any component requirements.

===============================================

... removed the other goals ...

该选项能让你查看插件所有的目标及相关参数。但是有时候这些信息显得太多了。这时候你可以获取单个目标的信息,设置mojo参数和plugin参数。下面的命令列出了Compiler 插件的compile目标的所有信息

$ mvn help:describe -Dplugin=compiler -Dmojo=compile -Dfull

Note

什么? Mojo ?在Maven里面,一个插件目标也被认为是一个 “Mojo” 。

2.8. 关于Apache软件许可证

Apache Maven 是基于 Apache 许可证2.0版发布的。如果你想阅读该许可证,你可以查阅${M2_HOME}/LICENSE.txt或者从开源发起组织的网站上查阅

241c40f5f705cc17552709d2/licenses/apache2.0.php。

很有可能你正在阅读本书但你又不是律师。如果你想知道 Apache许可证2.0版意味着什么,Apache软件基金会收集了一个很有帮助的,关于许可证的常见问题解答(FAQ):241c40f5f705cc17552709d2/foundation/licence-FAQ。这里是对问题“我不是律师,所有这些是什么意思?”的回答。

它允许你:

?? 自由的下载和使用 Apache 软件,无论是软件的整体还是部分,也无论是出于个人目的,公司内部目的,还是商业目的。

?? 在你创建的类库或分发版本里使用 Apache 软件。

它禁止你:

?在没有正当的权限下重新分发任何源于 Apache 的软件或软件片段。

?以任何可能声明或暗示基金会认可你的分发版本的形式下使用 Apache 软件基金会拥有的标志。

?以任何可能声明或暗示你创建了 Apache 软件的形式下使用 Apache 软件基金会拥有的标志。

它要求你:

?在你重新分发的包含 Apache 软件的软件里,包含一份该许可证的副本。

?对于任何包含 Apache 软件的分发版本,提供给 Apache软件基金会清楚的权限。

它不要求你:

?在任何你再次发布的包含Apache软件的版本里,包含Apache软件本身源代码,或者你做的改动的源码。

?提交你对软件的改动至 Apache 软件基金会(虽然我们鼓励这种反馈)。

?Part I. Maven实战

?第一本关于Maven的书是来自O'Reilly的Maven开发者笔记,这本书通过一系列步骤介绍Maven。开发者笔记系列书籍背后的想法是,当开发人员和另一个开发人员坐在一起,经历他曾经用来学习和编码的整个思考过程,这样会学得最好。虽然开发者笔记系列成功了,但笔记格式有一个缺点:笔记被设计成“集中关注于目标”,它让你通过一系列步骤来完成某个特定的目标。而有大的参考书,或者“动物”书,提供全面的材料,覆盖了整个的课题。两种书都有优缺点,因此只出版一种书是有问题的。

?为了阐明这个问题,考虑如下情形,数万的读者读完开发者笔记后,他们都知道了如何创建一个简单的项目,比方说一个Maven项目从一组源文件创建一个WAR。但是,当他们想知道更多的细节或者类似于Assembly 插件的详细描述的时候,他们会陷入僵局。因为没有关于Maven的写得很好的参考手册,他们需要在Maven站点上搜寻插件文档,或者在一系列邮件列表中不停挑选。当人们真正开始钻研Maven的时候,他们开始在Maven站点上阅读无数的由很多不同的开发人员编写的粗糙的HTML 文档,这些开发人员对为插件编写文档有着完全不同的想法:数百的的开发人员有着不同的书写风格,语气以其方言。除去很多好心的志愿者所做的努力,在Maven站点上阅读插件文档,最好的情况下,令人有受挫感,最坏的情况下,成为了抛弃Maven的理由。很多情况下Maven用户感觉“被骗了”因为他们不能从站点文档上找到答案。

?虽然第一本Maven开发者笔记吸引了很多Maven的新用户,为很多人培训了最基本的Maven用例,但同样多的读者,当他们不能找到准确的写得很好的参考材料的时候,感觉到了挫败感。很多年来,缺少可靠的(或者权威的)参考资料阻碍了Maven的发展;这也成了一种Maven用户社区成长的阻碍力量。本书想要改变这种情况,通过提供,第一:在Part I, “Maven实战”中更新原本的Maven开发者笔记,第二:在Part II, “Maven Reference”中第一次尝试提供全面的参考。在你手里的(或者屏幕上的)实际上是二书合一。

?本书的这个部分中,我们不会抛弃开发者笔记中的描述性推进方式,这是帮助人们“以实战方式”学习Maven的很有价值的材料。在本书的第一部分中我们“边做边介绍”,然后在Part II, “Maven Reference”中我们填充空白,钻研细节,介绍那些Maven新手不感兴趣的高级话题。Part II, “Maven Reference”可能使用与样例项目无关的一个参考列表和一程序列表,而Part I, “Maven实战”将由实际样例和故事驱动。读完Part I, “Maven实战”

后,你将会拥有几个月内开始使用Maven所需要的一切。只有当你需要通过编写定制插件来开始自定义你的项目,或者想了解特定插件细节的时候,才可能需要回到Part II, “Maven Reference”。

Chapter 3. 一个简单的Maven项目

3.1. 简介

3.1.1. 下载本章的例子

3.2. 创建一个简单的项目

3.3. 构建一个简单的项目

3.4. 简单的项目对象模型(Project Object Model)

3.5. 核心概念

3.5.1. Maven插件和目标(Plugins and Goals)

3.5.2. Maven生命周期 (Lifecycle)

3.5.3. Maven坐标 (Coordinates)

3.5.

4. Maven仓库(Repositories)

3.5.5. Maven依赖管理 (Dependency Management)

3.5.6. 站点生成和报告(Site Generation and Reporting)

3.6. 小结

3.1. 简介

本章我们介绍一个用Maven Archetype插件从空白开始创建的简单项目。当你跟着这个简单项目的开发过程,你会看到这个简单的应用给我们提供了介绍Maven核心概念的机会。

在你能开始使用Maven做复杂的,多模块的构建之前,我们需要从基础开始。如果你之前用过Maven,你将会注意到这里很好的照顾到了细节。你的构建倾向于“只要能工作”,只有当你需要编写插件来自定义默认行为的时候,才需要深入Maven的细节。另一方面,当你需要深入Maven细节的时候,对Maven核心概念的彻底理解是至关重要的。本章致力于为你介绍一个尽可能简单的Maven项目,然后介绍一些使Maven成为一个可靠的构建平台的核心概念。读完本章后,你将会对构建生命周期 (build lifecycle),Maven仓库 (repositories),依赖管理(dependency management)和项目对象模型(Project Object Model)有一个基本的理解。

3.1.1. 下载本章的例子

本章开发了一个十分简单的例子,它将被用来探究Maven的核心概念。如果你跟着本章表述的步骤,你应该不需要下载这些例子来重新创建那些Maven已经生成好的代码。我们将会使用Maven Archetype插件来创建这个简单的项目,本章不会以任何方式修改这个项目。如果你更喜欢通过最终的例子源代码来阅读本章,本章的例子项目和这本书的例子代码可以从这里下载到:

241c40f5f705cc17552709d2/book/mvn-examples-1.0.zip或者

241c40f5f705cc17552709d2/book/mvn-examples-1.0.tar.gz。解压存档文件到任何目录下,然后到ch03/目录。在ch03/目录你将看到一个名字为simple/的目录,它包

含了本章的源代码。如果你希望在Web浏览器里看这些例子代码,访问

241c40f5f705cc17552709d2/book/examples-1.0并且点击ch03/目录。

3.2. 创建一个简单的项目

开始一个新的Maven项目,在命令行使用Maven Archetype插件。

$ mvn archetype:create -DgroupId=org.sonatype.mavenbook.ch03 \

-DartifactId=simple \

-DpackageName=org.sonatype.mavenbook

[INFO] Scanning for projects...

[INFO] Searching repository for plugin with prefix: 'archetype'. [INFO] artifact org.apache.maven.plugins:maven-archetype-plugin: checking for

\

updates from central

[INFO]

----------------------------------------------------------------------- [INFO] Building Maven Default Project

[INFO] task-segment: [archetype:create] (aggregator-style)

[INFO] -------------------------------------------------------------------- [INFO] [archetype:create]

[INFO] artifact org.apache.maven.archetypes:maven-archetype-quickstart: \

checking for updates from central

[INFO] Parameter: groupId, Value: org.sonatype.mavenbook.ch03

[INFO] Parameter: packageName, Value: org.sonatype.mavenbook

[INFO] Parameter: basedir, Value: /Users/tobrien/svnw/sonatype/examples [INFO] Parameter: package, Value: org.sonatype.mavenbook

[INFO] Parameter: version, Value: 1.0-SNAPSHOT

[INFO] Parameter: artifactId, Value: simple

[INFO] * End of debug info from resources from generated POM *

[INFO] Archetype created in dir: /Users/tobrien/svnw/sonatype/examples/simple mvn是Maven2的命令。archetype:create称为一个Maven目标 (goal)。如果

你熟悉Apache Ant,一个Maven目标类似于一个Ant目标 (target);它们都描述

了将会在构建中完成的工作单元(unit of work)。而像-Dname=value这样的对是

将会被传到目标中的参数,它们使用-D属性这样的形式[1],类似于你通过命令行

向Java虚拟机传递系统属性。archetype:create这个目标的目的通过archetype

快速创建一个项目。在这里,一个archetype被定义为“一个原始的模型或者类型,

在它之后其它类似的东西与之匹配;一个原型(prototype)”。Maven有许多可用的archetype,从生成一个简单的Swing应用,到一个复杂的Web应用。本章我们

用最基本的archetype来创建一个入门项目的骨架。这个插件的前缀是“archetype”,目标为”create”。[1]

我们已经生成了一个项目,看一下Maven在simple目录下创建的目录结构:simple/

simple/pom.xml

/src/

/src/main/

/main/java

/src/test/

/test/java

这个生成的目录遵循Maven标准目录布局,我们之后会去看更多的细节,但是,现在让我们只是尝试了解这些基本的目录。

Maven Archtype插件创建了一个与artifactId匹配的目录——simple。这是项目的基础目录。

每个项目在文件pom.xml里有它的项目对象模型 (POM)。这个文件描述了这个项目,配置了插件,声明了依赖。

我们项目的源码了资源文件被放在了src/main目录下面。在我们简单Java项目这样的情况下,这个目录包含了一下java类和一些配置文件。在其它的项目中,它可能是web应用的文档根目录,或者还放一些应用服务器的配置文件。在一个Java项目中,Java类放在src/main/java下面,而classpath资源文件放在src/main/resources下面。

我们项目的测试用例放在src/test下。在这个目录下面,src/test/java存放像使用JUnit或者TestNG 这样的Java测试类。目录src/test/resources下存放测试classpath资源文件。

Maven Archtype插件生成了一个简单的类org.sonatype.mavenbook.App,它是一个仅有13行代码的Java,所做的只是在main方法中输出一行消息:

package org.sonatype.mavenbook;

/**

* Hello world!

*

*/

public class App

{

public static void main( String[] args )

{

System.out.println( "Hello World!" );

}

}

最简单的Maven archetype生成最简单的Maven项目:一个往标准输出打印“Hello World”的程序。

3.3. 构建一个简单的项目

一旦你遵循Section 3.2, “创建一个简单的项目”使用Maven Archetype插件创建了一个项目,你会希望构建并打包这个应用。想要构建打包这个应用,在包含pom.xml的目录下运行mvn install。

$ mvn install

[INFO] Scanning for projects...

[INFO]

----------------------------------------------------------------------------

[INFO] Building simple

[INFO] task-segment: [install]

[INFO]

----------------------------------------------------------------------------

[INFO] [resources:resources]

[INFO] Using default encoding to copy filtered resources.

[INFO] [compiler:compile]

[INFO] Compiling 1 source file to /simple/target/classes

[INFO] [resources:testResources]

[INFO] Using default encoding to copy filtered resources.

[INFO] [compiler:testCompile]

[INFO] Compiling 1 source file to /simple/target/test-classes

[INFO] [surefire:test]

[INFO] Surefire report directory: /simple/target/surefire-reports

-------------------------------------------------------

T E S T S

-------------------------------------------------------

Running org.sonatype.mavenbook.AppTest

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.105 sec Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO] [jar:jar]

[INFO] Building jar: /simple/target/simple-1.0-SNAPSHOT.jar

[INFO] [install:install]

[INFO] Installing /simple/target/simple-1.0-SNAPSHOT.jar to \

~/.m2/repository/org/sonatype/mavenbook/ch03/simple/1.0-SNAPSHOT/ \

simple-1.0-SNAPSHOT.jar

本文来源:https://www.bwwdw.com/article/gcmq.html

Top