老問題了:idea中使用maven archetype新建項目時卡住

背景

作爲一個後端Java打工人,idea就是最重要的打飯工具。創建項目,熟悉吧,但是,這麼多年下來,因爲idea換了版本,電腦換了等等,我還是時不時遇到根據maven archetype新建maven項目卡住。沒錯,我說的就是下面這樣的場景:

image-20230818220009447

image-20230818220115722

總之吧,就是停在上面這裏,不動了:

[INFO] --- maven-archetype-plugin:3.2.1:generate (default-cli) @ standalone-pom ---
[INFO] Generating project in Batch mode

以前都是網上隨便找個文章搞一搞,或者有時候多等一會,解決了也就不管了,直到下次因爲換電腦、重裝idea等等,又不行了。我也奇怪,你拿Generating project in Batch mode去網上一搜,出來的解決辦法還各不相同。

這次我決定好好探究下,瞭解下內部原理,知其然,也要知其所以然,把這個小問題搞清楚。

打開debug級別參數,查看阻塞原因

首先,點這裏,可以看到完整命令:

image-20230818220715248

基本就是:

"C:\Program Files\Java\jdk1.8.0_202\bin\java.exe" 
-Dmaven.home=F:\tools\apache-maven-3.8.1-bin\apache-maven-3.8.1  
--errors
-DgroupId=org.example
-DartifactId=test8
-Dversion=1.0-SNAPSHOT

-DarchetypeGroupId=org.apache.maven.archetypes
-DarchetypeArtifactId=maven-archetype-quickstart
-DarchetypeVersion=1.4

-DarchetypeRepository=F:/maven/repository

org.apache.maven.plugins:maven-archetype-plugin:RELEASE:generate

可以看下上面的命令,我已經去除了不重要的參數,剩下的分幾個部分:

  • maven home目錄
  • 日誌級別,目前是-errors,不會打印太詳細的日誌
  • -DgroupId/-DartifactId/-Dversion 我們要生成的業務module的座標
  • -DarchetypeGroupId/-DarchetypeArtifactId/-DarchetypeVersion module模版/原型的座標
  • -DarchetypeRepository module模版/原型的本地倉庫位置
  • org.apache.maven.plugins:maven-archetype-plugin:RELEASE:generate 丟給maven的執行參數,表示要執行的插件及目標

上面這裏,日誌級別是比較高的,我們需要調低,怎麼調呢,通過idea的settings即可:image-20230818221451851

打開debug級別後,再次運行,命令裏就會多出一個:--debug參數,而運行時就會出現如下日誌:

	![image-20230818221704629](https://dump-1252523945.cos.ap-shanghai.myqcloud.com/img/202308182217713.png)

日誌顯示正在獲取某個xml文件。

這個文件的url已經給出來了,網上都是說,文件特別大,可以自己瀏覽器下載下來,放到某個位置,然後再改個參數-DarchetypeCatalog=local,後續讓maven都從這個位置去讀即可。

我看了下,這個文件確實大,14M左右,而且是從maven官方倉庫那小水管下載,確實要卡很久,文件是幹啥的呢,catalog表示目錄,合起來意思就是項目模版的目錄,比如我們常用的quickstart,只是其中的一個:

-DarchetypeGroupId=org.apache.maven.archetypes
-DarchetypeArtifactId=maven-archetype-quickstart
-DarchetypeVersion=1.4

文件內容大概如下,整個文件包含了5w多個模板,這麼多,能不慢嗎:

image-20230818223322663

image-20230818223432985

一個疑問

按照網上的方案,我把文件下載下來了,但我還不知道把文件放到哪裏去。

我想着,我先把參數-DarchetypeCatalog=local改了,看看debug日誌,在local參數情況下,是去哪裏獲取這個文件:

image-20230818223623549

然後,注意啊,敲黑板了!rerun的話,這個參數是不生效的,必須新建project或module,這個參數纔會生效,也就是說,之前建的都沒效果,僅對新project、module生效。

image-20230818223920206

此時,如下,它會去本地倉庫的根目錄下查找這個目錄文件:

image-20230818224159385

ok,知道去哪裏放這個目錄文件了,問題是,我還沒放呢,但它這次執行爲啥就成功了呢?

image-20230818224430566

雖然成功了,但是給我整得有點迷茫,不知道怎麼就成功了。我以爲是idea有什麼緩存,我還重啓了幾次idea,後來發現應該就是這樣設計的:

加了-DarchetypeCatalog=local的情況下,會在本地的本地倉庫下找archetype-catalog.xml。但我們沒放,所以找不到。找不到的話,它也就放棄了,會直接去maven中央倉庫拉取這個指定模版的jar下來。

[DEBUG] Getting archetypes from catalog: F:\maven\repository\archetype-catalog.xml
// 下面這行,意思是容錯處理,去中央倉庫拉取
[WARNING] Archetype not found in any catalog. Falling back to central repository.

拉取下來的模版/原型的內容

我們前面提到,模版的座標爲:

-DarchetypeGroupId=org.apache.maven.archetypes
-DarchetypeArtifactId=maven-archetype-quickstart
-DarchetypeVersion=1.4

拉取下來後,我們看看其內容:

image-20230818225230149

jar包解壓後,發現很眼熟,就是我們模板項目的內容:

image-20230818225400014

打開其中兩個文件查看,發現還有不少佔位符:

image-20230818225611178

image-20230818225619818

下面這個App.java的$package佔位符,我們在命令裏沒有顯式傳遞,是maven獲取了-DgroupId=com.example的值作爲其默認值。

所以,解決本問題的方法,就是在maven的runner加上參數-DarchetypeCatalog=local就可以了,不需要下載xml文件再放到指定目錄。

如果我們放置的話呢,看看日誌是啥樣:

[INFO] Generating project in Batch mode
[DEBUG] Getting archetypes from catalog: F:\maven\repository\archetype-catalog.xml
[INFO] Archetype repository not defined. Using the one from [org.apache.maven.archetypes:maven-archetype-quickstart:1.4] found in catalog local

瞭解該插件

https://maven.apache.org/archetype/maven-archetype-plugin/

image-20230818230444710

我也是才知道,還可以根據現在已有的項目來生成模版,感覺還是不錯的,後面打算研究下,畢竟公司內項目一多,在項目間需要複用的東西就越來越多,搞個模版工程還是不錯的。

該插件的goal:generate

我們上面使用的就是該插件的generate 目標:

https://maven.apache.org/archetype/maven-archetype-plugin/generate-mojo.html

這裏就有各個參數的解釋,這也是爲什麼網上文章都讓我們這麼改參數的原因:

image-20230818230727608

mvn命令如何執行該插件

 mvn archetype:generate  
 -DarchetypeGroupId=org.apache.maven.archetypes
 -DarchetypeArtifactId=maven-archetype-quickstart
 -DarchetypeVersion=1.1 
 
 -DgroupId=com.company
 -DartifactId=project
 -Dversion=1.0-SNAPSHOT
 -Dpackage=com.company.project
 
 -X --errors -DarchetypeCatalog=local

這裏-X,就和表示前面idea中的debug級別日誌是一樣的,具體可查看mvn -h:

 -X,--debug                             Produce execution debug output

另外,注意這裏,指定了-Dpackage,即手動指定了我們module的包名。

總結

魔鬼藏於細節,但我們不要放過細節。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章