Maven系列

Maven 安装与配置

1. Maven 介绍

Maven 翻译为 “专家”,“内行”。Maven 是 Apache 下的一个纯 Java 开发的开源项目,它是一个项目管理工具,使用 Maven 对 Java 项目进行构建、依赖管理。

1.1 什么是项目构建

项目构建是一个项目从编写源代码到编译、测试、运行、打包、部署、运行的过程。

Maven 将项目构建的过程进行标准化,每个阶段使用一个命令完成,下图展示了构建过程的一些阶段,后面章节详细介绍每个阶段,这里先大概了解下:

图1.1.1 Maven项目构建过程

上图中部分阶段对应命令如下:

  1. 清理阶段对应 Maven 的命令是 clean,清理输出的 class 文件
  2. 编译阶段对应 Maven 的命令是 compile,将 Java 代码编译成 class 文件。
  3. 打包阶段对应 Maven 的命令是 package,Java 工程可以打成 jar 包,web 包可以打成 war 包

运行一个 Maven 工程(web工程)需要一个命令:tomat:run

Maven 工程构建的优点:

  1. 一个命令完成构建、运行,方便快捷。
  2. Maven 对每个构建阶段进行规范,非常有利于大型团队协作开发。

1.2 什么是依赖管理

Maven 项目管理所依赖的 jar 包不需要手动向工程添加 jar 包,只需要在 pom.xml(Maven 工程的配置文件)添加 jar 包的坐标,自动从 Maven 仓库中下载 jar 包、运行,如下图:

图1.1.2 Maven依赖管理

使用 maven 依赖管理添加 jar 的好处:

  1. 通过 pom.xml 文件对 jar 包的版本进行统一管理,可避免版本冲突。
  2. Maven 团队维护了一个非常全的 Maven 仓库,里边包括了当前使用的 jar 包,Maven 工程可以自动从 Maven 仓库下载 jar 包,非常方便。

1.3 使用 Maven 的好处

通过上边介绍传统项目和 Maven 项目在项目构建及依赖管理方面的区域,Maven 有如下的好处:

  1. 一步构建。Maven 对项目构建的过程进行标准化,通过一个命令即可完成构建过程。
  2. 依赖管理。Maven 工程不用手动导 jar 包,通过在 pom.xml 中定义坐标从 Maven 仓库自动下载,方便且不易出错。
  3. Maven 的跨平台,可在 window、linux 上使用。
  4. Maven 遵循规范开发有利于提高大型团队的开发效率,降低项目的维护成本,大公司都会考虑使用 Maven 来构建项目。

2. Maven 的安装与配置

Maven 是基于 Java 开发的,无论是 Windows 上还是 Linux 上直接解压即可,前提是已经安装有 JDK。安装完成后需要配置环境变量:

JAVA_HOME:D:\Program Files\Java\jdk1.8.0_91
MAVEN_HOME:D:\Maven\apache-maven-3.5.0

3. Maven 目录结构介绍

3.1 MAVEN_HOME

bin
boot
conf
lib
LICENSE
NOTICE
README.txt
  • bin 该目录包含了 mvn 运行的脚本,这些脚本用来配置 Java 命令,准备好 classpath 和相关的 Java 系统属性,然后执行 Java 命令。其中 mvn 是基于 UNIX 平台的 shel 脚本,mvn.bat 是基于 Windows 平台的 bat 脚本。在命令行输人任何一条 mvn 命令时,实际上就是在调用这些脚本。该目录还包含了 mvnDebug 和 mvnDebug.bat 两个文件,同样,前者是 UNIX 平台的 shell 脚本,后者是 Windows 平台的 bat 脚本。那么 mvn 和 mvnDebug 有什么区别呢?打开文件我们可以看到,两者基本上是一样的,只是 mvnDebug 多了一条 MAVEN_DEBUG_OPTS 配置,其作用就是在运行 Maven 时开启 debug,以便调试 Maven 本身。此外,该目录还包含 m2.conf 文件,这是 clssworlds 的配置文件,后面会介绍 classworlds。

  • boot 该目录只包含一个文件,以 maven3.5.0 为例,该文件为 plexus-classworlds-2.5.2.jar。plexus-classworlds 是一个类加载器框架,相对于默认的 java 类加载器,它提供了更丰富的语法以方便配置, Maven 使用该框架加载自己的类库。对于一般的 Maven 用户来说,不必关心该文件。

  • conf 该目录包含了一个非常重要的文件 settings.xml。直接修改该文件,就能在机器上全局地定制 Maven 的行为。一般情况下,我们更偏向于复制该文件至 ~/.m2/ 目录下(~表示用户目录),然后修改该文件,在用户范围定制 Maven 的行为。后面将会多次提到 settings.xml,并逐步分析其中的各个元素。

  • lib 该目录包含了所有 Maven 运行时需要的 Java 类库,Maven 本身是分模块开发的,因此用户能看到诸如 maven-core-3.5.0.jar、 maven-model-3.5.0.jar 之类的文件。此外,这里还包含一些 Maven 用用到的第三方依赖,如 commons-cli-1.4.jar。可以说,lib 目录就是真正的 Maven。关于该文件,还有一点值得一提的是,用户可以在这个目录中找到 Maven 内置的超级 POM,这一点在 8.5 节详细解释。

  • 其他: LICENSE.txt 记录了 Maven 使用的软件许可证 Apache License Version2.0;NOTICE.txt 记录了 Maven 包含的第三方软件;而 READMIE.txt 则包含了 Maven 的简要介绍,包括安装需求及如何安装的简要指令等。

3.2 ~/.m2

在讲述该小节之前,我们先运行一条简单的命令: mvn help: system。该命令会打印出所有的 Java 系统属性和环境变量,这些信息对我们日常的编程工作很有帮助。这里暂不解释 help:system 涉及的语法,运行这条命令的目的是让 Maven 执行一个真正的任务。我们可以从命令行输出看到 Maven 会下载 maven-help-plugin,包括 pom 文件和 jar 文件。这些文件都被下载到了 Maven 本地仓库中。

默认情况下,.m2 文件夹下放置了 Maven 本地仓库 .m2/repository。所有的 Maven 构件都被存储到该仓库中,以方便重用。可以到 ~/.m2/repository/org/apache/maven/plugins/maven-help-plugins 目录找到刚才下载的 maven-help-plugins 的 pom 文件和 jar 文件。 Maven 根据一套规则来确定任何一个构件在仓库中的位置,这一点在第 6 章交付详细阐述。

默认情况下,~/.m2 目录下除了 repository 仓库之外就没有其他目录和文件了,不过大多数 Maven 用户需要复制 MAVEN_HOME/conf/settings.xml 文件到 ~/.m2/settings.xml。这是条最佳实践,我们将在 3 小节详细解释。

4. 设置 HTTP 代理

有时候你所在的公司基于安全因素考虑,要求你使用通过安全认证的代理访问因特网。这种情况下,就需要为 Maven 配配置 HTTP 代理,才能让它正常访问外部仓库,以下载所需要的资源。首先确认自己无法直接访问公共的的 Maven 中央仓库,直接运行命令 ping repo.maven.org 可以检查网络。如果真的需要代理,先检査一下代理服务器是否畅通。比如现在有一个 IP 地址为 218.14.227.197,端口为 3128 的代理服务,我们可以运行 telnet 218.14.227.197 3128 来检测该地址的该端口是否畅通。如果得到出错信息,需要先获取正确的代理服务信息;

检查完毕之后,编辑 ~/.m2/settings.xml 文件。添加代理配置如下:

<proxy>
  <id>my-proxy</id>
  <active>true</active>
  <protocol>http</protocol>
  <host>218.14.227.197</host>
  <port>3128</port>
  <!-- <username>proxyuser</username>
  <password>proxypass</password>
  <nonProxyHosts>local.net|some.host.com|*.google.com</nonProxyHosts> -->
</proxy>

这段配置十分简单, proxies 下可以有多个 proxy 元素,如果声明了多个 proxy 元素,则默认情况下第一个被激活的 proxy 会生效。这里声明了一个 id 为 my-proxy 的代理, active 的值为 true 表示激活该代理, protocol 表示使用的代理协议,这里是 http。当然,最重要的是指定正确的主机名(host元素)和端口(port元素)。上述 XML 配置中注释掉了 username、password、 nonProxyHosts 几个元素。当代理服务需要认证时,就需要配置 username 和 password。nonProxyHosts 元素用来指定哪些主机名不需要代理,可以使用 "|" 符号来分隔多个主机名。此外,该配置也支持通配符,如 *.google.com 表示所有以 google.com 结尾的域名不需要代理。

5. maven 安装最佳实践

本节介绍一些在安装 Maven 过程中不是必须的,但十分有用的实践。

5.1 设置 MAVEN_OPTS 环境变量

前面介绍 Maven 安装目录时我们了解到,运行 mvn 命令实际上是执行了Java 命令,既然是运行 Java,那么运行 Java 命令可用的参数当然也应该在运行 mvn 命令时可用。这个时候, MAVEN_OPTS 环境变量就能派上用场。

通常需要设置 MAVEN_OPTS 的值为 -Xms128m -Xmx512m,因为 Java 默认的最大可用内存往往不能够满足 Maven 运行的需要,比如在项目较大时,使用 Maven 生成项目站点需要占用大量的内存,如果没有该配置,则很容易得到 java.lang.OutOfMemeoryError。因此,开始就配置该变量是推荐的做法。

关于如何设置环境变量,请参考前面设置 MAVEN_HOME 环境变量的做法,尽量不要直接修改 mvn.bat 或者 mvn 这两个 Maven 执行脚本文件。因为如果修改了脚本文件,升级 Maven 时就不得不再次修改,一来麻烦,二来容易忘记。同理,应该尽可能地不去修改任何 Maven 安装目录下的文件。

5.2 配置用户范围 settings.xml

Maven 用户可以选择配置 $MAVEN_HOME/conf/settings.xml 或者 ~/.m2/settings.xml。前者是全局范围的,而后者是用户范围的。Maven 会先找用户配置,如果找到则以用户配置文件为准,否则使用全局配置文件。

推荐使用用户范围的 settings.xml,主要是为了避免无意识地影响到系统中的其他用户。如果有切实的需求,需要统一系统中所有用户的 settings.xml 配置,当然应该使用全局范围的 settings.xml。

除了影响范围这一因素,配置用户范围 settings.xml 文件还便于 Maven 升级。直接修改 conf 目录下的 settings.xml 会导致 Maven 升级不便,每次升级到新版本的 Maven,都需要复制 settings.xml 文件。如果使用 ~/.m2 目录下的 settings.xml,就不会影响到 Maven 安装文件,升级级时就不需要触动 settings.xml 文件。

5.3 不要使用IDE内嵌的 Maven

Maven 入门使用

1. Maven 项目工程目录约定

Project
  |-src
  |   |-main
  |   |  |-java        —— 存放项目的 .java 文件
  |   |  |-resources   —— 存放项目资源文件,如 spring、hibernate 配置文件
         |-webapp      —— webapp 目录是 web 工程的主目录
            |-WEB-INF
              |-web.xml
  |   |-test
  |      |-java        —— 存放所有测试 .java 文件,如 JUnit 测试类
  |      |-resources   —— 测试资源文件
  |-target             —— 目标文件输出位置例如 .class、.jar、.war 文件
  |-pom.xml            —— Maven 项目核心配置文件

2. 常用的 Maven 命令

(1) compile

compile 是 Maven 工程的编译命令,作用是将 src/main/java 下的文件编译为 class 文件输出到 target 目录下。

(2) test

test 是 Maven 工程的测试命令,会执行 src/test/java 下的单元测试类。

(3) clean

test 是 Maven 工程清理命令,执行 clean 会删除 target 目录的内容。

(4) package

package 是 Maven 工程的打包命令,对于 java 工程执行 package 打成 jar 包,对于 web 工程打成 war 包。

(5) install

install 是 Maven 工程的安装命令,执行 install 将 Maven 打成 jar 包或 war 包发布到本地仓库。

3. 生命周期

3.1 三套生命周期

Maven 对项目构建过程分为三套相互独立的生命周期,请注意这里说的是“三套”,而且“相互独立”,这三套生命周期分别是:

Clean Lifecycle 在进行真正的构建之前进行一些清理工作。
Default Lifecycle 构建的核心部分,编译,测试,打包,部署等等。
Site Lifecycle 生成项目报告,站点,发布站点。

3.2 生命周期的阶段

3.2.1 clean 生命周期的阶段

  1. pre-clean 执行一些需要在 clean 之前完成的工作
  2. clean 移除所有上一次构建生成的文件
  3. post-clean 执行一些需要在 clean 之后立刻完成的工作

3.2.2 defalut 生命周期的阶段

  1. validate
  2. generate-sources
  3. process-sources
  4. generate-resources
  5. process-resources 复制并处理资源文件,至目标目录,准备打包。
  6. compile 编译项目的源代码。
  7. process-classes
  8. generate-test-sources
  9. process-test-sources
  10. generate-test-resources
  11. process-test-resources 复制并处理资源文件,至目标测试目录。
  12. test-compile 编译测试源代码。
  13. process-test-classes
  14. test 使用合适的单元测试框架运行测试。这些测试代码不会被打包或部署。
  15. prepare-package
  16. package 接受编译好的代码,打包成可发布的格式,如 JAR 。
  17. pre-integration-test
  18. integration-test
  19. post-integration-test
  20. verify
  21. install 将包安装至本地仓库,以让其它项目依赖。
  22. deploy 将最终的包复制到远程的仓库,以让其它开发人员与项目共享。

3.2.3 site 生命周期的阶段

  1. pre-site 执行一些需要在生成站点文档之前完成的工作
  2. site 生成项目的站点文档
  3. post-site 执行一些需要在生成站点文档之后完成的工作,并且为部署做准备
  4. site-deploy 将生成的站点文档部署到特定的服务器上

3.3 命令与生命周期的阶段

每个 maven 命令对应生命周期的某个阶段,例如:

mvn clean 命令对应 clean 生命周期的 clean 阶段
mvn test 命令对应 default 生命周期的 test 阶段

执行命令会将该命令在的在生命周期当中之前的阶段自动执行,比如:

mvn clean 命令会自动执行 pre-clean 和 clean 两个阶段
mvn test 命令会自动执行 validate、compile、test 等阶段

注意:执行某个生命周期的某个阶段不会影响其它的生命周期!

如果要同时执行多个生命周期的阶段可在命令行输入多个命令,中间以空格隔开,例如:

clean package 该命令执行 clean 生命周期的 clean 阶段和 default 生命周期的 package 阶段

4. pom.xml 基本配置

pom.xml 是 Maven 项目的核心配置文件,位于每个工程的根目录,基本配置如下:

<project > :文件的根节点 .
<modelversion > : pom.xml使用的对象模型版本
<groupId > :项目名称,一般写项目的域名
<artifactId > :模块名称,子项目名或模块名称
<version > :产品的版本号 . 
<packaging > :打包类型,一般有jar、war、pom 等 
<name > :项目的显示名,常用于 Maven 生成的文档。  
<description > :项目描述,常用于 Maven 生成的文档
<dependencies> :项目依赖构件配置,配置项目依赖构件的坐标
<build> :项目构建配置,配置编译、运行插件等。

Maven系列(一)plugin

maven-compiler-plugin

使用 mvn compile 命令,出现错误: 编码 GBK 的不可映射字符而不能编译。这是因为代码或注释中存在中文引起的,一般在 IDE 中会自动处理编译时的字符集,就不会碰到这个错误。这个错误是在生成代码后,其中自动加上了中文注释,手动删除中文注释处理这个问题太麻烦。这个错误是在命令行执行编译命令才出现的,需要设置编译的字符集,设置方式是:

<plugin> 
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId> 
    <configuration> 
        <source>1.7</source> 
        <target>1.7</target> 
        <encoding>UTF-8</encoding> 
    </configuration> 
</plugin> 

其中:

  • encoding 如果不设置的话会用本地操作系统的编码来编译文件

maven-resources-plugin

<plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-resources-plugin</artifactId> 
    <version>2.3</version> 
    <configuration> 
        <encoding>UTF-8</encoding> 
    </configuration> 
</plugin>

其中:

  • encoding 设置资源文件的编码方式

maven-dependency-plugin

拷贝依赖包 mvn dependency:copy-dependencies,默认会拷到项目的 target\dependency 目录,想要复制到自定义的目录比如 target/lib 目录下,需要在 pom.xml 文件中添加设置覆盖默认设置:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <configuration>
        <outputDirectory>${project.build.directory}/lib</outputDirectory>
        <excludeTransitive>false</excludeTransitive>
        <stripVersion>true</stripVersion>
    </configuration>
</plugin>

其中:

  • outputDirectory ${project.build.directory}是maven变量,表示target目录。如果不写的话,将在根目录下创建 target\dependency 目录;
  • excludeTransitive 表示是否不包含间接依赖的包;
  • stripVersion 表示复制的jar文件去掉版本信息。

如果需要在其他过程,比如 package 中加入 copy-dependencies,需要在该 plugin 标签中这样设置:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>copy-dependencies</id>
            <phase>package</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <outputDirectory>${project.build.directory}/lib</outputDirectory>
                <excludeTransitive>false</excludeTransitive>
                <stripVersion>true</stripVersion>
            </configuration>
        </execution>
    </executions>
</plugin>

maven-jar-plugin

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
        <archive>
            <manifest>
                <mainClass>com.github.binarylei.network.netty.helloworld.Server</mainClass>
                <!-- 打包时 MANIFEST.MF文件不记录的时间戳版本 -->
                <useUniqueVersions>false</useUniqueVersions>
                <addClasspath>true</addClasspath>
                <classpathPrefix>lib/</classpathPrefix>
            </manifest>
        </archive>
    </configuration>
</plugin>

maven-javadoc-plugin

通过 maven-javadoc-plugin 生产文档包插件

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-javadoc-plugin</artifactId>
    <version>2.10.4</version>
    <configuration>  
        <aggregate>true</aggregate>  
    </configuration> 
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>jar</goal>
            </goals>
        </execution>
    </executions>
</plugin>

maven-source-plugin

通过 maven-source-plugin 生产源码包插件

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-source-plugin</artifactId>
    <version>2.4</version>
    <configuration>  
        <attach>true</attach>  
    </configuration> 
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>jar-no-fork</goal>
            </goals>
        </execution>
    </executions>
</plugin>

tomcat7-maven-plugin

tomcat7:run 本地运行项目

 <plugin>
    <groupId>org.apache.tomcat.maven</groupId>
    <artifactId>tomcat7-maven-plugin</artifactId>
    <version>2.2</version>
    <configuration>
        <!--此端口表示本地项目运行的端口-->
        <port>9999</port>
        <!--利用tomcat manager部署-->
        <url>http://192.168.0.11:8080/manager/text/</url>
        <server>tomcat-deploy</server>
        <!--以下用户名和密码需要在tomca-user.xml文件中配置如下内容
        <role rolename="tomcat"/>  
        <role rolename="manager"/>      
        <role rolename="manager-script"/>  
        <role rolename="manager-status"/>  
        <role rolename="manager-jmx"/>      
        <role rolename="manager-gui"/>  
        <role rolename="admin"/>  
        <role rolename="admin-gui"/>   
        <user username="tomcat" password="tomcat" roles="admin,admin-gui,manager,manager-gui,manager-script,manager-status,manager-jmx"/>  
        第一次部署用tomcat7:deploy命令,前提是tomcat必须先启动,然后tomcat webapps目录下manager目录还在
        tomcat7:redeploy重新部署
        tomcat7:undeploy删除部署
        -->
        <username>tomcat</username>
        <password>tomcat</password>
        <!--项目部署访问路径-->
        <path>/${project.name}</path>
    </configuration>
</plugin>

jetty-maven-plugin

 <plugin>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-maven-plugin</artifactId>
    <version>9.3.8.v20160314</version>
    <configuration>
        <webAppConfig>
            <!-- 指定 root context 在这里指定为${project.artifactId} 即 jetty, 那么访问时就用http://localized:8080/jetty 
                访问, 如果指定梶为test 就用http://localized:8080/test访问,更多信息,请查看jetty 插件官方文档 -->
            <contextPath>/${project.name}</contextPath>
            <defaultsDescriptor>src/test/resources/webdefault.xml</defaultsDescriptor>
        </webAppConfig>
        <stopPort>9966</stopPort>
        <stopKey>stop</stopKey>
        <stopWait>10</stopWait>
        <scanIntervalSeconds>10</scanIntervalSeconds>
        <!-- 指定额外需要监控变化的文件或文件夹,主要用于热部署中的识别文件更新 -->
        <scanTargetPatterns>
            <scanTargetPattern>
                <directory>src</directory>
                <includes>
                    <!-- <include>*.java</include> <include>*.properties</include> -->
                    <include>*.html</include>
                    <include>*.js</include>
                    <include>*.css</include>
                </includes>
                <!-- <excludes> <exclude>**/*.xml</exclude> <exclude>**/myspecial.properties</exclude> 
                    </excludes> -->
            </scanTargetPattern>
        </scanTargetPatterns>
        <!-- 指定监控的扫描时间间隔,0为关闭jetty自身的热部署,主要是为了使用jrebel -->
        <!-- <scanIntervalSeconds>0</scanIntervalSeconds> -->
        <!-- 指定web页面的文件夹 -->
        <webAppSourceDirectory>${project.name}/src/main/webapp</webAppSourceDirectory>
    </configuration>
</plugin>


Maven系列(二)exec-maven-plugin

1. mvn 命令行运行

# exec:java 不会自动编译代码,你需要手动执行 mvn compile 来完成编译
mvn compile 
# 执行 exec 运行 main 方法
mvn exec:java -Dexec.mainClass="com.github.binarylei.Main" 
    -Dexec.args="arg0 arg1 arg2" 
mvn exec:exec -Dexec.executable="java" -Dexec.args="-DsystemProperty1=value1 -DsystemProperty2=value2 
    -XX:MaxPermSize=256m -classpath %classpath com.github.binarylei.Main arg1 arg2"

2. exec:java

exec 主要由两个 goal 组成:exec:exec 和 exec:java。你应该如何选择呢?

  • 首先,你需要记住,exec:exec 总是比 exec:java 强大而灵活
  • 此外,两者的主要区别是在线程管理上:exec:exec 总是启动一个新的线程,并且在只剩下守护线程的时候从 VM 上退出(关闭应用程序)。而对于 exec:java,当所有非守护线程结束时,守护线程会被 join 或 interrupt,应该程序不会关闭。

一般的使用者来说,这种差别并不重要。对于两者的选择,一般来说,如果你的工程启动非常简单,不需要设置 jvm 参数、系统属性、命令行参数,那么就用 exec:java,你只需要指定一下 mainClass,一切就 OK 了。例如这面这段配置:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <version>1.2.1</version>
    <executions>
        <execution>
            <phase>install</phase>
            <goals>
                <goal>java</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <mainClass>com.github.binarylei.Main</mainClass>
    </configuration>
</plugin>

3. exec:exec

假定我们的应用程序是通过这样的 java 命令来启动的:

java -DsystemProperty1=value1 -DsystemProperty2=value2 -XX:MaxPermSize=256m 
    -classpath .... com.github.binarylei.Main arg1 arg2

这个启动命令先后为应用程序设置了必要的系统属性:

  • systemProperty1 和 systemProperty2,
  • jvm 参数
  • classpath:....省略的部分就是我不说你也能想到会有多么冗长的类路径
  • 程序入口:--主类的类名,arg1/arg2 是传给应用程序的命令行参数
<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <version>1.2.1</version>
    <executions>
        <execution>
            <phase>install</phase>
            <goals>
                <goal>exec</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <executable>java</executable> <!-- executable指的是要执行什么样的命令 -->
        <arguments>
            <argument>-DsystemProperty1=value1</argument> <!-- 这是一个系统属性参数 -->
            <argument>-DsystemProperty2=value2</argument> <!-- 这是一个系统属性参数 -->
            <argument>-XX:MaxPermSize=256m</argument> <!-- 这是一个JVM参数 -->
            <argument>-classpath</argument> <!-- 这是classpath属性,其值就是下面的<classpath/> -->
            <classpath/> <!-- 这是exec插件最有价值的地方,工程的classpath并不需要手动指定,由exec自动计算得出 -->
            <argument>com.github.binarylei.Main</argument> <!-- 程序入口,主类名称 -->
            <argument>arg1</argument> <!-- 程序的第一个命令行参数 -->
            <argument>arg2</argument> <!-- 程序的第二个命令行参数 -->
        </arguments>
    </configuration>
</plugin>

如果 pom 配置了插件则通过以下命令启动程序:

mvn exec:exec 或
mvn installs

是不是简洁了很多。

4. profiles

<profiles>
    <profile>
        <id>dev</id>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>exec-maven-plugin</artifactId>
                    <version>1.2.1</version>
                    <executions>
                        <execution>
                            <phase>install</phase>
                            <goals>
                                <goal>java</goal>
                            </goals>
                        </execution>
                    </executions>
                    <configuration>
                        <mainClass>com.github.binarylei.Main2</mainClass>
                        <arguments>
                            <argument>arg1</argument>
                            <argument>arg2</argument>
                        </arguments>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>

maven 中可以通过以下命令启动程序:

mvn installs -Pdev
posted @ 2021-11-17 10:13  常给自己加个油  阅读(157)  评论(0)    收藏  举报