admin 管理员组文章数量: 1086019
阿帕奇 maven教程
阿帕奇 maven教程
Maven是Java™开发人员的出色构建工具,您也可以使用它来管理项目的生命周期。 作为生命周期管理工具,Maven跨阶段运行,而不是Ant风格的构建“任务”。 Maven处理项目生命周期的所有阶段,包括验证,代码生成,编译,测试,打包,集成测试,验证,安装,部署以及项目站点的创建和部署。
要了解Maven与传统构建工具之间的区别,请考虑构建JAR文件和EAR文件的过程。 使用Ant,您需要定义特定的任务来组装每个工件。 另一方面,Maven可以为您完成大部分工作:您只需告诉它项目是JAR还是EAR文件,然后指示它处理“打包”阶段即可。 Maven将找到所需的资源并构建文件。
您会发现许多入门指南,这些入门指南包括在本文的“ 相关主题”部分中列出的一些指南。 这里的五个技巧旨在帮助您了解接下来的内容:使用Maven管理应用程序生命周期时出现的编程方案。
1.可执行的JAR文件
关于本系列
所以您认为您了解Java编程吗? 事实是,大多数开发人员从头开始学习Java平台,仅学习足够的知识即可完成工作。 在这个正在进行的系列文章中,Java技术专家深入探讨了Java平台的核心功能,并提出了一些技巧和窍门,这些技巧和窍门甚至可以帮助您解决最棘手的编程挑战。
使用Maven构建JAR文件非常容易:只需将项目包装定义为“ jar”,然后执行包装生命周期阶段即可。 但是定义可执行的JAR文件更加棘手。 有效地执行此操作涉及以下步骤:
- 在您的JAR的MANIFEST.MF文件中定义一个
main
类,该main
类定义了可执行类。 (MANIFEST.MF是打包应用程序时Maven生成的文件。) - 查找项目依赖的所有库。
- 将那些库包括在MANIFEST.MF文件中,以便您的应用程序类可以找到它们。
您可以手动完成所有这些操作,也可以在两个Maven插件( maven-jar-plugin
和maven-dependency-plugin
的帮助下更有效地进行操作。
maven-jar-plugin
maven-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插件都通过<configuration>
元素公开其配置。 在此示例中, maven-jar-plugin
修改了其archive
属性,特别是存档的manifest
属性,该属性控制MANIFEST.MF文件的内容。 它包括三个元素:
-
addClassPath
:将此元素设置为true可以告诉maven-jar-plugin
将一个Class-Path
元素添加到MANIFEST.MF文件,并在该Class-Path
元素中包括所有依赖项 -
classpathPrefix
:如果计划将所有依赖项与要构建的JAR包含在同一目录中,则可以忽略此元素; 否则,请使用classpathPrefix
指定所有相关JAR文件的前缀。 在清单1中,classpathPrefix
指定所有依赖项应位于相对于归档文件的“lib
”文件夹中。 -
mainClass
:使用此元素定义当用户使用java -jar
命令执行JAR文件时要执行的类的名称。
Maven依赖插件
使用这三个元素配置MANIFEST.MF文件后,下一步是实际将所有依赖项复制到lib
文件夹。 为此,您使用了maven-dependency-plugin
,如清单2所示:
清单2.使用maven-dependency-plugin将依赖项复制到lib
<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
目录( project-home/target/lib
)下的lib
目录。
有了依赖关系并修改了MANIFEST.MF后,您可以使用简单的命令启动应用程序:
java -jar jarfilename.jar
2.自定义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-Class定义
Manifest-Version: 1.0
Premain-Class: com.geekcap.openapm.jvm.agent.Agent
Can-Redefine-Classes: true
Can-Retransform-Classes: true
Can-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的3
Maven 2已成为最受欢迎和使用最广泛的开源Java生命周期管理工具之一。 Maven 3于2010年9月晋升为alpha 5,为Maven带来了一些期待已久的变化。 请参阅“ 相关主题”部分,以了解Maven 3的新增功能。
这是一个有趣的示例,因为它都定义了一个Premain-Class
,它允许JAR文件作为Java代理工作,并且具有mainClass
,使它可以作为可执行JAR文件运行。 在这个特定示例中,我使用了OpenAPM
(我构建的代码跟踪工具)来定义将由Java代理和用户界面记录的代码跟踪,这将有助于对记录的跟踪进行分析。 简而言之,该示例显示了将显式清单文件与动态修改相结合的强大功能。
3.依赖树
Maven最有用的功能之一是它对依赖项管理的支持:您只需定义应用程序所依赖的库,然后Maven即可找到它们(在本地或中央存储库中),下载它们并使用它们来编译代码。 。
有时,您可能需要了解特定依赖项的来源-例如,如果要在构建中找到同一JAR文件的不同且不兼容的版本。 在这种情况下,您需要阻止将一个版本的JAR文件包含在您的构建中,但是首先您需要找到保存JAR的依赖项。
一旦您知道以下命令,查找依赖关系就变得异常容易:
mvn dependency:tree
dependency: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配置文件可让您执行所有这些操作,而不必分别为每个环境构建明确的说明。
关键在于将环境配置文件与面向任务的配置文件相结合。 每个环境概要文件都定义了其特定的位置,脚本和服务器。 因此,在我的pom.xml文件中,我将定义面向任务的构建,如清单6所示:
清单6.部署构建
<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>
此构建执行tomcat-deployer-plugin
,该tomcat-deployer-plugin
配置为连接到特定的主机,端口以及特定的用户名和密码凭据。 所有这些信息都是使用变量定义的,例如${deploymentmanagerRestHost}
。 这些变量是在每个配置文件中按环境定义的,如清单7所示:
清单7.环境配置文件
<profiles><profile><id>dev</id><properties><deploymentManagerRestHost>10.50.50.52</deploymentManagerRestHost><deploymentManagerRestPort>58090</deploymentManagerRestPort><deploymentManagerRestUsername>myusername</deploymentManagerRestUsername><deploymentManagerRestPassword>mypassword</deploymentManagerRestPassword></properties></profile><profile><id>qa</id><properties><deploymentManagerRestHost>10.50.50.50</deploymentManagerRestHost><deploymentManagerRestPort>58090</deploymentManagerRestPort><deploymentManagerRestUsername>myotherusername</deploymentManagerRestUsername><deploymentManagerRestPassword>myotherpassword</deploymentManagerRestPassword></properties></profile>
</profiles>
部署Maven配置文件
在清单7的概要文件中,我定义了两个概要文件,并根据概要文件名称中的值激活了它们。 如果选择的概要文件是dev
那么将使用开发部署信息。 如果选择的概要文件是qa
,那么将使用QA部署信息,依此类推。
这是部署到开发的命令:
mvn -Pdev clean install
–Pdev
标志告诉Maven激活开发配置,而传递-Pqa
将激活QA配置。
5.自定义Maven插件
Maven提供了数十种预建插件供您使用,但是在某些时候,您可能会发现自己需要自定义插件。 构建自定义Maven插件非常简单:
- 创建一个新项目,将POM包装设置为“
maven-plugin
。 - 包括对
maven-plugin-plugin
的调用,该调用定义了您公开的插件目标。 - 创建一个Maven插件“
mojo
”类(扩展AbstractMojo
的类)。 - 注释该类以定义将作为配置参数公开的目标和变量。 注释
@Mojo
是必需的,它控制执行mojo的方式和时间。 - 实现
execute()
方法,当您的插件被调用时将被调用。
作为示例,清单8显示了用于部署Tomcat的自定义插件的相关部分:
清单8. TomcatDeployerMojo.java
package net.fpic.maven.plugins;import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;/*** Goal that deploys a web application to Tomcat*/
@Mojo(name = "deploy", defaultPhase = LifecyclePhase.INSTALL)
public class TomcatDeployerMojo extends AbstractMojo {/*** The host name or IP address of the deployment server*/@Parameter(alias = "host", property = "deploy.host", required = true)private String serverHost;/*** The port of the deployment server*/@Parameter(alias = "port", property = "deploy.port", defaultValue = "58020", required = true)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", property = "deploy.username")private String username;/*** The password for the specified username*/@Parameter(alias = "password", property = "deploy.password")private String password;/*** The name of the source artifact to deploy, such as target/pos.war*/@Parameter(alias = "artifactSource", property = "deploy.artifactSource", required = true)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", property = "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 fieldsif (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");}...}
}
在类级别, @Mojo
批注值name
指定此MOJO执行的目标,而lifecyclePhase
指定目标执行的阶段。 除了映射到包含实际值的系统属性的表达式之外,每个公开的属性都有一个@Parameter
批注,该批注指定将通过其执行参数的别名。 如果属性设置了required=true
,那么它是必需的。 如果它具有defaultValue
,那么如果未指定该值,则将使用该值。 在execute()
方法中,可以调用getLog()
来访问Maven记录器,该记录器将根据记录级别将指定的消息输出到标准输出设备。 如果该插件失败,则抛出MojoExecutionException
将导致构建失败。
结论
您可以仅将Maven用于构建,但最好的Maven是项目生命周期管理工具。 本文介绍了五个鲜为人知的功能,这些功能可以帮助您更有效地使用Maven。 请参阅“ 相关主题”部分,以了解有关Maven的更多信息。
翻译自: .html
阿帕奇 maven教程
本文标签: 阿帕奇 maven教程
版权声明:本文标题:阿帕奇 maven教程 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/b/1693588842a230943.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论