在 IntelliJ IDEA 中远程调试 Java 程序
在 IntelliJ IDEA 中遠程調(diào)試 Java 程序
- 說明
- IntelliJ IDEA 遠程調(diào)試的原理
- 使用 IntelliJ IDEA 遠程調(diào)試原始 Java 程序的步驟
說明
- 本文的遠程調(diào)試對象以運行在 Linux 上的 Java 程序為例。
IntelliJ IDEA 遠程調(diào)試的原理
??遠程調(diào)試指的是使用本地客戶端來調(diào)試運行在遠程服務(wù)器上的程序。IntelliJ IDEA 遠程調(diào)試的原理是,當(dāng)服務(wù)器端以調(diào)試模式運行 Java 程序時,如果客戶端使用文本相同的字節(jié)碼和事先約定好的端口號,就可以遠程調(diào)試該 Java 程序。因此,IntelliJ IDEA 遠程調(diào)試的必要條件是:
-
Java 程序必須在服務(wù)端已經(jīng)啟動且在調(diào)試時正在運行。IntelliJ IDEA 只有觸發(fā)調(diào)試的能力,沒有遠程部署啟動 Java 程序的能力。
-
Java 程序在服務(wù)端以調(diào)試模式啟動。以調(diào)試模式啟動需要在運行該 Java 程序時,使用一些調(diào)試模式的 JVM 參數(shù)。
-
客戶端使用 IntelliJ IDEA 進行調(diào)試時,使用與服務(wù)端事先約定好的相同端口號,且該端口號在服務(wù)端沒有被占用。
-
客戶端使用 IntelliJ IDEA 進行調(diào)試時,使用的代碼在文本上與服務(wù)端一致。在文本上一致指的是,客戶端使用的代碼與服務(wù)端使用的代碼的文字完全相同,如果不一致,使用的斷點將不起作用。文本上一致不包括注釋,但包括換行。文本上一致不需要是同一個代碼源文件,只需要文本相同即可。
??使用 IntelliJ IDEA 進行遠程調(diào)試的注意事項:
-
IntelliJ IDEA 只有觸發(fā)調(diào)試的能力,沒有遠程部署啟動 Java 程序的能力。只能自己先確保 Java 程序可以在服務(wù)端基本運行之后才能在客戶端使用遠程調(diào)試,無法通過 IntelliJ IDEA 來直接利用服務(wù)端的環(huán)境運行 Java 代碼。
-
在遠程調(diào)試時,程序是在服務(wù)端運行的,與客戶端沒有任何關(guān)系,產(chǎn)生的數(shù)據(jù)對客戶端不會有任何影響。
-
代碼在文本上與服務(wù)端一致 僅指代碼相同。文本上一致不包括注釋,但包括換行。文本上一致不需要是同一個代碼源文件,只需要文本相同即可。也不需要約定 JAR 包名,但需要使用同一標(biāo)識的應(yīng)用。
-
在 IntelliJ IDEA 的代碼中打斷點不需要在調(diào)試之前打斷點,只需要在程序運行到此斷點之前打即可。一般部署在服務(wù)端的應(yīng)用都是一個無限循環(huán)的應(yīng)用,同一處代碼會不斷地運行。因此一般可以在調(diào)試時的任何時候打斷點。
-
一旦在客戶端的 IntelliJ IDEA 中觸發(fā)了斷點,在服務(wù)端運行的 Java 程序會立刻被暫停運行,且受客戶端的 IntelliJ IDEA 所控制。
??IntelliJ IDEA 遠程調(diào)試有兩種模式,一種是 attach,另一種是 listen。attach 指的是服務(wù)端的 Java 程序已經(jīng)運行,使用 IntelliJ IDEA 立即進行調(diào)試。listen 指是服務(wù)端的 Java 程序可能還沒有運行,現(xiàn)在正在監(jiān)聽在服務(wù)端的該端口,直到服務(wù)端的 Java 程序啟動了再觸發(fā)調(diào)試。本文使用的是 attach 模式。
使用 IntelliJ IDEA 遠程調(diào)試原始 Java 程序的步驟
筆者的運行環(huán)境:
- 客戶端:
- IntelliJ IDEA 2020.1.2 (Ultimate Edition)
- Windows 10 教育版
- Xshell 7.0.0014
- Xftp 7
- 服務(wù)器:
- CentOS Stream 8
- Java 11.0.12
為了方便遠程輸入命令、將文件加入到 Linux 操作系統(tǒng)中,最好還要在一臺 Windows 操作系統(tǒng)上面使用一種終端控制軟件,如 Xshell、Xftp 等。關(guān)于這方面的內(nèi)容,可見筆者的另一篇如下博客。同時,該博客還給出了查看 Linux 中的 IP 的方法:
如何在 Windows 主機上訪問本地局域網(wǎng)中的 Linux 主機:
https://blog.csdn.net/wangpaiblog/article/details/120052152?spm=1001.2014.3001.5502
現(xiàn)在,假設(shè)讀者已經(jīng)會了如何將文件從 Windows 中傳入 Linux 中,以及查看 Linux 中的 IP。
為了方便說明,筆者編寫了一個傻瓜的 Java 程序。此 Java 程序是在本地的客戶端中的 IntelliJ IDEA 中完成編寫的。示例代碼如下:
以下代碼的簡單解釋:
- 以下為無限循環(huán)延時代碼。間隔時間為 1 秒,每秒會打印循環(huán)的圈數(shù)。
- 使用無限循環(huán)的原因是,為了確保進行遠程調(diào)試時,遠程程序依然處于運行的狀態(tài)。
- 無需為無限循環(huán)而擔(dān)心,因為這里是阻塞型程序,在 CMD 中運行時,使用 ctrl + C 即可立刻終止該程序。
在 IntelliJ IDEA 中進行遠程調(diào)試的相關(guān)配置。如下圖所示進行操作。
如下圖所示進行操作。注意復(fù)制圖中的 JVM 代碼,這將在之后在服務(wù)端用于以調(diào)試模式啟動本程序。
筆者示例中約定的端口號為 5005,JVM 代碼為:
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005在本地客戶端制作 JAR 包。
如果讀者沒使用 Maven 等構(gòu)建工具,打包的方法可見筆者的另一篇博客:
不使用 Maven 等構(gòu)建工具,而使用原始方法在 IntelliJ IDEA 中制作 JAR 包:
https://blog.csdn.net/wangpaiblog/article/details/120359856?spm=1001.2014.3001.5501
如果讀者使用了 Maven,則 Maven 下打包的方法可見筆者的另一篇博客:
將 Maven 中的多模塊項目只打成一個 JAR 包:
https://blog.csdn.net/wangpaiblog/article/details/119628194
得到 JAR 包之后,可以使用 Xftp 將其上傳到服務(wù)器端的 Linux 中。
對于很多 Linux 系統(tǒng),此時還不能直接進行遠程調(diào)試,因為 Linux 上有防火墻,默認(rèn)會阻止所有的遠程訪問。對于筆者的 CentOS Stream 8 x86_64,默認(rèn)的防火墻為 firewalld,而不是 iptables。(很多人會選擇安裝 iptables,但偷懶的筆者沒有選擇這樣做。)
-
一個偷懶的方法就是,永久地關(guān)閉防火墻。關(guān)閉的方法如下:
systemctl stop firewalld
systemctl mask firewalld
firewall-cmd --reload
-
另一個方法是,在防火墻中永久開放上述約定的端口號 5005。開放的方法如下:
firewall-cmd --zone=public --add-port=5005/tcp --permanent
firewall-cmd --reload
單獨開放完端口 5005 之后,可以輸入以下命令查看是否生效:
firewall-cmd --zone=public --query-port=5005/tcp
[root@localhost temp]# firewall-cmd --zone=public --query-port=5005/tcp yes實際上,也可以輸入以下命令查看所有開放的端口:
firewall-cmd --zone=public --list-ports
[root@localhost temp]# firewall-cmd --zone=public --list-ports 5005/tcp
進入上述 JAR 包的目錄。假設(shè)上面上傳的 JAR 包名為 demo.jar。整合前面復(fù)制的 JVM 代碼,輸入以下命令來運行此 demo 程序。
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005 -jar demo.jar可以看到,前面的無限循環(huán)程序開始運行了。
現(xiàn)在就可以在本地客戶端的 IntelliJ IDEA 進行遠程調(diào)試了。
如果遠程調(diào)試成功。在服務(wù)器端運行的上述 Java 程序會立刻被暫停運行。而在 IntelliJ IDEA 的調(diào)試控制臺 Console 中會有如下顯示:
最后,記得去服務(wù)器端使用 ctrl + C 終止上述 demo 程序。
盡管很多讀者認(rèn)真閱讀了筆者的教程,但現(xiàn)實中仍然可能出現(xiàn)很多調(diào)試失敗的例子。當(dāng)讀者遠程調(diào)試失敗的時候,還請再回去看筆者本文前面寫的 IntelliJ IDEA 遠程調(diào)試的原理,不過這里也再提幾點:
-
如果遠程服務(wù)端的 Java 程序沒有啟動,這是一定會調(diào)試失敗的。因為如果遠程服務(wù)端的 Java 程序沒有啟動,則遠程服務(wù)端的端口號會不存在。(這與有沒有在防火墻對外開放端口號權(quán)限無關(guān)。如果遠程服務(wù)端的 Java 程序沒有啟動,就會連端口號都沒有,開放端口號權(quán)限也沒用。)
-
如果想知道遠程服務(wù)端的端口號有沒有生成,可以在遠程服務(wù)端輸入以下命令:(如果運行的程序阻塞了當(dāng)前的 Shell 窗口,可以在 Xshell 中另開一個 Shell 窗口。)
netstat -na | grep 5005
[root@localhost ~]# netstat -na | grep 5005 tcp 0 0 0.0.0.0:5005 0.0.0.0:* LISTEN -
如果想知道本地客戶端能不能連接遠程的端口號,可以在本地客戶端輸入以下命令:
ssh -v -p 5005 192.168.0.100
以筆者在 Windows 的 CMD 中,訪問 Linux 的端口號 5005 為例。
如果訪問成功,輸出信息為:
C:\Users\XXXXX>ssh -v -p 5005 192.168.0.100 OpenSSH_for_Windows_7.7p1, LibreSSL 2.6.5 debug1: Connecting to 192.168.0.100 [192.168.0.100] port 5005. debug1: Connection established. debug1: identity file C:\\Users\\XXXXX/.ssh/id_rsa type 0 debug1: key_load_public: No such file or directory debug1: identity file C:\\Users\\XXXXX/.ssh/id_rsa-cert type -1 debug1: key_load_public: No such file or directory debug1: identity file C:\\Users\\XXXXX/.ssh/id_dsa type -1 debug1: key_load_public: No such file or directory debug1: identity file C:\\Users\\XXXXX/.ssh/id_dsa-cert type -1 debug1: key_load_public: No such file or directory debug1: identity file C:\\Users\\XXXXX/.ssh/id_ecdsa type -1 debug1: key_load_public: No such file or directory debug1: identity file C:\\Users\\XXXXX/.ssh/id_ecdsa-cert type -1 debug1: key_load_public: No such file or directory debug1: identity file C:\\Users\\XXXXX/.ssh/id_ed25519 type -1 debug1: key_load_public: No such file or directory debug1: identity file C:\\Users\\XXXXX/.ssh/id_ed25519-cert type -1 debug1: key_load_public: No such file or directory debug1: identity file C:\\Users\\XXXXX/.ssh/id_xmss type -1 debug1: key_load_public: No such file or directory debug1: identity file C:\\Users\\XXXXX/.ssh/id_xmss-cert type -1 debug1: Local version string SSH-2.0-OpenSSH_for_Windows_7.7 ssh_exchange_identification: read: Connection reset如果訪問不成功,輸出信息為:
C:\Users\XXXXX>ssh -v -p 5005 192.168.0.100 OpenSSH_for_Windows_7.7p1, LibreSSL 2.6.5 debug1: Connecting to 192.168.0.100 [192.168.0.100] port 5005. debug1: connect to address 192.168.0.100 port 5005: Connection refused ssh: connect to host 192.168.0.100 port 5005: Connection refused -
如果本地 IntelliJ IDEA 中沒有使用前述的 在文本上一致 的代碼,而其它正確,則遠程調(diào)試會成功,但斷點會打不了(斷點不生效)。
總結(jié)
以上是生活随笔為你收集整理的在 IntelliJ IDEA 中远程调试 Java 程序的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 不使用 Maven 等构建工具,而使用原
- 下一篇: Java 13 的下载安装教程