文章前半部分是分析過程摹察,不想看的直接拉到"重點部分"
在學(xué)習(xí)SpringBoot的時候了解到汽久,spring-boot-maven-plugin打包生成的jar包中包含了工程需要的依賴,所以這樣的jar包可以直接運(yùn)行虏两。但是工程自身是不依賴spring-boot-loader等啟動類的(實際上spring-boot-maven-plugin插件依賴了這些啟動類的jar包峭沦,所以打包的時候可以將這些jar從遠(yuǎn)程倉庫下載并進(jìn)行repackage)扫皱。
SpringBoot插件打包生成的這種fat jar可以直接運(yùn)行治拿,最重要的一點是它實現(xiàn)了jar in jar的加載方式摩泪,這種fat jar的啟動類是org.springframework.boot.loader.JarLauncher,我一開始想試著在IDEA中debug JarLauncher這個啟動類來學(xué)習(xí)下加載原理劫谅,但是當(dāng)我以Application形式來啟動的時候(此時我已經(jīng)在dependency中依賴了spring-boot-loader)见坑,即使選了Main class,也會提示出錯同波。
會提示找不到Start-Class鳄梅,因為沒有manifest文件叠国。
后來我找到兩種方法未檩,均是用jdb命令在命令行進(jìn)行debug
- 解壓fat jar,直接運(yùn)行
jdb org.springframework.boot.loader.JarLauncher
粟焊,然后設(shè)置斷點冤狡,敲命令debug - 參考這篇文章jdb調(diào)試運(yùn)行本地jar包孙蒙,通過
jdb -attach
的命令來遠(yuǎn)程控制jar的啟動,然后仍舊敲命令debug
但是由于沒有IDE的可視化環(huán)境悲雳,用以上兩種方法debug的效率非常低下挎峦,然后我就想,IDEA既然有遠(yuǎn)程debug的功能合瓢,估計底層也是用jdb命令來實現(xiàn)的坦胶,所以我就想?yún)⒖嫉诙N方法,先啟動jar晴楔,然后通過IDEA的remote方式來debug顿苇,沒想到無意中發(fā)現(xiàn)IDEA竟然還支持JAR Application的形式進(jìn)行debug,這樣就簡單多了税弃。
重點部分
配置好Jar Application需要的一些參數(shù)纪岁,jar包的路徑,搜索類文件的路徑即工程路徑(見下圖)则果;
然后再在工程的pom文件中引入spring-boot-loader的依賴(因為IDEA會在工程里查找源文件幔翰,所以必須主動引入才行)员帮,在JarLauncher類上打上斷點周拐,就可以愉快地進(jìn)行debug了。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-loader</artifactId>
</dependency>
補(bǔ)上用remote的方式debug spring-boot-loader的啟動源碼
解壓打包好的jar包帝洪,進(jìn)入加壓后的目錄款青,以如下命令直接運(yùn)行org.springframework.boot.loader.JarLauncher啟動類java -agentlib:jdwp=transport=dt_socket,server=y,address=8000 org.springframework.boot.loader.JarLauncher
贡定,(每個參數(shù)的含義可以通過java -agentlib:jdwp=help
命令查看),然后在idea中配置remote運(yùn)行模式即可可都,Host為127.0.0.1缓待,Port為8000即可,見下圖: