|
在無法訪問運行中的實例時,調(diào)試一個Java程序可能相當(dāng)麻煩;當(dāng)應(yīng)用程序在遠程環(huán)境下運行,并且不會在控制臺或日志文件中輸出任何結(jié)果時,調(diào)試工作變得
更加困難。如果你需要對一個運行中的Java應(yīng)用程序進行全方位調(diào)試,Sun的Java平臺調(diào)試構(gòu)架(JPDA)可為您提供幫助。 JPDA是一組API集合,旨在幫助你調(diào)試Java代碼。J2SE自1.2.2版開始推出JPDA工具集,并在1.3.x版中將它直接包含在J2SE軟件包中。 JPDA并非一個應(yīng)用程序或調(diào)試工具,而是一組精心設(shè)計的接口與協(xié)議,了解這點很重要。Sun設(shè)計這一標準的目的是提供一個基礎(chǔ)構(gòu)架,以便第 三方工具和調(diào)整器能夠高效利用它。還有許多利用JPDA的優(yōu)秀調(diào)試器和IDE,包括一些獲得廣泛認可的工具,如Borland JBuilder、Oracle JDeveloper、IntelliJ IDEA、Sun NetBeans、IBM Eclipse等等。不過,Sun在它的傳統(tǒng)命令行式調(diào)試器jdb中提供了一個參考實例。Java 1.3重新編寫了jdb以支持JPDA。在本文中,我將討論JPDA技術(shù)及它的一些實際應(yīng)用。 工作原理 JPDA由三個接口構(gòu)成,這些接口為桌面系統(tǒng)的開發(fā)環(huán)境而設(shè)計。Java虛擬機工具接口(JVMTI)定義虛擬機(VM)在調(diào)試時必須提供的 服務(wù)。(在Java 5.0中,JVMTI替代已被刪除的Java虛擬機調(diào)試接口)。Java調(diào)試線協(xié)議(JDWP)定義在調(diào)試過程和調(diào)試器前端之間傳輸?shù)男畔⒑驼埱蟮母袷健? 它執(zhí)行Java調(diào)試接口(JDI)。JDI定義用戶代碼級信息和請求。 JPDA概念將調(diào)試過程分為兩部分:被調(diào)試的程序(被調(diào)試者-debuggee)和JDI。JDI一般為一個調(diào)試應(yīng)用程序的用戶接口(或 Java IDE的一部分)。被調(diào)試的應(yīng)用程序在后端運行,而JDI在前端運行。在前端與后端之間有一個通信通道運行JDWP協(xié)議;因此,被調(diào)試程序與調(diào)試器可以位 于同一個系統(tǒng)內(nèi),也可位于不同的系統(tǒng)中。 從開發(fā)者的角度,一個調(diào)試應(yīng)用程序可進入任何JPDA層面。因為JDI是最高層,也最容易使用,我們推薦使用這個接口。假設(shè)一家公司用JDI 開發(fā)了一個調(diào)試器。公司能夠把它用于參考實例中,它將自動與VM和Sun支持的平臺協(xié)同工作,因此大多數(shù)IDE供應(yīng)商采用這種方式。還可以這樣,例如,參 考實例在前端運行,被調(diào)試者運行另一家公司執(zhí)行JDWP(它可能運行或忽略JVMTI)的VM。 一些調(diào)試器可能建立在較低層面之上,如JDWP(例如,如果Java沒有編寫前端)或JVMTI(針對需要低級功能的專用調(diào)試器)。 調(diào)試器的后端負責(zé)由調(diào)試器前端向被調(diào)試者VM傳輸請求,如“告訴我變量X的值”;它還負責(zé)向前端傳輸對這些請求(包括像到達斷點之類的預(yù)計事件)的響應(yīng)。后端與前端利用JDWP通過一個通信通道進行通信。后端與被調(diào)試者VM利用JVMTI進行通信。 通信通道連接調(diào)試器的前端與后端??梢哉J為它由兩個裝置組成:一個連接器和一個傳送器。連接器是一個JDI對象,它在前端與后端建立連接;可能有三種類型的連接器: 收聽型:前端從后端收聽一個進入的連接。 依附型:前端依附到一個已運行的后端上。 發(fā)布型:前端發(fā)布運行被調(diào)試者代碼和后端的Java過程。 傳送器是在前端和后端傳輸信息的基本裝置。在JPDA規(guī)范中沒有指定必須使用的傳送器裝置??赡艿难b置包括:套接字、串行線路和共享內(nèi)存。但 是,JDWP指定了流經(jīng)通道的連續(xù)化位流的格式與語義。許多IDE和調(diào)試器都支持兩種類型的傳送器(Sun的參考實例就是如此):共享內(nèi)存(如果被調(diào)試者 和調(diào)試器位于同一系統(tǒng))和套接字(被調(diào)試者和調(diào)試器可位于任何地方,包括同一系統(tǒng))。 從J2SE 5.0開始,JPDA包括了服務(wù)提供器接口,允許對連接器與傳送器實例進行開發(fā)與配置。這些服務(wù)提供器服務(wù)接口允許調(diào)試器和其它工具供應(yīng)商開發(fā)新的連接器實例,并提供除Sun的套接字和共享內(nèi)存以外的其它傳送器裝置。 被調(diào)試者與調(diào)試器之間的通信以連接為導(dǎo)向。因此,一方必須作為服務(wù)器,收聽一個連接;另一方作為一個客戶端連接到服務(wù)器。JPDA允許以調(diào)試應(yīng)用程序和目標VM為服務(wù)器。 JPDA實際應(yīng)用 如果你需要使用套接字傳送器,在對應(yīng)的JVM中以dt_socket為名確定自變量的類型。如果被調(diào)試者和調(diào)試器位于同一機器之中,且運行的 是Windows系統(tǒng),你可以使用名為dt_schmem的共享內(nèi)存連接器。如果你希望用一個與JPDA兼容的調(diào)試器調(diào)試應(yīng)用程序,你應(yīng)在調(diào)試模式下運行 調(diào)試器,并提交其它參數(shù),如傳送器類型、主機名稱、端口號及其它信息。所有JPDA和調(diào)試參數(shù)必須在啟動應(yīng)用程序時作為自變量提交。 要進行調(diào)試,你必須將調(diào)試JDWP代理加載到應(yīng)用程序的JVM中。從Java 5.0開始,你可以用-agentlib:jdwp選項來完成加載。5.0以前版本則使用-Xdebug和-Xrunjdwp選項(5.0也支持- Xdebug和-Xrunjdwp選項,不過新的-agentlib:jdwp選項更加好用。因為5.0中的JDWP代理使用JVMTI接口連接VM,而 非舊的JVMDI接口)。你應(yīng)該向-agentlib:jdwp(Java 5.0中)或-Xrunjdwp(Java 5.0以前版本) 參數(shù)提供子選項;兩組可能的子選項相同。 以下列方式指定子選項: -agentlib:jdwp=[=],[=]... 或 -Xrunjdwp:[=],[=]... 你可以使用這些選項: help:打印如何應(yīng)用它的簡單信息,并退出VM。 server:(是”y”或否”n”):如“server=y”,收到一個要依附的調(diào)試應(yīng)用程序;如“server=n”,依附到指定地址的調(diào)試應(yīng)用程序。 address:連接傳送地址。如果server=n,嘗試依附到這個地址的調(diào)試應(yīng)用程序;如server=y,收到這個地址的連接。 timeout:如果server=y,它以毫秒為單位指定等待調(diào)試器依附的時間;如server=n,它以毫秒為單位指定依附到調(diào)試器所用的時間。 suspend:如“是”,JVM延緩執(zhí)行,直到調(diào)試器與被調(diào)試JVM建立連接。 以下是命令行實例: agentlib:jdwp=transport=dt_socket,server=y,address=8000 在端口8000收聽一個套接字連接。在主類加載前延緩這個VM(默認suspend=y)。一旦連接上調(diào)試應(yīng)用程序,它發(fā)送一個JDWP命令恢復(fù)VM。 agentlib:jdwp=transport=dt_shmem,server=y,suspend=n 選擇一個有效的共享內(nèi)存?zhèn)鬏數(shù)刂凡⑺蛴〕鰜?。在那個地址收聽一個共享內(nèi)存連接。在調(diào)試應(yīng)用程序依附之前,允許VM開始執(zhí)行。 agentlib:jdwp=transport=dt_socket,address=myhost:8000 通過myhost主機端口8000的套接字依附到一個運行的調(diào)試應(yīng)用程序。在主類加載前延緩這個VM。 |
|
|
來自: hailin_cqx > 《我的圖書館》