java 可以以調試模式啟動,啟動后可以使用 jdb 對程序進行調試。以調試模式啟動,需要加入以下參數:
java -Xdebug -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n
一般如 tomcat, jboss, weblogic 等服務器中會使用 JAVA_OPTS 環境變量,如果要運行這類服務,可以設置該環境變量如下:
linux 下
export JAVA_OPTS="$JAVA_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n" JAVA_OPTS="$JAVA_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n"
windows 下
set JAVA_OPTS=%JAVA_OPTS% -Xdebug -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n
maven 使用 MAVEN_OPTS 參數,設置跟上面的類同
以下是一個簡單的服務器端代碼,接收 UDP 請求
package mm; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; public class UServer { public static void main(String[] args) throws IOException { DatagramSocket socket = new DatagramSocket(8000); while (true) { DatagramPacket dataPackage = new DatagramPacket(new byte[100], 100); socket.receive(dataPackage); System.out.println("Receive from : " + dataPackage.getAddress().getHostName()); System.out.println("Data: [" + new String(dataPackage.getData()) + "]"); dataPackage.setData("abc你好".getBytes()); socket.send(dataPackage); } } }
通過以下命令運行該服務器:
java -Xdebug -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n mm.UServer
通過以下命運運行 jdb,即可進行調試
[root@server test] # jdb -attach 192.168.1.79:8787 -sourcepath . Set uncaught java.lang.Throwable Set deferred uncaught java.lang.Throwable Initializing jdb ... > stop at mm.UServer:12 Set breakpoint mm.UServer:12 > Breakpoint hit: "thread=main", mm.UServer.main(), line=12 bci=11 12 DatagramPacket dataPackage = new DatagramPacket(new byte[100], 100); main[1] next Step completed: "thread=main", mm.UServer.main(), line=13 bci=25 13 socket.receive(dataPackage); main[1] main[1] next > next Nothing suspended. > Step completed: "thread=main", mm.UServer.main(), line=14 bci=30 14 System.out.println("Receive from : " main[1] !! next Step completed: "thread=main", mm.UServer.main(), line=15 bci=42 15 + dataPackage.getAddress().getHostName()); main[1] main[1] !! next > Step completed: "thread=main", mm.UServer.main(), line=14 bci=55 14 System.out.println("Receive from : " main[1] !! next > Step completed: "thread=main", mm.UServer.main(), line=16 bci=58 16 System.out.println("Data: [" + new String(dataPackage.getData()) + "]"); main[1] !! next > Step completed: "thread=main", mm.UServer.main(), line=17 bci=95 17 dataPackage.setData("abc你好".getBytes()); main[1] !! next > Step completed: "thread=main", mm.UServer.main(), line=18 bci=104 18 socket.send(dataPackage); main[1] !! next > Step completed: "thread=main", mm.UServer.main(), line=11 bci=109 11 while (true) { main[1] !! next > Step completed: Breakpoint hit: "thread=main", mm.UServer.main(), line=12 bci=11 12 DatagramPacket dataPackage = new DatagramPacket(new byte[100], 100); main[1]
調試的主要命令有
- stop at 在指定行設置斷點
- stop on 在指定的方法設置斷點
- next 單步執行到下一步
- !! 重復最后一次命令
目前 eclipse 中已經集成了 jdb,可以在 eclipse 的 debug 選項中設置連接遠程主機進行遠程調試