1.为什么使用exec?

现在的工程往往依赖 众多的jar包,不像war包工程,对于那些打包成jar包形式的本地java应用来说,通过java命令启动将会是一件极为繁琐的事情,原因很简单,太 多的依赖让参数-classpath变得异常的恐怖。为此,在发布应用时,一般使用两种方法来启动应用程序:一种是通过工具将工程及其所有依赖的jar包 打包成一个独立的jar包(在maven里有两个插件assemly和shade是用来完成这种工作的);另一种方法是编写一个run.bat文件,文件 包含一个启动应用的java命令,很显然,这个命令的classpath必须包含全部依赖的jar包。但是对于尚处在开发阶段的应用来说,第一种方法需要 将所有jar包解压再重新打包,因此非常耗时,特别是工程非常大的时候。第二种方法的问题在于,对处在开发阶段的工程,经常需要引入或升级jar包,这就 需要频繁地修改run.bat文件。实际上,对于使用maven管理的工程,完全可以通过maven来获取工程的classpath,简化应用程序的启动 命令,这正是maven插件exec被设计出来的主要动机。使用exec比使用java命令去启动应用程序最大的优势就在于:你不需要再去为-classpath而伤脑筋了。

2. exec:execexec:java的区别

exec 主要由两个goal组成:exec:exec和exec:java。你应该如何选择呢?首先,你需要记住,exec:exec总是比exec:java强 大而灵活,这一点会在后面的示例中体现出来,除此之外,两者的主要区别是在线程管理上:exec:exec总是启动一个新的线程,并且在只剩下守护线程的 时候从VM上退出(关闭应用程序)。而对于exec:java,当所有非守护线程结束时,守护线程会被joine或interrupt,应该程序不会关 闭。但是对于一般的使用者来说,这种差别并不重要。对于两者的选择,一般来说,如果你的工程启动非常简单,不需要设置jvm参数、系统属性、命令行参数, 那么就用exec:java,你只需要指定一下mainClass,一切就OK了。例如这面这段配置:

[html] view plaincopy

  1. <plugin>

  2. <groupId>org.codehaus.mojo</groupId>

  3. <artifactId>exec-maven-plugin</artifactId>

  4. <version>1.2.1</version>

  5. <executions>

  6. <execution>

  7. <goals>

  8. <goal>java</goal>

  9. </goals>

  10. </execution>

  11. </executions>

  12. <configuration>

  13. <mainClass>com.yourcompany.app.Main</mainClass>

  14. </configuration>

  15. </plugin>

如果恰恰相反,你的应用程序启动非常复杂,需要设置jvm参数、系统属性、命令行参数等,那么你就需要使用exec:exec了,下面我们看一个exec:exec的“好”“大”“全”示例。

3.一个“好”“大”“全”的例子

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

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

这 个启动命令先后为应用程序设置了必要的系统属性systemProperty1和systemProperty2,然后设置了一个jvm参数,接着是程序 的classpath,....省略的部分就是我不说你也能想到会有多么冗长的类路径了,再接下来是程序入口--主类的类名,arg1 arg2是传给应用程序的命令行参数。

3.1. 在xml中配置:

首先我们来看一下如何在pom中通过配置来实现这个启动命令:

[html] view plaincopy

  1. <plugin>

  2. <groupId>org.codehaus.mojo</groupId>

  3. <artifactId>exec-maven-plugin</artifactId>

  4. <version>1.2.1</version>

  5. <configuration>

  6. <executable>java</executable> <!-- executable指的是要执行什么样的命令 -->

  7. <arguments>

  8. <argument>-DsystemProperty1=value1</argument> <!-- 这是一个系统属性参数 -->

  9. <argument>-DsystemProperty2=value2</argument> <!-- 这是一个系统属性参数 -->

  10. <argument>-XX:MaxPermSize=256m</argument> <!-- 这是一个JVM参数 -->

  11. <!--automatically creates the classpath using all project dependencies,

  12. also adding the project build directory -->

  13. <argument>-classpath</argument> <!-- 这是classpath属性,其值就是下面的<classpath/> -->

  14. <classpath/> <!-- 这是exec插件最有价值的地方,关于工程的classpath并不需要手动指定,它将由exec自动计算得出 -->

  15. <argument>com.yourcompany.app.Main</argument> <!-- 程序入口,主类名称 -->

  16. <argument>arg1</argument> <!-- 程序的第一个命令行参数 -->

  17. <argument>arg2</argument> <!-- 程序的第二个命令行参数 -->

  18. </arguments>

  19. </configuration>

  20. </plugin>

将上面的配置加到pom中并保存,然后执行:

mvn exec:exec

即可启动应用程序了。

3.2. 在命令行中配置:

除写在pom配置文件中,exec也支持更加灵活的命令行方式来启动,你可以在你的pom中只声明引入了exec插件,不提供任何配置内容,然后在命令行中设置相关参数,同样以上面的命令为例,如果使用命令行方式来配置,那么这个命令将会是:

mvn exec:exec -Dexec.executable="java" -Dexec.args="-DsystemProperty1=value1 -DsystemProperty2=value2 -XX:MaxPermSize=256m -classpath %classpath com.yourcompany.app.Main arg1 arg2"

怎么样,是不是看起来更加简洁?

注意:exec.args指的 是exec:exec的commandlineArgs参数,而我们上面xml配置中的参数是arguments,两者是不一样的,这种做法是比较好的, 因为exec规定:如果有commandlineArgs,将优先使用commandlineArgs,如果没有再去找是否配置了argument,这样 给我们在命令行执行不同设定参数的机会。下面是exec官网对此的相关说明:

1.If commandLineArgs is specified, it will be used as is, except for replacing %classpath with proper classpath using dependencies
2.Otherwise if the property exec.args is specified, it will be used
3.Otherwise the list of argument and classpath will be parsed and used

Exec Maven插件的更多相关文章

  1. 常用Maven插件介绍

    我们都知道Maven本质上是一个插件框架,它的核心并不执行任何具体的构建任务,所有这些任务都交给插件来完成,例如编译源代码是由maven- compiler-plugin完成的.进一步说,每个任务对应 ...

  2. 学习笔记——Maven实战(八)常用Maven插件介绍(下)

    我们都知道Maven本质上是一个插件框架,它的核心并不执行任何具体的构建任务,所有这些任务都交给插件来完成,例如编译源代码是由maven- compiler-plugin完成的.进一步说,每个任务对应 ...

  3. 【转载】常用Maven插件介绍

    http://www.cnblogs.com/crazy-fox/archive/2012/02/09/2343722.html 我们都知道Maven本质上是一个插件框架,它的核心并不执行任何具体的构 ...

  4. 【转】常用Maven插件

    我们都知道Maven本质上是一个插件框架,它的核心并不执行任何具体的构建任务,所有这些任务都交给插件来完成,例如编译源代码是由maven- compiler-plugin完成的.进一步说,每个任务对应 ...

  5. Spring cloud的Maven插件(一):repackage目标

    简介 Spring Boot Maven Plugin插件提供spring boot在maven中的支持.允许你打包可运行的jar包或war包. 插件提供了几个maven目标和Spring Boot ...

  6. Maven实战(八)——常用Maven插件介绍(下)

    我们都知道Maven本质上是一个插件框架,它的核心并不执行任何具体的构建任务,所有这些任务都交给插件来完成,例如编译源代码是由maven- compiler-plugin完成的.进一步说,每个任务对应 ...

  7. Windows10下安装Maven以及Eclipse安装Maven插件 + 创建Maven项目

    在官网下载Maven      http://maven.apache.org/download.cgi 下载下来后加压缩,将apache-maven-3.5.4文件夹复制到想要存放它的位置,我放在了 ...

  8. 常用的Maven 插件

    Maven本质上是一个插件框架,它的核心并不执行任何具体的构建任务,所有这些任务都交给插件来完成. 例如编译源代码是由maven- compiler-plugin完成的.进一步说,每个任务对应了一个插 ...

  9. 使用docker Maven插件本地构建docker镜像并发布到远程服务器

    1.登录网站https://start.spring.io/,生成一个基本的SpringBoot应用. 2.将应用导入Eclipse IDE并创建Application类.目录结构如下: Applic ...

随机推荐

  1. P-R曲线深入理解

    P-R曲线就是精确率precision vs 召回率recall 曲线,以recall作为横坐标轴,precision作为纵坐标轴.首先解释一下精确率和召回率. 解释精确率和召回率之前,先来看下混淆矩 ...

  2. 20191210-RobotFramework常见问题解决

    附加-问题解决 1.   执行robot用例的时候提示WebDriverException: Message: invalid argument: can't kill an exited proce ...

  3. 数列分段 II

    题目描述 思路 代码 #include <cstdio> int n, m, arr[100005], ans; int l, r, mid, inf = 0x7f3f3f3f; inli ...

  4. Django模型层之单表操作

    Django模型层之单表操作 一 .ORM简介 我们在使用Django框架开发web应用的过程中,不可避免地会涉及到数据的管理操作(如增.删.改.查),而一旦谈到数据的管理操作,就需要用到数据库管理软 ...

  5. shell中if条件字符串、数字比对,[[ ]]和[ ]区别

    目录 shell 括号 test 和 []符号 [[]] 符号 let和(())符号 "[]" , "[[]]" 和 "(())"对比 sh ...

  6. mvn: command not found in Jenkins slave

    在Jenkins上添加了一个slave node, 并绑定了一个团队项目,通过shell来执行后续操作,结果卡在了 mvn: command not found 其实这个node上是配置了maven的 ...

  7. Jmeter 接口测试之MD5加密函数(函数助手篇)

    转自:https://blog.csdn.net/hhyangel372/article/details/81571058 本文给大家介绍一下如何使用Jmeter自带的函数对常量和变量进行简单的加密处 ...

  8. www.qtbig.com:QList的at与[]10亿次运行速度比较(运行速度at都优于[],但区别不大)

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/nicai_xiaoqinxi/artic ...

  9. gradle中引用本地项目

    例如在别的地方有一个 apiProject,里面有 apiModule,你想要引用,而不是复制到现有项目,那么 1.现有项目的settings.gradle下 include ':apiModule' ...

  10. LOJ3120 CTS2019 珍珠 生成函数、二项式反演、NTT

    传送门 题目大意:给出一个长度为\(n\)的序列\(a_i\),序列中每一个数可以取\(1\)到\(D\)中的所有数.问共有多少个序列满足:设\(p_i\)表示第\(i\)个数在序列中出现的次数,\( ...