关于java:曹工杂谈Maven源码调试工程搭建

6次阅读

共计 4399 个字符,预计需要花费 11 分钟才能阅读完成。

Maven 源码调试工程搭建

思路

咱们后面的文章《【曹工杂谈】Maven 和 Tomcat 能有啥分割呢,都穿打补丁的衣服吗》剖析了 Maven 大体的执行阶段,次要包含三个阶段:

  1. 启动类阶段,负责加载框架;
  2. 框架外围(maven core)阶段,次要负责依据参数中的 goal,如 clean,找到对应的插件的 jar 包,生成插件对象,解析参数并调用插件代码;
  3. 插件执行阶段,执行实现后,控制权会交还给框架外围,由 maven core 实现善后工作。

这三个阶段,别离会去不同的中央加载对应的 jar 包。

大略理解了这个流程后,咱们开始思考,咱们到底要调试哪一部分的代码。

  • 如果咱们要调试阶段一的代码,那么,又分两种状况,是否须要改变阶段一的代码,如果须要改变,那么,就要找到阶段一的 jar 的源码,而后加载到 idea 中,并且,启动调试的时候,也需把 classpath 指定到咱们的源码工程;如果不须要改变,那就能够参考:《【曹工杂谈】详解 Maven 插件调试办法》,间接把 jar 包引入 idea 的 project classpath 即可。
  • 如果咱们须要调试阶段二的代码,那么,也分两种状况,须要改变代码,就去找源码,而后引入到 idea;同时,阶段一去找阶段二的时候,默认还是去了 %MAVEN_HOME%/lib/*.jar 下边去找,咱们这时候就得纠正它的错误行为,让它转而去咱们的源码工程下找阶段二的代码。
  • 如果须要调试阶段三的代码,如果须要改变,默认也是要引入插件的源码工程;然而,阶段二,去找插件代码的时候,要让它去咱们的源码工程下找代码是比拟艰难的(默认就是去本地仓库找,要纠正这个行为,难度较大),因而,就算了。咱们还是会引入插件的源码,然而,每次改了插件代码,手动部署到本地仓库就行。

咱们接下来,就开始实现下面的三个指标。

搭建阶段三的调试工程

大部分人可能感兴趣的还是插件代码,想本人搭着玩的,能够参考:《【曹工杂谈】详解 Maven 插件调试办法》

然而在这里,我还是须要基于我在 gitee 上新建的一个仓库,来给大家解说。后续的源码剖析文章(如果有的话)也会基于这个工程来解说。

代码在这里:https://gitee.com/ckl111/mave…

下边介绍下目录构造:

  • test-maven-core,用来在这个 module 的 pom 上,执行 mvn clean 等命令
  • plugin-sources,用来寄存插件的代码,后续的插件源码都会往这里放
  • plexus-classworlds-source,用来寄存阶段一的那个启动类的源码
  • 除此之外,都是 maven 框架自身的源码,这部分,统称为 maven core

下载了源码后,进行 idea 导入,导入时,抉择这个主目录下的 pom,这个 pom,就是框架外围的 pom,默认只会导入框架外围的 maven 工程;咱们还须要手动,把 test-maven-core、plugin-sources、plexus-classworlds-source 都导入一下(对着 pom 右键,Mark As Maven Project 即可)。

导入实现后,咱们默认会有 4 个 root maven 工程,其中,最下面的那个 Apache Maven,就是 maven 外围框架。

接下来,也简略了,如果不须要批改代码的话,那就能够在任意地位打断点了。打完断点,怎么触发呢,下边这样就行了。

我这边曾经 ok 了,你呢?

如果想批改插件代码,改完后,记得 mvn install 插件到本地仓库。

搭建阶段二的调试工程

如果大家只是想跟着代码 debug,那么,间接在 maven 框架对应的类上打断点就行了,下图就是在 maven core 这个 module 上打断点。

如果可能本人想改改 maven 源码、辅助学习的话,咱们就得动点心理。

在此之前,咱们须要把整个 maven 框架外围,先编译一次,因而,在 G:\gitee-projects\maven-3.8.1-source-learn(只是我这边的目录)下,执行:

mvn -DskipTests=true install

如果大家有报错,什么 rat 相干的,能够来这里:

把这个插件元素(<plugin> 元素)删掉。

我这边还遇到了 checkstyle 报错,同样,也在这个 pom 里,把 checkstyle 查看删掉。

最终呢,还是执行 ok 了。

下面这步 ok 后,在昨天的文章里《【曹工杂谈】Maven 和 Tomcat 能有啥分割呢,都穿打补丁的衣服吗》,咱们说了,maven 的启动类,是去下边这个中央,找 maven core 代码的:

F:\tools\apache-maven-3.8.1-bin\apache-maven-3.8.1\bin\m2.conf.

文件内容本来是这样的:

main is org.apache.maven.cli.MavenCli from plexus.core

set maven.conf default ${maven.home}/conf

[plexus.core]
load       ${maven.conf}/logging
optionally ${maven.home}/lib/ext/*.jar
load       ${maven.home}/lib/*.jar

其中,load ${maven.home}/lib/*.jar 就加载了 maven 的外围框架 jar。这个中央,咱们得改改,让它还得去咱们 idea 中源码工程下加载 class。

main is org.apache.maven.cli.MavenCli from plexus.core

set maven.conf default ${maven.home}/conf

[plexus.core]
load       ${maven.conf}/logging
optionally ${maven.home}/lib/ext/*.jar
load       G:\gitee-projects\maven-3.8.1-source-learn\maven-artifact\target\classes
load       G:\gitee-projects\maven-3.8.1-source-learn\maven-builder-support\target\classes
load       G:\gitee-projects\maven-3.8.1-source-learn\maven-compat\target\classes
load       G:\gitee-projects\maven-3.8.1-source-learn\maven-core\target\classes
load       G:\gitee-projects\maven-3.8.1-source-learn\maven-embedder\target\classes
load       G:\gitee-projects\maven-3.8.1-source-learn\maven-model\target\classes
load       G:\gitee-projects\maven-3.8.1-source-learn\maven-model-builder\target\classes
load       G:\gitee-projects\maven-3.8.1-source-learn\maven-plugin-api\target\classes
load       G:\gitee-projects\maven-3.8.1-source-learn\maven-repository-metadata\target\classes
load       G:\gitee-projects\maven-3.8.1-source-learn\maven-resolver-provider\target\classes
load       G:\gitee-projects\maven-3.8.1-source-learn\maven-settings\target\classes
load       G:\gitee-projects\maven-3.8.1-source-learn\maven-settings-builder\target\classes
load       G:\gitee-projects\maven-3.8.1-source-learn\maven-slf4j-provider\target\classes
load       ${maven.home}/lib/*.jar

也就是去咱们得 target 下加载 classes。

这样呢,咱们就能够改变咱们 idea 里导入的 maven 外围框架的代码,而后 compile 了,compile 后,class 进入到对应的 target 目录下,正好就在上文的 m2.conf 里的门路中。

为了验证是否失效,咱们轻易在 maven 外围框架打了个断点,看看以后类的类加载器的门路,发现的确曾经 ok 了。

搭建阶段一的调试工程

阶段一,也就是那个启动 jar 包,对应的源码在:

咱们只须要在启动测试工程里,把 classpath 指向这里的 target 目录,而不是 maven 装置目录下的 plexus-classworlds-2.6.0.jar 就能够了。

咱们把这段复制进去,而后把其中,指向 jar 包的替换掉:

-classpath "G:\gitee-projects\maven-3.8.1-source-learn\target;F:\tools\apache-maven-3.8.1-bin\apache-maven-3.8.1\boot\plexus-classworlds.license;C:\Program Files\JetBrains\IntelliJ IDEA 2021.1.1\lib\idea_rt.jar"

把这段贴到 maven 执行的参数中即可。

总结

汇总一下:

  1. 阶段一,指定 classpath 来调试咱们的源码工程:

    -classpath "G:\gitee-projects\maven-3.8.1-source-learn\target;F:\tools\apache-maven-3.8.1-bin\apache-maven-3.8.1\boot\plexus-classworlds.license;C:\Program Files\JetBrains\IntelliJ IDEA 2021.1.1\lib\idea_rt.jar"
  2. 阶段二,框架外围阶段,通过批改 maven 装置目录下的 m2.conf 的内容来实现
  3. 阶段三,插件源码阶段,批改源码后,通过编译部署到本地仓库后实现

我是逐日, 深圳腾讯打工人,成都深圳两地重复横跳的后端 java 程序猿一枚. 之前在深圳 3 年,起初去了成都 4 年,当初又来了深圳,也开始写写前端,有须要内推的能够找我。对于一线编码实战、网络、数据库、高并发等有浓厚兴趣。

也欢送加我,拉进技术群一起交换;腾讯内推也能够找我。

本文由博客一文多发平台 OpenWrite 公布!

正文完
 0