遠程Debug Java進程的方法

原文地址java

遠程debug的意思是啓動一個Java進程,啓動一個debugger進程,將二者鏈接起來,利用debugger來debug Java進程。git

事實上目前全部的IDE的debug功能都是經過遠程debug方式來實現的,它們都利用了一個叫作JDPA(Java Platform Debugger Architecture)的技術。github

利用JDPA咱們除了可以在IDE開發的時候debug,也可以將IDE attach到一個生產環境上正在運行的Java進程作debug(事實上這兩個場景在本質上是同樣的)。web

下面會用兩個例子來講明如何使用Intellij IDEA來debug一個Java進程。apache

debug一個簡單的Java應用

咱們作了一個很簡單的Java應用,它啓動後會每隔2秒打印出一個不斷增加的數字。tomcat

源代碼在Github debug-simple-app網絡

  1. 執行mvn clean package打包
  2. 執行java -jar target/debug-simple-app.jar運行

如今咱們要用IDEA遠程Debug它。咱們先ctrl+c把進程中止掉。oracle

1)把項目導入到IDEA裏,由於若是沒有源碼的話咱們沒有辦法打斷點app

2)按照下面步驟新建一個Remote Run/Debug Configuration:socket

  1. 圖片描述
  2. 選擇Remote
    圖片描述
  3. 除了改個名字,設定Use module classpath,其他的選項不須要修改,直接用默認的就行
    圖片描述

    這裏解釋一下各類參數:

    Debugger mode:debugger的模式,有兩種:attach和listen。

    • attach的意思是debugger鏈接到被debug的Java進程,是主動式的。
    • listen的意思是debugger監聽由Java進程發送過來的通訊,是被動式的。

Host和Port的設定了被debug的Java進程的Host和Port,實際上這也告訴咱們,遠程Debug是經過網絡進行的。

JDK選項可根據你的不一樣JDK版原本構造不一樣的Command line arguments for remote JVM。

Command line arguments for remote JVM這個文本框你是不能修改的,它告訴了你若是要這個Java進程可以被遠程Debug,那麼必須添加這些參數才能夠。
因此你要把這裏的參數複製出來,後面會用得着。

Use module classpath,該選項設定使用那個module的源代碼來debug。

3)把剛纔的Command line arguments for remote JVM添加到剛纔的運行命令。

像這樣:java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -jar target/debug-simple-app.jar

4)點擊下圖裏的Debug按鈕開始debug

圖片描述

你會發現Console裏出現這麼一句話Connected to the target VM, address: 'localhost:5005', transport: 'socket'
這說明debugger已經attach成功了。

5)在debug-simple-app裏的代碼打個斷點看看效果。

debug一個tomcat應用

實際上debug一個tomcat應用和前面的例子沒有什麼大的區別。

咱們寫了一個很簡單的Servlet,它會返回Hello World以及被訪問的次數。

源代碼在Github debug-tomcat-app

  1. 執行mvn clean package打包
  2. target/debug-tomcat-app.war丟到tomcat
  3. 而後訪問http://localhost:8080/debug-tomcat-app/hello查看結果

如今咱們要用IDEA來debug,那麼先把tomcat停掉。

1)一樣須要把項目導入到IDEA裏

2)執行tomcat的bin/catalina.sh jpda start,讓tomcat能夠被debug

3)執行jps -v | grep Bootstrap找到Tomcat進程:

76905 Bootstrap -Djava.util.logging.config.file=... 
-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager 
-Djdk.tls.ephemeralDHKeySize=2048 
-Djava.protocol.handler.pkgs=org.apache.catalina.webresources 
-agentlib:jdwp=transport=dt_socket,address=localhost:8000,server=y,suspend=n 
-Dcatalina.base=... 
-Dcatalina.home=... 
-Djava.io.tmpdir=...

注意上面的-agentlib...address=localhost:8000參數,記住這個端口

4)和前面的例子同樣,新建一個Remote Run/Debug Configuration,把端口設定爲8000,而後啓動

5)而後打個斷點試試

若是你想改變Tomcat的端口怎麼作?看看bin/catalina.sh你會發現這麼一段註釋

JPDA_TRANSPORT  (Optional) JPDA transport used when the "jpda start"
                command is executed. The default is "dt_socket".

JPDA_ADDRESS    (Optional) Java runtime options used when the "jpda start"
                command is executed. The default is localhost:8000.

JPDA_SUSPEND    (Optional) Java runtime options used when the "jpda start"
                command is executed. Specifies whether JVM should suspend
                execution immediately after startup. Default is "n".

JPDA_OPTS       (Optional) Java runtime options used when the "jpda start"
                command is executed. If used, JPDA_TRANSPORT, JPDA_ADDRESS,
                and JPDA_SUSPEND are ignored. Thus, all required jpda
                options MUST be specified. The default is:

                -agentlib:jdwp=transport=$JPDA_TRANSPORT,
                    address=$JPDA_ADDRESS,server=y,suspend=$JPDA_SUSPEND

因此你只須要提供JPDA_ADDRESS環境變量參數就好了。好比這樣:JPDA_ADDRESS=5005 bin/catalina.sh jpda start

參考文檔

相關文章
相關標籤/搜索