【曹工雜談】Maven源碼調試工程搭建


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/maven-3.8.1-source-learn

下邊介紹下目錄結構:

  • 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相關的,可以來這里:

把這個插件元素( 元素)刪掉。

我這邊還遇到了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. 階段三,插件源碼階段,修改源碼后,通過編譯部署到本地倉庫后實現


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM