遠(yuǎn)程debug調(diào)試java代碼
日常環(huán)境和預(yù)發(fā)環(huán)境遇到問題時,可以用遠(yuǎn)程調(diào)試的方法本地打斷點(diǎn),在本地調(diào)試。生產(chǎn)環(huán)境由于網(wǎng)絡(luò)隔離和系統(tǒng)穩(wěn)定性考慮,不能進(jìn)行遠(yuǎn)程代碼調(diào)試。
整體過程是通過修改遠(yuǎn)程服務(wù)JAVA_OPTS參數(shù),然后本地通過Eclipse或IDEA等工具調(diào)試。
下面簡單介紹下理論。
理論
JPDA(Java Platform Debugger Architecture)是Java平臺調(diào)試體系結(jié)構(gòu)的縮寫。由3個規(guī)范組成,分別是JVMTI(JVM Tool Interface),JDWP(Java Debug Wire Protocol),JDI(Java Debug Interface) 。
1.JVMTI定義了虛擬機(jī)應(yīng)該提供的調(diào)試服務(wù),包括調(diào)試信息(Information譬如棧信息)、調(diào)試行為(Action譬如客戶端設(shè)置一個斷點(diǎn))和通知(Notification譬如到達(dá)某個斷點(diǎn)時通知客戶端),該接口由虛擬機(jī)實(shí)現(xiàn)者提供實(shí)現(xiàn),并結(jié)合在虛擬機(jī)中
2.JDWP定義調(diào)試服務(wù)和調(diào)試器之間的通信,包括定義調(diào)試信息格式和調(diào)試請求機(jī)制
3.JDI在語言的高層次上定義了調(diào)試者可以使用的調(diào)試接口以能方便地與遠(yuǎn)程的調(diào)試服務(wù)進(jìn)行交互,Java語言實(shí)現(xiàn),調(diào)試器實(shí)現(xiàn)者可直接使用該接口訪問虛擬機(jī)調(diào)試服務(wù)。 java調(diào)試工具jdb,就是sun公司提供的JDI實(shí)現(xiàn)。eclipse IDE,它的兩個插件org.eclipse.jdt.debug.ui和org.eclipse.jdt.debug與其強(qiáng)大的調(diào)試功能密切相關(guān),其中前者是eclipse調(diào)試工具界面的實(shí)現(xiàn),而后者則是JDI的一個完整實(shí)現(xiàn)。
遠(yuǎn)程調(diào)試
遠(yuǎn)程調(diào)試分為主動連接調(diào)試,和被動連接調(diào)試。這里以Eclipse為例。
主動連接調(diào)試:服務(wù)端配置監(jiān)控端口,本地IDE連接遠(yuǎn)程監(jiān)聽端口進(jìn)行調(diào)試,一般調(diào)試問題用這種方式。
被動連接調(diào)試:本地IDE監(jiān)聽某端口,等待遠(yuǎn)程連接本地端口。一般用于遠(yuǎn)程服務(wù)啟動不了,啟動時連接到本地調(diào)試分析。
主動連接調(diào)試
首先需要遠(yuǎn)程服務(wù)配置啟動腳本:
JAVA_OPTS="$JAVA_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000"
如果是啟動jar包,指令:
java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000 -jar test.jar?
這里-Xdebug是通知JVM工作在DEBUG模式下,-Xrunjdwp是通知JVM使用(java debug wire protocol)來運(yùn)行調(diào)試環(huán)境。transport是監(jiān)聽Socket端口連接方式(也可以dt_shmem共享內(nèi)存方式,但限于windows機(jī)器,并且服務(wù)提供端和調(diào)試端只能位于同一臺機(jī))。server=y表示當(dāng)前是調(diào)試服務(wù)端,=n表示當(dāng)前是調(diào)試客戶端。suspend=n表示啟動時不中斷(如果啟動時中斷,一般用于調(diào)試啟動不了的問題)。address=8000表示本地監(jiān)聽8000端口。
遠(yuǎn)程服務(wù)(tomcat/jboss)啟動成功后,本地Eclipse對需要調(diào)試的地方打上斷點(diǎn),然后項(xiàng)目右鍵啟動遠(yuǎn)程調(diào)試:Debug as->Debug Configurations->Remote Java Application。Host為遠(yuǎn)程主機(jī)IP,Port為遠(yuǎn)程監(jiān)聽調(diào)試端口,Connection Type為:Standard(Socket Attach),如圖:

點(diǎn)擊Debug,然后打斷點(diǎn),遠(yuǎn)程服務(wù)運(yùn)行到斷點(diǎn)處本地就會中斷,然后進(jìn)行調(diào)試。
被動連接調(diào)試
首先需要Eclipse配置監(jiān)聽,如主動連接調(diào)試的Eclipse配置圖片,Connection Type選擇:Standard(Socket Listen),配置本地監(jiān)聽端口,比如默認(rèn)8000。點(diǎn)擊Debug開始等待遠(yuǎn)程連接調(diào)試。
然后配置遠(yuǎn)程服務(wù)啟動腳本:
JAVA_OPTS="$JAVA_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,address=127.0.0.1:8000,suspend=y"
如果是調(diào)試jar包,指令:
java -Xdebug -Xrunjdwp:transport=dt_socket,address=127.0.0.1:8000,suspend=y -jar remoting-debug.jar
參數(shù)含義和主動連接調(diào)試一樣,只是這里suspend=y表示啟動時就中斷,需要連接本地IDE調(diào)試啟動。address=ip:port,ip需要修改為本地的對外IP。
這樣遠(yuǎn)程項(xiàng)目啟動時就連接到本地,方便調(diào)試項(xiàng)目啟動不了的問題。
總結(jié)
另外除了在啟動腳本如上配置外,還可以用這種方式配置:
啟動時:sh catalina.sh jpda start。修改啟動時是否中斷或本地監(jiān)聽端口,設(shè)置變量值:JPDA_SUSPEND=y JPDA_ADDRESS=9999。