在您的Maven-Fu包中增加了一些东西
Apache Maven很简单,但是功能非常强大。 使用一些技巧,您可以大大简化和优化您的开发经验。
处理多个非托管模块
假设您有一个主项目A
提供了两个实用程序模块foo
和bar
,另一个项目B
A
了foo
和bar
。
在使用B
,您意识到需要偶尔对foo
和bar
进行一些调整。 但是,由于它们在不同的项目中,因此通常需要
- 切换到
A
- 做出改变
mvn install
- 切换回
B
- 和“刷新”依赖项(如果您使用的是IDE)。
每次都需要进行上游更改。
使用Maven,您可以使用模拟主POM临时“合并”这三部分,该主POM将foo
, bar
和B
定义为子模块:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><!-- blah blah blah --><modules><module>foo</module><module>bar</module><module>B</module></modules>
对我有什么用?
IDE(如IntelliJ IDEA )会将根标识为多模块项目。 这意味着您将能够:
- 从一个模块无缝浏览到另一个模块。 不再需要反编译,字节码不兼容或源映射 ; 在“综合”项目范围内搜索某种类或方法的用法(或重构其中一种方法)时,非常方便。
- 在同一项目窗口中按需修改每个模块的源和资源。 IDE将自动重新编译所做的更改,并将所有内容添加到运行时类路径中。 方便进行带热重装的IDE测试和调试。
- 版本无缝。 如果这三个模块位于不同的VCS根目录下,则IDEA(如IDEA)将分别跟踪每个存储库。 如果您提交了一组更改,则每个存储库都会有一个新的提交,以反映其自己的更改部分; 都带有相同的消息!
同时,如果构建了根模块,那么普通的Maven将按照适当的顺序构建foo
/ bar
和B
(如果需要),这正是我们想要的。
相对路径,FTW!
即使模块分散在整个文件系统中,Maven仍可以通过相对路径轻松解决它们:
<modules><module>../foo</module><module>grandpa/papa/bar</module><module>../../../../../media/disk2/repos/top-secret/B</module></modules>
放下那
也许最常用(因此最被滥用 )的Maven命令是:
mvn clean install
在您对项目进行一些更改后,事实上的事实便会运行。
而且,在大多数情况下,这简直是过分杀伤力。
从头开始?
该命令结合了两个生命周期阶段 – Maven构建过程的“阶段”。 阶段具有确定的顺序; 因此,如果您请求某个阶段运行,则其生命周期中的所有先前阶段都将在此阶段之前运行。 但是,如果Maven插件发现自己无事可做,那么他们就足够聪明地跳过工作。 例如,如果编译的类是最新的,则不会进行编译。
现在, clean
不再是默认生命周期的一部分; 而是通过删除整个target
目录从头开始。 另一方面, install
几乎快结束了(就在默认生命周期中进行deploy
之前)。
mvn clean install
将同时运行这两个阶段; 而且,由于clean
, 介于两者之间的所有事物也同样如此 。
当您想要清理所有内容并最终将最新的工件安装到本地 Maven存储库中时,它很方便。 但是在大多数情况下,您并不需要所有这些。
此外, install
最终会使您的本地Maven缓存混乱; 特别是如果您经常使用MB或GB大小的捆绑包进行快照/发布。
只做必要的事情!
如果您更新了一个源文件,并希望将其传播到target/classes
目录:
mvn compile
Maven将自动检测任何更改–如果没有更改,则完全跳过编译。
如果更改是在测试类或资源中:
mvn test-compile
将其放入target/test-classes
。
只是为了运行测试(它将自动编译任何脏的源代码/测试类):
mvn test
要获得target
最终捆绑包的副本:
mvn package
由于您可能经常要在包装之前先从干净的表盘开始:
mvn clean package
同样,只需指定结束阶段即可; 或同时包含开始和结束目标(如果要在某种程度上保持清洁)。 您将节省大量时间,处理能力和脾气。
同时在生产中…
如果您当前的版本可以投入生产,只需忘记上面的大部分内容即可;)
mvn clean package
虽然任何“子命令”在理论上都应该做同样的事情,但是您不想冒险;)
虽然我使用上面的package
,但从某种意义上说, install
也会更好。 因为这样您将在.m2/repository
中拥有生产工件的副本–如果丢失了已交付/部署的副本,则可能会节省很多时间。
更多跳过…
--no-snapshot-updates
如果您仔细观察了一个涉及快照依赖项的构建,您会发现它花了几秒钟的时间来搜索快照的Maven元数据文件(并最终以警告告终;除非您习惯于将快照工件发布到远程)。
如果您还本地建立快照依赖关系,那么通常这没有用,因此可以通过--no-snapshot-updates
或-nsu
参数禁用元数据检查(和快照同步尝试)。
当然, -o
将阻止所有远程同步; 但是如果您确实想提取某些依赖项,则不能使用它,在这种情况下, -nsu
会有所帮助。
您可以跳过编译!
像(著名的) -Dmaven.test.skip
–或-DskipTests
,您可以通过-Dmaven.main.skip
跳过编译步骤(即使代码有所更改)。 当您只想运行测试而无需花费编译开销时,非常方便; 当然,如果您知道这些内容已经被编译。 就像-DskipTests
一样-但是-DskipTests
!
( 对此SO帖子表示敬意)
延续:
您可能已经知道,如果模块在构建过程中发生故障,则可以通过-rf :module-name
参数从该点恢复构建。
此参数也可以立即使用。 它不仅限于故障场景。 如果您有30个模块,但是只想构建最后5个模块,则可以使用-rf :name-of-26th-module
。
美味的测试技巧
继承测试
通常,Maven工件不包括测试类/资源。 但是在某些情况下,您希望将一些基本测试类继承到子模块中。 使用测试罐说明符,您可以继承仅包含测试类和资源的工件:
<dependency><groupId>com.acme</groupId><artifactId>foo</artifactId><version>3.2.1</version><type>test-jar</type><scope>test</scope></dependency>
“从属”模块上的相应构建配置如下:
<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><executions><execution><goals><goal>test-jar</goal></goals></execution></executions></plugin></plugins></build>
一个警告是,在此过程中不会继承可传递测试依赖项,而必须在每次使用测试JAR时再次手动指定它们。 (至少我没有遇到更好的选择。)
如果您正在处理一个测试用例,请不要全部运行。
-Dtest=com.acme.my.pkg.Test
可以单独进行WIP测试,因此可以节省大量时间。
根据您的测试运行程序, -Dtest
也可能支持通配符选择器 。
当然,您可以临时修改测试插件配置的或数组(例如SureFire )以限制可运行测试的集合。
调试它
调试Maven测试?
如果您的测试运行程序(例如SureFire)允许您自定义用于测试的命令行或JVM参数,则可以轻松地将派生的JVM配置为在测试开始执行之前等待调试器 :
<build><pluginManagement><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><!-- ... --><configuration><argLine>-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,address=8000</argLine>
调试Maven本身?
如果您正在编写或对Maven插件或扩展进行故障排除,则在调试模式下运行Maven本身会很方便。
Maven最终是Java,因此您可以简单地调用调用时运行的最终命令,然后使用-Xdebug
…params重新运行它。
但是Maven已经有了一个更酷的mvnDebug
命令,可以自动为您执行此操作。 它的语法与mvn
相同,因此非常容易习惯。
调用后,默认情况下它将在端口8000上侦听调试器,并在连接一个端口后立即开始执行; 并在断点处停止,显示内部状态,允许表达式求值等。
看日志!!!
这是值得的,因为我们非常善于忽略事物-就在眼前。
就在一开始
我敢打赌,在构建开始时,Maven会有95%的机会喷出至少一个[WARNING]
。 虽然我们几乎总是忽略或“推迟”它们,但它们会在将来的某个时刻咬人。
即将结束
如果出现编译,测试或其他故障,Maven将尝试通过转储上下文(stacktraces, [ERROR]
等)来提供帮助。 有时,您需要向后滚动一到两页才能找到实际的内容,因此,不要在第一次尝试时就放弃并砸在脸上。
最近,我花了将近一个小时的时间来弄清楚-rf :
原因-rf :
'd build失败; 从头开始时,同一件事成功了。 最后,它systemPath
关于systemPath
依赖项解决错误的两行[WARNING]
小systemPath
。 就在我眼前,却如此无形。
绝望的时光
在某些情况下,标准的Maven输出无法查明问题,在跟踪模式( -X
)中运行Maven是最佳做法。 尽管其输出可能令人生畏,但它包含Maven(以及您)在构建过程中需要了解的所有内容。 插件版本,编译/测试依赖树,外部命令调用(例如测试); 这样您就可以深入挖掘并找到罪魁祸首。
一如既往,耐心是一种美德。
最后的话
就像使用Maven一样,
- 知道你在做什么。
- 知道你真正想做什么。
- 相信Maven可以做到 ,除非另有证明;)
翻译自: https://www.javacodegeeks.com/2018/11/additions-bag-maven-fu.html
在您的Maven-Fu包中增加了一些东西相关推荐
- Eclipse Maven 依赖包找不到源代码及javadoc
1. 问题描述 可以查看 jdk 源代码及对应的 javadoc 文件: 可以查看 maven 依赖包中 zookeeper 对应的源代码和 javadoc 文件: 但是新下载了 org.apache ...
- [Android] 介绍一个gradle插件shrinker: 快速无副作用去除apk包中多余的 R类
看到微信团队近期把 Matrix 开源了,点个赞并蹭个热点 Matrix其中有个组件是 ApkChecker,他会检查apk包中一系列"多余"的东西.其中有一项功能是: 统计apk ...
- java打包要依赖maven库吗_maven-将依赖的 jar包一起打包到项目 jar 包中
前言: 有时候在项目开发中,需要很多依赖的 jar 包,其中依赖的 jar 包也会依赖其他的 jar 包,导致jar 包的管理很容易不全,以下有两种方法可以规避这个问题. 一.在pom.xml 文件中 ...
- linux 手动解压or增加or更新 jar 包中文件
查看 jar 包中的文件列表,进行重定向,输出到txt文件 jar -tvf aa.jar > aa.txt 更新文件到 jar 中,目录需对应 jar -uf aa.jar com/aa.cl ...
- dependency报红_解决IDEA中Maven依赖包导入失败报红问题(总结最有效8种解决方案)...
问题描述: 真的,说来话长,这应该是我花最多时间去解决关于Maven依赖包导入的问题,以前粘贴复制导入,自动下载成功了, 这次怎么搞,怎么让他自动下载都还是红红的一片, 花了大半天,各种尝试,只为搏得 ...
- IDEA中Maven依赖包无法下载,maven使用阿里源无法Could not transfer artifact xx.xx from/to alimaven(aliyun)-
方式一: 大部分人会有这种问题,直接修改即可,请参考持.之.以.恒 IDEA中Maven依赖包无法下载或导入问题解决办法 二 maven使用阿里数据源不能生效,如这种 Could not transf ...
- linux上jar包无法识别本地文件格式,解决使用maven将项目打包成jar包后运行在linux系统中无法读取jar包中文件的问题...
哈哈,之前计划的每周至少更新一个博客的计划又因为各种原因都泡汤了.看来坚持真得是一件挺让人头疼的问题,无论如何,从这周开始接下来每周一定要至少更新一个技术博客,欢迎大家监督! 好,言归正传.之前前几周 ...
- 【springboot maven 本地包依赖】
springboot maven 本地包依赖 一. 注册到本地maven(推荐) 优势: 可以二次依赖,重复使用 劣势: 同时使用这个工程的人,需要重复在本地安装这个包 首先在本地安装本地依赖包(只需 ...
- linux替换jar的文件,Linux下用jar命令替换war包中的文件【转】
问题背景:在Linux环境上的weblogic发布war包,有时候只是修改了几个文件,也要上传整个war包,这样很费时间,因此整理了一下Linux环境,更新单个文件的方法. 1.如果要替换的文件直接在 ...
最新文章
- 【Java】LeetCode 232. 用栈实现队列
- 利用FreeImage将gif图像转为opencv中的Mat
- XML表示的数据库数据
- PostgreSQL参数优化对比性能测试
- SQL逻辑查询语句执行顺序
- 笔记-项目进度管理-控制进度
- Asp.Net CoreDocker部署到树莓派3B中
- bfs理解——hdu6386好题
- /usr/include/sys/stat.h文件属性
- bzoj1770: [Usaco2009 Nov]lights 燈(折半搜索)
- python基础操作---string
- EPS中编写第一个程序
- 【编程知识】常用参考表对照表
- 齐治运维堡垒机后台命令执行漏洞
- Zebras CodeForces - 950C(思维)
- DS18B20的CRC验证算法
- Apache--配置虚拟主机
- 【java】Eclipse使用
- 记住CAD绘图快捷键,让你快速当大师
- DSP2812 RAM不够用的解决方法
热门文章
- 纪中A组模拟赛总结(2021.7.19)
- [POI2015] Pustynia(差分约数,线段树优化建图,拓扑)
- 详解Vue中watch的高级用法
- MySQL dayname()函数
- Java8-本地缓存
- List转数组toArray方法
- 28. 实现 strStr()---LeetCode---JAVA(今天又是一行超人)
- 2019蓝桥杯省赛---java---A---6(完全二叉树的权值)
- python快捷方式图标_python – PyInstaller无法更改快捷方式图标
- 利用session防止表单重复提交