前言
今年的更新頻率簡直是降至冰點了,一方面平時加班相對多一些了,下班只想玩手機;另一方面,好像進了大廠後,學習動力也很低了,總之就,很懶散,部落格的話,今年都才只更新了不到5篇。
現在慢慢有一點狀態,開始學點技術;今天這篇就是講maven外掛,為啥會折騰這個,公司內有個mybatis generator,針對公司內部做了一些定製開發,具體內容不知道,但是,有個很蛋疼的問題,在根據資料庫表,反向生成po的時候,不能把資料庫表的欄位的註釋,給生成為po的field 註釋。
之前試過自己折騰一下,解決這個問題,但是實在不瞭解maven外掛這塊,因此一直就忍了將就用,大不了就沒有註釋嘛;前幾個月就把maven原始碼下載下來了,但是原始碼裡一堆的單元測試,卻一直不知道怎麼像我們平時使用的方式那樣去debug,最後就三天打魚兩天曬網地瞎看,效果很差,看了多少就忘多少,最近才把debug外掛的方式折騰ok,這裡就分享給大家。
下邊正文。
越是複雜的開源專案,裡面用到的maven外掛就越多,一個pom,大幾百行是常事,經常呢,大家都是隻知道怎麼配置,或者說,不知道怎麼配置,需要改配置的時候,就一頓猛搜,經常網上搜出來的,可能還因為版本不匹配發生“他文章裡可以,我這邊為啥不行”。
反正,總結一句話,maven外掛很多時候,對大家來說,就是一個黑盒。
而我們恰恰不太能忍受黑盒,當然了,像什麼jvm那種c++寫的黑盒就算了,讓人頭禿。
另外,可以再給大家一個看這篇文章的理由,就問你一個問題:spring boot是怎麼打包成fat jar,又是怎麼從一個fat jar啟動的?
是吧,這裡的答案就在spring boot的maven外掛裡了。今天我們肯定不會那麼複雜,搞個clean外掛學習下,就ok了。
怎麼單行除錯一個外掛的原始碼呢
建立演示工程
我們需要一個maven的project,最終弄完,我這邊樣子是這樣的:
下邊是步驟:直接像下面這樣生成一個,然後next結束:
為了方便演示,我們pom.xml裡,刪除了
<?xml version="1.0" encoding="UTF-8"?>
<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>
<groupId>org.example</groupId>
<artifactId>test-project</artifactId>
<version>1.0-SNAPSHOT</version>
<name>test-project</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
</build>
</project>
大家看上面這個pom,很乾淨,會不會以為這樣就沒有配置外掛了呢,不是的,預設的,就會給我們的maven的生命週期繫結一些外掛,比如在clean階段繫結maven-clean-plugin外掛。可以看我下圖,可以看到這裡還是有好幾個外掛的,為了力求簡單好理解,我們關注clean外掛,我這邊是2.5版本,大家對於版本號不用糾結,可能不同的idea版本出來的會有差異。
除錯clean外掛
怎麼除錯呢,首先得觸發maven的clean外掛執行,是吧?怎麼觸發執行呢?
如何觸發執行clean外掛
針對這種命令很簡單的,不需要給外掛傳引數的命令,直接上圖這樣就可以觸發除錯執行。
大家來看看執行效果:
上面這一串,看起來很長,其實很多都是-D指定的SystemProperty和classpath,最終呢,其實就是java -main類 -args的格式。
這裡的引數就是"clean:clean"。
去哪裡打斷點
有人開始問了,你不是說除錯嗎,這都一把跑完了啊,再說了,我想打斷點去哪裡打呢?
ok,要打斷點,我們得知道,mvn clean肯定會執行到的那個方法,然後才能在那裡提前打斷點埋伏,就好像我們總是知道,程式執行,會進入main方法一樣。
而mvn clean,一定會執行到clean外掛中的CleanMojo這個class(這部分知識算是需要提前瞭解的部分):
要除錯這個類,必須得在當前的project(idea裡,一個project包含多個module)裡,能找到這個class。在idea裡,老子上來就是double shift,
看起來,找不到這個類啊,還怎麼玩?最簡單的辦法是,先直接把這個jar包加到project裡面,
新增到libraries裡:
加的時候,會提示你,要不要加入到當前這個project,要選:yes。加了後,就可以看到:
老子抬手又是doubel shift,可以看到,這個cleanMojo已經存在了。
既然存在了,接下來就是打斷點:
繼續觸發執行debug
可以看到,已經成功停在了我們的斷點上,接下來單步除錯就行。但是哈,大家也注意到,我們這邊因為是打在反編譯的class上的,而反編譯的class呢,肯定沒有原始碼那麼舒服的,這個問題呢,也簡單,等我循序漸進來講。
去哪裡打斷點--方式2
我們下邊這個方式,當然是想辦法在原始碼上打斷點,原始碼去哪裡獲取?
https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-clean-plugin/2.5
原始碼下載下來後,我嘗試了下圖這樣的方式(就是在前面方案的基礎上,把原始碼附上了):
這種方式,打個斷點,看看:
這個方式是可以除錯外掛本身那幾個java檔案,但是外掛依賴的那些,就還是有問題,這種方式吧,雞肋。
去哪裡打斷點--最推薦的方式
我們還是不搞那些有的沒的了,來官方的外掛開發地址拉程式碼:
https://maven.apache.org/scm.html
下載後解壓,發現是個maven工程,舒服了。直接匯入idea。匯入後,我們打好了斷點,下邊開始,跑一波debug。
可以看到,這把舒服了,確確實實,除錯的是原始碼了。但是,這裡提醒一下,不要想著去改程式碼,如果直接改,改了肯定就class和java原始碼的行號,對應不上了,至於為什麼,這是一個值得大書特書的故事了,留待後續。
擴充套件
前面我們說的,觸發maven clean執行,是用的這種方式。
實際上,這種只能應付簡單場景,不需要傳參什麼的,複雜場景還是需要像下面這樣:
比如,我們公司的那個mybatis 生成器:
就會指定很多引數,比如對應的配置檔案的位置,對吧。