2019独角兽企业重金招聘Python工程师标准>>> hot3.png

转自:http://www.ibm.com/developerworks/cn/java/j-5things13/

Maven 是为 Java™ 开发人员提供的一个极为优秀的构建工具,您也可以使用它来管理您的项目生命周期。作为一个生命周期管理工具,Maven 是基于阶段操作的,而不像 Ant 是基于 “任务” 构建的。Maven 完成项目生命周期的所有阶段,包括验证、代码生成、编译、测试、打包、集成测试、安装、部署、以及项目网站创建和部署。为了更好地理解 Maven 和传统构建工具的不同,我们来看看构建一个 JAR 文件和一个 EAR 文件的过程。使用 Ant,您可能需要定义专有任务来组装每个工件。另一方面,Maven 可以为您完成大部分工作:您只需要告诉它是一个 JAR 文件还是一个 EAR 文件,然后指示它来完成 “打包” 过程。Maven 将会找到所需的资源,然后构建文件。在本文的 参考资料 部分,您将发现大量介绍 Maven 的入门教程。本文的 5 个技巧目的是帮助您解决即将出现的一些问题:使用 Maven 管理您的应用程序的生命周期时,将会出现的编程场景。

1. 可执行的 JAR 文件使用 Maven 构建一个 JAR 文件比较容易:只要定义项目包装为 “jar”,然后执行包装生命周期阶段即可。但是定义一个可执行 JAR 文件却比较麻烦。采取以下步骤可以更高效:在您定义可执行类的 JAR 的 MANIFEST.MF 文件中定义一个 main 类。(MANIFEST.MF 是包装您的应用程序时 Maven 生成的。)找到您项目依赖的所有库。在您的 MANIFEST.MF 文件中包含那些库,便于您的应用程序找到它们。您可以手工进行这些操作,或者要想更高效,您可以使用两个 Maven 插件帮助您完成:maven-jar-plugin 和 maven-dependency-plugin。

maven-jar-pluginmaven-jar-plugin 可以做很多事情,但在这里,我们只对使用它来修改默认 MANIFEST.MF 文件的内容感兴趣。在您的 POM 文件的插件部分添加清单 1 所示代码:清单 1. 使用 maven-jar-plugin 修改 MANIFEST.MF

<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><configuration><archive><manifest><addClasspath>true</addClasspath><classpathPrefix>lib/</classpathPrefix><mainClass>com.mypackage.MyClass</mainClass></manifest></archive></configuration></plugin>

所有 Maven 插件通过一个 元素公布了其配置,在本例中,maven-jar-plugin 修改它的 archive 属性,特别是存档文件的 manifest 属性,它控制 MANIFEST.MF 文件的内容。包括 3 个元素:addClassPath:将该元素设置为 true 告知 maven-jar-plugin 添加一个 Class-Path 元素到 MANIFEST.MF 文件,以及在 Class-Path 元素中包括所有依赖项。classpathPrefix:如果您计划在同一目录下包含有您的所有依赖项,作为您将构建的 JAR,那么您可以忽略它;否则使用 classpathPrefix 来指定所有依赖 JAR 文件的前缀。在清单 1 中,classpathPrefix 指出,相对存档文件,所有的依赖项应该位于 “lib” 文件夹。mainClass:当用户使用 lib 命令执行 JAR 文件时,使用该元素定义将要执行的类名。

maven-dependency-plugin当您使用这 3 个元素配置好了 MANIFEST.MF 文件之后,下一步是将所有的依赖项复制到 lib 文件夹。为此,使用 maven-dependency-plugin,如清单 2 所示:清单 2. 使用 maven-dependency-plugin 将依赖项复制到库

<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-dependency-plugin</artifactId><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>

maven-dependency-plugin 有一个 copy-dependencies,目标是将您的依赖项复制到您所选择的目录。本例中,我将依赖项复制到 build 目录下的 lib 目录(project-home/target/lib)。将您的依赖项和修改的 MANIFEST.MF 放在适当的位置后,您就可以用一个简单的命令启动应用程序:java -jar jarfilename.jar2. 定制 MANIFEST.MF虽然 maven-jar-plugin 允许您修改 MANIFEST.MF 文件的共有部分,但有时候您需要一个更个性化的 MANIFEST.MF。解决方案是双重的:在一个 “模板” MANIFEST.MF 文件中定义您的所有定制配置。配置 maven-jar-plugin 来使用您的 MANIFEST.MF 文件,然后使用一些 Maven 配置增强。例如,考虑一个包含 Java 代理的 JAR 文件。要运行一个 Java 代理,需要定义 Premain-Class 和设置许可。清单 3 展示了这样一个 MANIFEST.MF 文件的内容:清单 3. 在一个定制的 MANIFEST.MF 文件中定义 Premain-ClassManifest-Version: 1.0Premain-Class: com.geekcap.openapm.jvm.agent.AgentCan-Redefine-Classes: trueCan-Retransform-Classes: trueCan-Set-Native-Method-Prefix: true在 清单 3 中,我已指定 Premain-Class - com.geekcap.openapm.jvm.agent.Agent 被授权许可来对类进行重定义和再转换。接下来,我更新 maven-jar-plugin 代码来包含 MANIFEST.MF 文件。如清单 4 所示:清单 4. 包含 Premain-Class

<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><configuration><archive><manifestFile>src/main/resources/META-INF/MANIFEST.MF</manifestFile><manifest><addClasspath>true</addClasspath><classpathPrefix>lib/</classpathPrefix><mainClass>com.geekcap.openapm.ui.PerformanceAnalyzer</mainClass></manifest></archive></configuration></plugin>

Maven 3Maven 2 已确立了它作为一种最流行和最易使用的开源 Java 生命周期管理工具的地位。Maven 3,2010 年 9 月升级为 alpha 5,带来一些期待已久的改进。在 参考资料 部分寻找 Maven 的新功能。这是一个很有趣的示例,因为它既定义了一个 Premain-Class — 允许 JAR 文件作为一个 Java 代理运行,也有一个 mainClass — 允许它作为一个可执行的 JAR 文件运行。在这个特殊的例子中,我使用 OpenAPM(我已构建的一个代码跟踪工具)来定义将被 Java 代理和一个用户界面记录的代码跟踪。简而言之,这个示例展示一个显式清单文件与动态修改相结合的力量。回页首

3. 依赖项树Maven 一个最有用的功能是它支持依赖项管理:您只需要定义您应用程序依赖的库,Maven 找到它们、下载它们、然后使用它们编译您的代码。必要时,您需要知道具体依赖项的来源 — 这样您就可以找到同一个 JAR 文件的不同版本的区别和矛盾。这种情况下,您将需要防止将一个版本的 JAR 文件包含在您的构建中,但是首先您需要定位保存 JAR 的依赖项。一旦您知道下列命令,那么定位依赖项往往是相当容易的:mvn dependency:treedependency:tree 参数显示您的所有直接依赖项,然后显示所有子依赖项(以及它们的子依赖项,等等)。例如,清单 5 节选自我的一个依赖项所需要的客户端库:清单 5. Maven 依赖项树[INFO] ------------------------------------------------------------------------[INFO] Building Client library for communicating with the LDE[INFO]    task-segment: [dependency:tree][INFO] ------------------------------------------------------------------------[INFO] [dependency:tree {execution: default-cli}][INFO] com.lmt.pos:sis-client:jar:2.1.14[INFO] +- org.codehaus.woodstox:woodstox-core-lgpl:jar:4.0.7:compile[INFO] |  \- org.codehaus.woodstox:stax2-api:jar:3.0.1:compile[INFO] +- org.easymock:easymockclassextension:jar:2.5.2:test[INFO] |  +- cglib:cglib-nodep:jar:2.2:test[INFO] |  \- org.objenesis:objenesis:jar:1.2:test在 清单 5 中您可以看到 sis-client 项目需要 woodstox-core-lgpl 和 easymockclassextension 库。easymockclassextension 库反过来需要 cglib-nodep 库和 objenesis 库。如果我的 objenesis 出了问题,比如出现两个版本,1.2 和 1.3,那么这个依赖项树可能会向我显示,1.2 工件是直接由 easymockclassextension 库导入的。dependency:tree 参数为我节省了很多调试时间,我希望对您也同样有帮助。4. 使用配置文件多数重大项目至少有一个核心环境,由开发相关的任务、质量保证(QA)、集成和生产组成。管理所有这些环境的挑战是配置您的构建,这必须连接到正确的数据库中,执行正确的脚本集、并为每个环境部署正确的工件。使用 Maven 配置文件让您完成这些任务,而无需为每个环境分别建立明确指令。关键在于环境配置文件和面向任务的配置文件的合并。每个环境配置文件定义其特定的位置、脚本和服务器。因此,在我的 pox.xml 文件中,我将定义面向任务的配置文件 “deploywar”,如清单 6 所示:清单 6. 部署配置文件

<profiles><profile><id>deploywar</id><build><plugins><plugin><groupId>net.fpic</groupId><artifactId>tomcat-deployer-plugin</artifactId><version>1.0-SNAPSHOT</version><executions><execution><id>pos</id><phase>install</phase><goals><goal>deploy</goal></goals><configuration><host>${deploymentManagerRestHost}</host><port>${deploymentManagerRestPort}</port><username>${deploymentManagerRestUsername}</username><password>${deploymentManagerRestPassword}</password><artifactSource>address/target/addressservice.war</artifactSource></configuration></execution></executions></plugin></plugins></build></profile></profiles>

这个配置文件(通过 ID “deploywar” 区别)执行 tomcat-deployer-plugin,被配置来连接一个特定主机和端口,以及指定用户名和密码证书。所有这些信息使用变量来定义,比如 ${deploymentmanagerRestHost}。这些变量在我的 profiles.xml 文件中定义,如清单 7 所示:清单 7. profiles.xml

<!-- Defines the development deployment information --><profile><id>dev</id><activation><property><name>env</name><value>dev</value></property></activation><properties><deploymentManagerRestHost>10.50.50.52</deploymentManagerRestHost><deploymentManagerRestPort>58090</deploymentManagerRestPort><deploymentManagerRestUsername>myusername</deploymentManagerRestUsername><deploymentManagerRestPassword>mypassword</deploymentManagerRestPassword></properties></profile><!-- Defines the QA deployment information --><profile><id>qa</id><activation><property><name>env</name><value>qa</value></property></activation><properties><deploymentManagerRestHost>10.50.50.50</deploymentManagerRestHost><deploymentManagerRestPort>58090</deploymentManagerRestPort><deploymentManagerRestUsername>myotherusername</deploymentManagerRestUsername><deploymentManagerRestPassword>myotherpassword</deploymentManagerRestPassword></properties></profile>

部署 Maven 配置文件在 清单 7 的 profiles.xml 文件中,我定义了两个配置文件,并根据 env (环境)属性的值激活它们。如果 env 属性被设置为 dev,则使用开发部署信息。如果 env 属性被设置为 qa,那么将使用 QA 部署信息,等等。这是部署文件的命令:mvn -Pdeploywar -Denv=dev clean install-Pdeploywar 标记通知要明确包含 deploywar 配置文件。-Denv=dev 语句创建一个名为 env 的系统属性,并将其值设为 dev,这激活了开发配置。传递 -Denv=qa 将激活 QA 配置。5. 定制 Maven 插件Maven 有十几个预构建插件供您使用,但是有时候您只想找到自己需要的插件,构建一个定制的 Maven 插件比较容易:用 POM packaging 创建一个新项目,设置为 “maven-plugin”。包括一个 maven-plugin-plugin 调用,可以定义您的公布插件目标。创建一个 Maven 插件 “mojo” 类 (一个扩展 AbstractMojo 的类)。为类的 Javadoc 做注释来定义目标,并为每个将被作为配置参数公布的变量做注解。实现一个 execute() 方法,该方法在调用您的插件是将被调用。例如,清单 8 显示了一个定制插件(为了部署 Tomcat)的相关部分:清单 8. TomcatDeployerMojo.java

package net.fpic.maven.plugins; import java.io.File;
import java.util.StringTokenizer; import net.fpic.tomcatservice64.TomcatDeploymentServerClient; import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException; import com.javasrc.server.embedded.CommandRequest;
import com.javasrc.server.embedded.CommandResponse;
import com.javasrc.server.embedded.credentials.Credentials;
import com.javasrc.server.embedded.credentials.UsernamePasswordCredentials;
import com.javasrc.util.FileUtils; /**
* Goal that deploys a web application to Tomcat
*
* @goal deploy
* @phase install
*/
public class TomcatDeployerMojo extends AbstractMojo
{
/**
* The host name or IP address of the deployment server
*
* @parameter alias="host" expression="${deploy.host}" @required
*/
private String serverHost; /**
* The port of the deployment server
*
* @parameter alias="port" expression="${deploy.port}" default-value="58020"
*/
private String serverPort; /**
* The username to connect to the deployment manager (if omitted then the plugin
* attempts to deploy the application to the server without credentials)
*
* @parameter alias="username" expression="${deploy.username}"
*/
private String username; /**
* The password for the specified username
*
* @parameter alias="password" expression="${deploy.password}"
*/
private String password; /**
* The name of the source artifact to deploy, such as target/pos.war
*
* @parameter alias="artifactSource" expression=${deploy.artifactSource}"
* @required
*/
private String artifactSource; /**
* The destination name of the artifact to deploy, such as ROOT.war.
* If not present then the
* artifact source name is used (without pathing information)
*
* @parameter alias="artifactDestination"
*   expression=${deploy.artifactDestination}"
*/
private String artifactDestination; public void execute() throws MojoExecutionException { getLog().info( "Server Host: " + serverHost + ", Server Port: " + serverPort + ", Artifact Source: " + artifactSource + ", Artifact Destination: " + artifactDestination ); // Validate our fields if( serverHost == null ) { throw new MojoExecutionException( "No deployment host specified, deployment is not possible" ); } if( artifactSource == null ) { throw new MojoExecutionException( "No source artifact is specified, deployment is not possible" ); } ... }
}

在这个类的头部,@goal 注释指定 MOJO 执行的目标,而 @phase 指出目标执行的阶段。除了一个映射到一个有真实值的系统属性的表达式之外,每个公布的属性有一个 @phase 注释,通过将被执行的参数指定别名。如果属性有一个 @required 注释,那么它是必须的。如果它有一个 default-value,那么如果没有指定的话,将使用这个值。在 execute() 方法中,您可以调用 getLog() 来访问 Maven 记录器,根据记录级别,它将输出具体消息到标准输出设备。如果插件发生故障,抛出一个 MojoExecutionException 将导致构建失败。结束语您可以使用 Maven 只进行构建,但是最好的 Maven 是一个项目生命周期管理工具。本文介绍了 5 个大家很少了解的特性,可以帮助您更高效地使用 Maven。在 参考资料 部分获取 Maven 的更多信息。

转载于:https://my.oschina.net/flynewton/blog/12804

关于 Apache Maven 您不知道的 5 件事相关推荐

  1. 关于多线程编程您不知道的 5 件事 有关高性能线程处理的微妙之处

    虽然很少有 Java™ 开发人员能够忽视多线程编程和支持它的 Java 平台库,更少有人有时间深入研究线程.相反地,我们临时学习线程,在需要时向我们的工具箱添加新的技巧和技术.以这种方式构建和运行适当 ...

  2. 关于ERP系统,你可能不知道的10件事

    谈到ERP系统,大多数人只是考虑ERP日常管理的核心功能,即财务.销售.采购.库存.生产和分销.保持对这些关键领域的控制对任何企业的成功都是不可或缺的.但这些只是冰山一角,如果深入挖掘ERP系统,你可 ...

  3. 佳能eosr控制环能否计算机控制,关于全画幅微单相机 你可能不知道的十件事

    01关于微单相机你不知道的十件事 2018年之前,全画幅微单领域没有竞争,索尼一家独大,徕卡只走奢侈路线.为了满足专业摄影师和资深发烧玩家更多的使用需求,佳能.尼康和松下纷纷加入战局,在2018年开启 ...

  4. 阴阳师服务器维护结界卡暂停吗,阴阳师BUFF暂停功能你不能不知道的六件事

    阴阳师BUFF暂停功能已经正式上线啦,哪些种类的加成可以暂停?在哪里找暂停按钮?暂停有时间限制吗?有次数限制吗?关于BUFF暂停你不能不知道的六件事! 一.在哪里暂停? 在庭院处点击头像右边的&quo ...

  5. 71java并发编程不得不知道的几件事

    多线程编程从来都是一件比较困难的事情,调试多线程程序也相当困难,这种困难来自于线程对共享资源操作的复杂性 ( 包括对于资源操作的线程间的先后顺序 ) .对于 Java 来说,它封装了底层硬件和操作系统 ...

  6. 我的世界java版移除猪灵了吗_我的世界:猪灵拥有三种类型?关于猪灵,你可能不知道的7件事...

    猪灵是1.16下界更新第二个快照版本20w07a加入的下界新生物,虽然上线时间已经有两个月之久,但对于大部分国内玩家来说却还是一个陌生的存在.为了让玩家更加的了解猪灵,迷恋整理了7件,你可能不知道的关 ...

  7. 关于PHP你可能不知道的10件事

    小编之前也曾报导过PHP开发人员容易忽略的几点精华,除了一些精华技术方法外,很多细微之处也是程序员们容易忽略的,下面我们为您总结了10个关于PHP你可能不知道的事情. 关于PHP更多内容,欢迎访问:P ...

  8. 关于中国央行法定数字货币,你可能不知道的7件事

    法定数字货币并不是加密的,将把金融权力还给中国的商业银行. 据福布斯8月27日报道,知情人士称,中国央行预计在11月11日推出由国家支持的数字货币,并面向包括腾讯.阿里巴巴在内的七家机构发行,此前担任 ...

  9. 500强校园招聘中大学生不知道的10件事

    最近改编成电影的<杜拉拉升职记>,应该很多人都第一时间去捧了场.动动手指数数,加上之前翻拍的<丑女无敌>.美国版的<丑女贝蒂>.揭露时尚圈工作狂本质的电影<穿 ...

最新文章

  1. QIIME 2教程. 01简介和安装 Introduction Install(2020.11开始更新)
  2. ctf(pwn) canary保护机制讲解 与 解密方法介绍
  3. 下拉列表项过多会导致浏览器卡死
  4. P2P穿透四种NAT类型
  5. mongodb创建集合与php扩展
  6. Spring 3.x 企业应用开发实战(含CD光盘1张)
  7. selenium webdriver学习(一)------------快速开始(转载JARVI)
  8. python文件写入_python读写不同编码txt文件
  9. 7.JavaScript变量
  10. linux 前端开发软件下载,Prepros Linux版下载
  11. 数字图像处理——LoG算子
  12. MP3编码之shine压缩异常解决
  13. 单目slam LoopClosing之Sim3优化
  14. IOS 出现不支持的 URL
  15. 心疼果粉,10V、4A,荣耀Magic2超级快充充电头正式曝光厉害了
  16. java 账本 创建数据库_想用你所学的JAVA与数据库写一个属于自己的账本吗?一起来看看呗!看如何用java项目操作数据库...
  17. 4k纸是几厘米乘几厘米_4k纸多大,纸张的大小规格
  18. python画气泡图(4个象限)
  19. 学生博客,教师博客地址,有用博客地址
  20. 互评成绩 python

热门文章

  1. 2018-行远自迩,登高自卑
  2. PJzhang:互联网是有国界
  3. 【笔试题】京东2017秋招笔试真题
  4. pycharm acejumpchar插件
  5. Codeforces Round #374 (Div. 2) A. One-dimensional Japanese Crosswor 水题
  6. 穷举 百文百鸡
  7. jquery常用选择器
  8. windows mobile+webservice+mysql
  9. wp7 通过后台代码给ListBoxItem添加ContextMenu 属性
  10. 关于Sybase ASE数据库的license以及试用版过期的问题的解决方案