標籤:jpda run put for 編譯器 import runtime xdebug exce
本節嘗試一下Java遠端偵錯的東西,記錄一遍簡單入門的東西。也就算是使用記錄吧!
寫一個簡單程式打成jar丟到遠程伺服器運行,類比遠程Server在運行。就拿Java調用shell指令碼提交作業程式為例分析。源碼如下(如下程式就是一個簡單範例程式碼,不要在乎代碼規範):
import java.io.InputStream;public class JavaShell { public static void main(String[] args) throws Exception { try { String grant = "chmod u+x submit-job.sh"; Runtime runtime = Runtime.getRuntime(); Process grantProc = runtime.exec(grant); int resultCode = grantProc.waitFor(); System.out.println(resultCode); grantProc = runtime.exec("./submit-job.sh"); resultCode = grantProc.waitFor(); System.out.println(resultCode); InputStream in = grantProc.getInputStream(); byte[] buffer = new byte[1024]; int code; while ((code = in.read(buffer, 0, buffer.length)) != -1) { System.out.print(new String(buffer, 0, code)); } /** * 死迴圈阻止debugger沒有串連上之前程式退出(測試suspend參數功能) */ System.out.println("shell指令碼執行完畢,接下來開始進行定時列印任務!"); int i = 0; while (true) { Thread.sleep(2000); System.out.println("這是第" + (++i) + "次迴圈!"); } } catch (Exception e) { System.out.println("this is a excption !"); } finally { } }}
打成Jar包提交到遠程伺服器之後運行:
java -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=9999,server=y,suspend=y -jar JavaShell.jar
會發現程式阻塞,並等待debugger串連,此時我們可以使用eclipse進行遠端偵錯:
點擊debugger即可進行串連,跟蹤源碼運行:
遠程有輸出,證明遠程程式正在跟蹤debugger執行:
到此我們就完成了調試的過程。接下來試一下參數suspend=n的情況:
java -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=9999,server=y,suspend=n -jar JavaShell.jar
此時會發現遠程程式並沒有阻塞等待調試器debugger串連,而是程式正常執行:
此時我們可以使用eclipse的遠程debugger進行遠端偵錯,但是需要注意:此時我們本地的斷點只能打在遠程還沒有執行的代碼處或者正在執行的代碼位置,例如我們就可以在死迴圈中打斷點(死迴圈是一直正在執行的代碼):
然後啟動debugger之後:
停留在斷點處。然後跟著斷點位置繼續我們的debug工作。到此就應該可以知道suspend參數的作用了:
在JVM DEBUG參數中,有一個參數叫"suspend",它的取值有兩個,“y”或者“n”。
如果您剛開始就想調試的話,將參數設定為"suspend=y",這樣Eclipse會遠端連線Java應用程式。
如果你想先運行項目,然後串連Eclipse,那麼可以將參數設定為"suspend=n",這樣的話,Java應用程式會正常運行,之後Eclipse會開始遠端連線。
更多參數細節:
-XDebug 啟用調試。
-Xnoagent 禁用預設sun.tools.debug調試器。
-Djava.compiler=NONE 禁止 JIT 編譯器的載入。
-Xrunjdwp 載入JDWP的JPDA參考執行執行個體。
transport 用於在偵錯工具和 VM 使用的進程之間通訊。
dt_socket 通訊端傳輸。
dt_shmem 共用記憶體傳輸,僅限於 Windows。
server=y/n VM 是否需要作為調試伺服器執行。
address=3999 調試伺服器的連接埠號碼,用戶端用來串連伺服器的連接埠號碼。
suspend=y/n 是否在調試用戶端建立串連之後啟動 VM 。
參考:http://calvinliu.iteye.com/blog/876009
Java關於遠端偵錯程式教程