使用Maven3加速开发

3
到目前为止,我发现了两种使用maven3运行程序的方法:
  1. $ mvn exec:exec -Dexec.args='...'
  2. $ mvn assembly:assembly && java -cp all-with-dependecies.jar example.Main ...
前一种方法使用mvn的JVM,会捕获异常并且启动速度很慢。后一种方法也很慢,因为它需要构建一个大的jar包并运行测试。
我希望使用类似于 $ mvn compile && java -cp $CLASSPATH example.Main 的方式。由于通常情况下 CLASSPATH 在运行之间是不变的,所以我只需要担心一次。
我的问题是如何在开发周期中加快编译、修改和测试的速度?

顺便问一下,你正在写什么类型的应用程序?是一个命令行工具吗? - Puce
你的命令行工具是否等待输入 (即可以长时间运行)还是执行完毕后立即退出? - Adam Gent
@Adam:它不等待标准输入。它需要一些参数并运行几秒钟。通常编译时间比运行时间长。 - Alexandru
8个回答

3
你可以尝试使用Maven Shell。它的介绍如下:
"Maven Shell是一个Maven的CLI界面,可实现更快的反应速度和与存储库和项目进行更智能的交互。使用Maven Shell,你将能够加速构建,因为项目信息和Maven插件都加载到一个单一的、始终准备好的JVM实例中,该实例可以执行Maven构建。"

我刚刚在玩mvnshell,它非常棒。 - Adam Gent

2
你可以使用Maven Dependency Plugin来构建类路径,然后重复使用它:
$ mvn dependency:build-classpath -Dmdep.outputFile=cp.txt
$ export CLASSPATH=target/classes:`cat cp.txt`
...
$ mvn compile && java -cp $CLASSPATH example.Main

2

尽量少用mvn命令行,而是使用像Eclipse这样的集成开发环境,以便快速测试增量更改。

Eclipse可以进行增量构建,即只构建更改的部分,因此速度更快。


我使用vim,需要从命令行运行应用程序。 - Alexandru
你可以在Eclipse中使用vim。有很多关于这方面的文章。 - Adam Gent

0

你可以通过传递选项:-Dmaven.test.skip=true 来跳过测试。

为什么你假设启动一个新的 JVM 比在 Maven 的 JVM 中运行程序更快呢?很可能恰恰相反。

编辑:加速开发周期的另一种简单方法是使用 --offline 选项,除非你正在改变依赖关系。


我只有几个测试。禁用它们并没有帮助太多。 - Alexandru
我并没有做出假设。在 mvn 启动和我的应用启动之间有相当长的时间间隔。 - Alexandru

0
上一次我创建命令行工具时,我使用了依赖插件将所有依赖软件包复制到一个目录中(例如target/dist/lib),在清单文件中配置了类路径和主类(Maven Jar 插件)。然后,我可以通过以下方式执行该应用程序: java -jar myJar.jar

你能详细说明一下你是如何复制所有依赖库的吗?我也在尝试同样的事情,但是我找不到如何做到这一点。 - Alexandru
就像我之前所说的,使用Maven依赖插件:http://maven.apache.org/plugins/maven-dependency-plugin/copy-dependencies-mojo.html注意,正如其他人提到的,在开发过程中,直接使用IDE启动应用程序比在命令行上更容易。 - Puce

0

除了Eclipse之外,另一个选择是使用JRebel,它可以有效地热替换您的代码,以便您可以一直运行程序。

不幸的是,JRebel并非免费,除非您是开源或使用Scala。

如果您在Eclipse(或IntelliJ)中使用调试模式运行程序,您也可以使用您的代码进行热替换,但您无法添加或删除方法。

我发现这两种方法在Java环境中是最有效的,如果您想要即时反馈。

最后一个选择是配置Maven使用Eclipse编译器,它比openjdk编译器更快(据说)。


0
如果您需要实现一个命令行工具,可以看一下maven appassembler插件,它在这种情况下非常有帮助。与maven-assembly相关,您可以创建一个.tar.gz/zip归档文件,可以解压缩并启动应用程序。

0
  • 创建一个单一的模块来管理所有构建时依赖项(注解、嵌入式Tomcat、代码生成器等)。只需构建一次,然后将其附加到编译器插件上,以便它们在所有模块的构建路径上。

  • 创建一个小的共享配置,并在每个模块中在构建时解压缩它(检查样式配置、日志配置等)。

  • 将Maven插件放置在它们自己的独立配置文件中,可以根据需要即时引入。例如:检查样式、FindBugs、JavaDoc、Surefire、Failsafe、代码签名等。您的正常构建应尽可能少地使用插件。这真的有助于故障排除,因为任何插件都可以通过-P命令行选项单独启用。

  • 避免在编译器插件上使用fork配置,它会使构建时间加倍。如果您需要-parameters,则仅为需要它的类分叉一次。

  • 编写测试,使它们可以并行运行。没有测试应该超过一秒钟。

  • 使用-T 1C选项并行构建。

  • 使用嵌入式版本的Tomcat,而不是Tomcat插件,用于启动Tomcat进行集成测试。避免多次启动Tomcat。

  • 在Tomcat配置属性中排除任何不需要扫描的JAR文件。

  • 将项目结构化为平衡树,在其自己的父POM下分组相关组件。

最顶层是你的BOM POM模块,共享资源模块和共享构建路径模块。一旦你把所有东西组织好了,你很少会再次构建它们。

接下来是你的顶级应用程序POM,其中包括以下父POM:

-没有依赖关系的通用低级模块。

-网关模块,包括http客户端库和接口模块。

-业务服务模块

-容器 - tomcat、Spring、DropWizzard等。

-包 - ubber jars、zips

-运行时 - Rpms、可执行的jars

POM依赖关系应始终指向更高级别的POM,以避免循环依赖。

较慢的构建工件应该放在最后,这样你就可以在不必等待缓慢打包的情况下工作。

你应该能够在大约5秒钟内构建任何组,用5秒钟构建你的war,在10秒钟内启动带有spring的tomcat,最坏情况下迭代20秒。

  • Maven编译器快速且增量,因此尽量避免生成任何强制重新编译的代码

  • 为你的测试创建一个小型DSL和解释器。我们已经看到这种方法运行速度是junit的两倍。

我刚刚使用这些技术将我们的大型完整构建时间从5分钟缩短到了45秒。虽然需要进行大量工程设计,但是这是值得的。这种方法适用于标准的Maven发布插件,并且可以使故障排除更加容易。

祝你好运。 永远不够快

PS PCIe固态硬盘也是很有帮助的


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接