访问原文:https://www.ibm.com/developerworks/cn/java/j-5things16/index.html
掌握现代 Maven 插件的技巧
Maven 是一个面向 Java™开发人员的领先的依赖管理和构建工具,而且名副其实!它通过阐述项目的构造来标准化软件构建流程,将它部署为应用程序,然后与其他项目共享它。
Maven 采用了一组可靠的插件来提供它的所有功能。在 Maven 中,插件拥有目标,在幕后,该目标就是 Java 方法。目标执行构建任务,比如编译项目,打包它,并将它部署到本地或远程服务器。这些活动可完美地映射到构建生命周期的各个阶段。
Maven 提供了自己的构建插件,这些插件已打包且可立即使用,而且预先配置了默认值。通过“约定高于配置”原则,可以确保能够针对给定任务的复杂性来扩展配置。大部分构建任务都只需极少的配置。
您还可以自定义 Maven 插件的行为。使用 Maven 的 <configuration>
元素,很容易重写插件默认值并定义新值。毫无疑问,大部分重写的默认值是 compiler 插件的 <source>
和<target>
值。
需要证据?您有多少次将清单 1 中的 XML 添加到 POM 中,以设置正确的 JVM 版本?
每个插件目标都映射到一个 Maven 生命周期阶段。发出 mvn compile
命令会告诉 mvn
实用程序调用绑定到 compile
生命周期阶段的所有目标。compiler
插件的 compile
目标被绑定到这个生命周期阶段。
阶段与目标之间是一对多的关系。多个插件目标可以绑定到同一个阶段,以形成相关任务集合。阶段也是分层的,这意味着执行一个阶段会导致执行它前面的所有阶段。
在本例中,发出 mvn compile
命令会启动 validate
阶段(Maven 的默认构建生命周期的第一个阶段),并调用绑定到该阶段的所有目标。
Maven 和 Google Code 网站维护着一个 Maven 插件列表。这些插件提供了各种各样有用且省时的功能,您可以将它们整合到构建流程中。我将介绍我发现的一些最有用的插件,并展示如何最充分地利用它们。
单击下面的按钮,下载本示例的代码。它包含一个简单的应用程序和一个包含已配置好的 Jarsigner
插件的 POM 文件。
对 JAR 或 WAR 执行数字签名是一项重要任务,尤其是在您想分发您的应用程序的时候。幸运的是,Java 平台提供了一个名为 jarsigner 的存档签名实用程序。它是一个命令行工具,可通过向它传递存档文件的位置和各种参数(比如包含您的加密密钥的密钥库)对存档文件执行签名。
可以在 JDK 安装的 <%JAVA_HOME%>/bin
目录中找到 jarsigner
。清单 2 展示了如何使用此实用程序对 JAR 执行签名。
jarsigner
是一个易于使用的命令行工具,而且开箱即用。 如果能自动化签名流程,在构建周期的 package
阶段对存档文件执行签名岂不是更好? 得益于包含 jarsigner
实用程序的 Maven Jarsigner 插件,您可以实现此目标。您只需要将该插件的 sign
目标绑定到您的构建周期的 package
阶段。
首先需要一个密钥库。如果没有,可以使用 Java 平台的 keytool 实用程序创建它,该实用程序可在 JDK 安装的<%JAVA_HOME%>/bin
目录中找到。
要创建一个密钥库,请导航到您想要放置它的位置并执行清单 3 中的命令。一定要将 KeyAlias
替换为合适的值,比如您的域名。官方 Oracle 文档详细介绍了该工具接受的更多配置选项。
创建密钥库的过程要求您回答一系列有关您自己和您的组织的问题,并提供一个安全密码。配置 Maven Jarsigner 插件时(接下来就会这么做)将需要此密码。
现在将 Maven Jarsigner 插件添加到您的构建生命周期中,然后配置它来对 package
阶段中生成的 JAR 执行数字签名。关联到此阶段是合理的,因为已构造 JAR 并将它存储在您项目的默认输出目录中,该目录通常是 target
目录。在 POM 文件的 <plugins>
部分,添加清单 4 中所示的代码。
您想要在构建 JAR 后对它执行签名,所以需要将签名过程(包装在 sign
目标中)连接到 package
生命周期阶段。为此,请将清单 5 中的代码添加到该插件中。
sign
目标需要一些配置细节才能对 JAR 执行数字签名。所以应该在 <configuration>
元素之间添加密钥库位置、您想要使用的凭证的别名、密钥库密码和凭证的密码,如清单 6 所示。
这是实现 JAR 签名特性所需的最低配置。请注意,该插件提供了大量额外的配置选项供选择。
最后一步是构建 JAR 并验证已对它正确执行签名。从命令行执行 package
目标,如下所示:mvn clean package
。在控制台输出中,会看到 JAR 正在构建,然后被签名。图 1 展示了您可能看到的结果
将 JAR 构建到 target
输出目录中,这是 Jarsigner 插件期望找到它的位置。该插件将使用您提供的凭证对 JAR 执行签名,然后向 META-INF
目录添加两个额外的文件:一个具有 .SF
扩展名的签名文件,以及一个具有 .RSA
扩展名的签名块文件。
现在已有一个经过数字签名的 JAR 可供分类。
在分类 JAR 之前,让我们验证已对它进行正确签名。可以使用 Maven Jarsigner 的 verify
目标,或者使用 jarsigner
工具通过命令行来实现此操作。在清单 7 中,我使用了命令行工具并向它传递我想要验证的存档文件。
如果成功,则会收到以下消息:jar verified
。
对 JAR 执行签名不是 Jarsigner 的唯一功能。该插件可对任何 Java 存档文件执行签名,包括 WAR 文件。要查看此操作是如何实现的,可以将 POM 的打包类型从 JAR 更改为 WAR,添加 Maven WAR 插件(如清单 8 所示)并执行命令:mvn clean package
。
检查 target
目录,您会找到已签名的 WAR 文件。
如果有多个存档文件要签名,Jarsigner 也能应对这种情况。清单 9 中的代码将 JAR 的签名位置指定为 target/all
,并且将对此目录中的所有 JAR 执行签名。
如果需要更精确地控制要签名的存档文件,可以使用通配符来显式包含和排除文件,如清单 10 所示。
单击下面的按钮,下载本示例的代码。它包含一个简单的 Web 应用程序和一个包含已配置好的 Cargo 插件的 POM 文件。
来自 Codehaus 的 Cargo 插件 是 Cargo API 的一个包装器。该 API 旨在配置、启动、停止应用程序并将它部署到各种受支持的容器中,并解析、创建和合并 Java EE 模块。
一个特别重要的特性是,Cargo 能够采用容器不可知的方式来指定服务器属性。这些属性包括端口、远程安全凭证、JVM 参数,以及(我们最感兴趣的)您想部署的应用程序的用户登录细节。该插件支持 14 种最流行的服务器的最新版本。
Cargo 插件最好关联到 Maven 生命周期的 package
阶段中。也可以直接引用 run
目标来独立执行它:mvn cargo:run
。独立执行会假设该项目已打包且准备好部署。
我们首先将 Cargo 的 run
目标关联到 package
阶段中,如清单 11 所示。
完成 Maven 集成后,现在需要对您希望 Cargo 部署应用程序的目标容器进行配置。Cargo 支持各种各样的容器场景,包括部署到已在运行的本地或远程服务器(这包括在需要时启动该服务器)。或者,可以配置 Cargo 来下载、安装、部署并启动它支持的 14 种服务器中的任意一种。
对于本示例,我将使用 IBM® WebSphere® Liberty,我已下载它并解压到一个名为 servers
的目录中。
容器配置至少需要容器 ID 和所安装服务器的主目录位置。清单 12 给出了位于我的 servers/wlp
目录中的 Liberty 服务器的配置。
另一个选项是指定 IBM 网站上的 Liberty ZIP 文件的 URL,在这种情况下,Cargo 插件会下载并安装该服务器。清单 13 显示了执行此操作的代码。
第一次执行 run
目标时,会下载和解压 ZIP 文件。在后续执行时,Maven 会检测到该文件已下载和安装,并跳过该任务。
您现在拥有最少的配置,可以将该应用程序部署到您的服务器中来测试该配置。通过调用 package
阶段 (mvn package
) 来启动该流程。将应用程序编译、打包并部署到服务器中,而且可通过以下 URL 访问它:http://localhost:8080/{artifactid}/index.html
。
默认情况下,使用 artifactid
来命名 Web 应用程序的上下文根目录。在某些情况下,您需要指定一个自定义上下文根目录。在清单 14 中,我将上下文根目录定义为 home
。
部署应用程序后,可通过以下地址访问该 Web 应用程序: localhost:8080/home/index.html
。
您现在已有一个非常可靠的部署流程,它会下载并安装一个服务器,将您的应用程序部署到一个自定义上下文根目录中。对于 Cargo 插件的功能而言,这才刚刚开始。
在我们开始定义配置属性时,Cargo 才真正发挥出它的实力。正如我之前提到的,这些配置属性是容器的属性,比如端口、协议,最重要的是用户登录细节。
让我们向示例应用程序添加一个用户,并强制登录到该站点。为了保持简单,我们将使用基本身份验证方法,只需要应用程序的 web.xml
文件中的极少配置。清单 15 显示了 user-role
的规范和对 WelcomeServlet
Web 资源的限制。