天天看點

IDEA 進行遠端 Debug,這個太強了。。

正文

回到正題

說到遠端Debug這個功能,基本上大多IDE都會自帶,但是一般情況下還真是很少用,大概是因為...

IDEA 進行遠端 Debug,這個太強了。。

Just a joke😄,不要當真

筆者切換到IDEA之後,還真再就沒用過遠端Debug,直到昨天發現了一個非常基礎的錯誤...

坑從何來

坑來自于我的開源小工具:

https://gitee.com/vtDev/v-mock

筆者本意是打造一個,簡單,輕巧,一鍵運作的接口模拟系統,用來友善等待他人接口的前端後端同學。

基于以上目的,我使用了嵌入式資料庫sqlite,來配合Springboot,構造了無須配置,一行啟動的小jar包. 目錄結構如下,資料庫直接扔在了Resource中:

IDEA 進行遠端 Debug,這個太強了。。

開源後有使用的同學提了Bug,筆者也是正常操作,改完bug重新打版發行.

更新版本的同學,發現資料沒了,筆者暫時給出了方案,嵌入式資料庫嘛,把舊jar中的DB檔案,覆寫到新Jar中就好了

IDEA 進行遠端 Debug,這個太強了。。

(DB檔案位于jar包中的位置)

說出這句話的時候,也不能完全賴🧠瓦特了,畢竟Springboot+Sqlite這種奇葩組合也是為了工具的小巧性,偶爾嘗試的産物.

Spring Boot 基礎就不介紹了,推薦下這個實戰教程:

https://github.com/javastacks/spring-boot-best-practice

事實上稍微想想,db檔案和其他資源不一樣,是要頻繁改寫的,當然改動的不是jar包中的原始檔案.

直到收到了一個Issues,告訴了筆者DB檔案複制到新jar中并沒有生效.

筆者也迅速反應過來,怎麼可能用的jar内的DB檔案,真實檔案不出意外是放在java.io.tmpdir下了.

java.io.tmpdir的路徑,一般情況下,macos是在$TMPDIR,win則在%temp%.

筆者也切換到了對應的目錄,終于看到了jar運作時真實使用的DB檔案:

IDEA 進行遠端 Debug,這個太強了。。

但是這個命名方式很奇怪啊,和原本的v-mock.sqlite并不沾邊.

一路追随sqlite的jdbc驅動源碼,找到了org.sqlite.SQLiteConnection的extractResource方法,看到了命名代碼:

IDEA 進行遠端 Debug,這個太強了。。

其實看到這已經清晰了,源碼中使用了sqlite-jdbc-tmp拼接了原始jar中DB檔案的URL類的hashcode作為檔案名.

之是以筆者開發的時候沒注意到,看看這個方法第一個if判斷就知道了。

筆者習慣用IDE中的Springboot或者Application模式直接啟動項目,并不是打包後的啟動方式

是以當Protocol是file而不是jar的情況,直接就使用了target/classes/db/v-mock.sqlite檔案,不用生成臨時檔案.

開發時,DB可視化工具也連接配接的是target/classes/db/v-mock.sqlite,是以當時并沒發現疑點.

事實上這是很正常的操作,很多地方的源碼都有判斷是普通web環境還是以jar運作的,如果有這方面的調試,要思考你的啟動方式了.

那麼想把斷點打在第一個if之後,看到效果,選擇之一就是可以使用遠端Debug的方式。

IDEA的遠端Debug

IDEA的遠端Debug子產品真的是設計十分貼心,傻瓜操作,指令都生成好了,不知道現在的eclipse版本有沒有這麼貼心.

IDEA 進行遠端 Debug,這個太強了。。

從configuration中搜尋remote模版,點選右上角的create configuration,就建立好了一個遠端debug啟動方式.

Debugger mode選擇Attach to remote JVM即可,它還有一個選項是Listen to remote JVM,意如其名嘛,一個是主動附着到啟動的程式,一個是被動監聽程式。

ip和端口不用多說,筆者直接用的本地jar包,是以填了localhost,右邊jdk版本如果使用其他版本的,需要調一下。

中間的文本框就是生成好的jvm參數了,非常人性化了,直接加入啟動指令即可 java -jar -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 v-mock.jar

可以完全不用管指令什麼意思,如果你想知道,筆者也大概解釋一下:

-agentlib:jdwp 最重要的參數,啟動JDWP代理,JDWP全稱就是Java Debug Wire Protocol,官方給的友善調試的工具.

transport=dt_socket 通過socket方式傳輸資料,dt八成就是data transfer的縮寫了.

server=y 開啟調試server端,注意,因為筆者上文選擇的是Attach to remote JVM,是以這裡才是y,等待有調試器Attach過來,如果你選了Listen模式,那麼就是反過來的,調試器是server,這裡就是n了.

suspend=n 是否挂起,這裡設定為n,也就是說程式正常跑,什麼時候需要Attach就去Attach即可,如果設定為y,程式将會等待調試器Attach上才會繼續執行,比如啟動源碼的調試場景.

address=5005 調試端口設定為5005,當然其它端口也可以.

IDEA 進行遠端 Debug,這個太強了。。

啟動jar包,再以剛才建立的方式進行debug,期待的斷點位置已經成功到達了。