JPDA(Java Platform Debugger Architecture)是 Java 平台調試體系結構的縮寫通過 JPDA 提供的 API開發人員可以方便靈活的搭建 Java 調試應用程序 JPDA 主要由三個部分組成Java 虛擬機工具接口(JVMTI)Java 調試線協議(JDWP)以及 Java 調試接口(JDI)本系列將會詳細介紹這三個模塊的內部細節通過實例為讀者揭開 JPDA 的面紗本文是該系列的第一篇將會著重從整體上介紹 JPDA 的各個組成闡述它們彼此之間的內在關聯
JPDA 概述
所有的程序員都會遇到 bug對於運行態的錯誤我們往往需要一些方法來觀察和測試運行態中的環境在 Java 程序中最簡單的您是否嘗試過使用 Systemoutprintln() 來輸出您的 Java 程序的執行中的各種變量狀態來發現您的 Java 程序運行時的問題?這種方式方便易用在一些簡單的情況下能夠解決您的問題但是如果當您的程序運行在遠程環境上或者當前環境不允許控制台終端輸出(比如考慮一下虛擬機初始化之時)您無法獲取終端輸出的時候呢?或者如果您根本無法本地修改運行您的程序?
無須擔心您可以通過很多的調試工具來幫助您解決這個問題常見的 IDE 都附帶一個非常直觀簡單的調試工具比如 Eclipse(圖 )就提供一個功能非常全面操作非常簡單的調試器
圖 使用 Eclipse 調試 Java 程序
其他的一些常見的 Java IDE比如 Netbeans 和 IntelliJ 等等也都提供了類似的功能您甚至能不用 IDE 提供的圖形界面使用 JDK 自帶的 jdb 工具以文本命令的形式來調試您的 Java 程序這些形形色色的調試器都支持本地和遠程的程序調試那麼它們是如何被開發的?它們之間存在著什麼樣的聯系呢?我們不得不提及 Java 的調試體系—— JPDA
我們知道Java 程序都是運行在 Java 虛擬機上的我們要調試 Java 程序事實上就需要向 Java 虛擬機請求當前運行態的狀態並對虛擬機發出一定的指令設置一些回調等等那麼 Java 的調試體系就是虛擬機的一整套用於調試的工具和接口
對於 Java 虛擬機接口熟悉的人來說您一定還記得 Java 提供了兩個接口體系JVMPI(Java Virtual Machine Profiler Interface)和 JVMDI(Java Virtual Machine Debug Interface)而它們以及在 Java SE 中准備代替它們的 JVMTI(Java Virtual Machine Tool Interface)都是 Java 平台調試體系(Java Platform Debugger ArchitectureJPDA)的重要組成部分 Java SE 自 版就開始推出 Java 平台調試體系結構(JPDA)工具集而從 JDK x 開始Java SDK 就提供了對 Java 平台調試體系結構的直接支持顧名思義這個體系為開發人員提供了一整套用於調試 Java 程序的 API是一套用於開發 Java 調試工具的接口和協議本質上說它是我們通向虛擬機考察虛擬機運行態的一個通道一套工具理解這一點對於學習 JPDA 非常重要
換句話說通過 JPDA 這套接口我們就可以開發自己的調試工具通過這些 JPDA 提供的接口和協議調試器開發人員就能根據特定開發者的需求擴展定制 Java 調試應用程序開發出吸引開發人員使用的調試工具前面我們提到的 IDE 調試工具都是基於 JPDA 體系開發的區別僅僅在於它們可能提供了不同的圖形界面具有一些不同的自定義功能另外我們要注意的是JPDA 是一套標准任何的 JDK 實現都必須完成這個標准因此通過 JPDA 開發出來的調試工具先天具有跨平台不依賴虛擬機實現JDK 版本無關等移植優點因此大部分的調試工具都是基於這個體系的
JPDA 組成模塊
JPDA 定義了一個完整獨立的體系它由三個相對獨立的層次共同組成而且規定了它們三者之間的交互方式或者說定義了它們通信的接口這三個層次由低到高分別是 Java 虛擬機工具接口(JVMTI)Java 調試線協議(JDWP)以及 Java 調試接口(JDI)這三個模塊把調試過程分解成幾個很自然的概念調試者(debugger)和被調試者(debuggee)以及他們中間的通信器被調試者運行於我們想調試的 Java 虛擬機之上它可以通過 JVMTI 這個標准接口監控當前虛擬機的信息調試者定義了用戶可使用的調試接口通過這些接口用戶可以對被調試虛擬機發送調試命令同時調試者接受並顯示調試結果在調試者和被調試著之間調試命令和調試結果都是通過 JDWP 的通訊協議傳輸的所有的命令被封裝成 JDWP 命令包通過傳輸層發送給被調試者被調試者接收到 JDWP 命令包後解析這個命令並轉化為 JVMTI 的調用在被調試者上運行類似的JVMTI 的運行結果被格式化成 JDWP 數據包發送給調試者並返回給 JDI 調用而調試器開發人員就是通過 JDI 得到數據發出指令圖 展示了這個過程
圖 JPDA 模塊層次
當然開發人員完全可以不使用完整的三個層次而是基於其中的某一個層次開發自己的應用比如您完全可以僅僅依靠通過 JVMTI 函數開發一個調試工具而不使用 JDWP 和 JDI只使用自己的通訊和命令接口當然除非是有特殊的需求利用已有的實現會使您事半功倍避免重復發明輪子
這三個模塊我們會在後續文章中分別詳細介紹這裡我們簡單介紹它們的主要功能
Java 虛擬機工具接口(JVMTI)
JVMTI(Java Virtual Machine Tool Interface)即指 Java 虛擬機工具接口它是一套由虛擬機直接提供的 native 接口它處於整個 JPDA 體系的最底層所有調試功能本質上都需要通過 JVMTI 來提供通過這些接口開發人員不僅調試在該虛擬機上運行的 Java 程序還能查看它們運行的狀態設置回調函數控制某些環境變量從而優化程序性能我們知道JVMTI 的前身是 JVMDI 和 JVMPI它們原來分別被用於提供調試 Java 程序以及 Java 程序調節性能的功能在 JSE 之後 JDK 取代了 JVMDI 和 JVMPI 這兩套接口JVMDI 在最新的 Java SE 中已經不提供支持而 JVMPI 也計劃在 Java SE 後被徹底取代
Java 調試線協議(JDWP)
JDWP(Java Debug Wire Protocol)是一個為 Java 調試而設計的一個通訊交互協議它定義了調試器和被調試程序之間傳遞的信息的格式在 JPDA 體系中作為前端(frontend)的調試者(debugger)進程和後端(backend)的被調試程序(debuggee)進程之間的交互數據的格式就是由 JDWP 來描述的它詳細完整地定義了請求命令回應數據和錯誤代碼保證了前端和後端的 JVMTI 和 JDI 的通信通暢比如在 Sun 公司提供的實現中它提供了一個名為 jdwpdll(jdwpso)的動態鏈接庫文件這個動態庫文件實現了一個 Agent它會負責解析前端發出的請求或者命令並將其轉化為 JVMTI 調用然後將 JVMTI 函數的返回值封裝成 JDWP 數據發還給後端
另外這裡需要注意的是 JDWP 本身並不包括傳輸層的實現傳輸層需要獨立實現但是 JDWP 包括了和傳輸層交互的嚴格的定義就是說JDWP 協議雖然不規定我們是通過 EMS 還是快遞運送貨物的但是它規定了我們傳送的貨物的擺放的方式在 Sun 公司提供的 JDK 中在傳輸層上它提供了 socket 方式以及在 Windows 上的 shared memory 方式當然傳輸層本身無非就是本機內進程間通信方式和遠端通信方式用戶有興趣也可以按 JDWP 的標准自己實現
Java 調試接口(JDI)
JDI(Java Debug Interface)是三個模塊中最高層的接口在多數的 JDK 中它是由 Java 語言實現的 JDI 由針對前端定義的接口組成通過它調試工具開發人員就能通過前端虛擬機上的調試器來遠程操控後端虛擬機上被調試程序的運行JDI 不僅能幫助開發人員格式化 JDWP 數據而且還能為 JDWP 數據傳輸提供隊列緩存等優化服務從理論上說開發人員只需使用 JDWP 和 JVMTI 即可支持跨平台的遠程調試但是直接編寫 JDWP 程序費時費力而且效率不高因此基於 Java 的 JDI 層的引入簡化了操作提高了開發人員開發調試程序的效率
表 總結了三個模塊的不同點
表 JPDA 層次比較
模塊 |
層次 |
編程語言 |
作用 |
JVMTI |
底層
C
獲取及控制當前虛擬機狀態
JDWP |
中介層
C
定義 JVMTI 和 JDI 交互的數據格式
JDI |
高層
Java
提供 Java API 來遠程控制被調試虛擬機
JPDA 實現
關於 Apache Harmony 項目
Apache Harmony 旨在開發出一個獨立且與現有 JDK 兼容的 Java SE 實現它以 Apache 軟件許可證 版發行它建立了一個開放的模塊化運行時架構包括虛擬機和類庫之間及其內部的模塊化通過這個平台社區能在已有實現的基礎上自由定制自己的 Java 實現或者對某個模塊單獨進行創新
每一個虛擬機都應該實現 JVMTI 接口但是 JDWP 和 JDI 本身與虛擬機並非是不可分的這三個層之間是通過標准所定義的交互的接口和協議聯系起來的因此它們可以被獨立替換或取代但不會影響到整體調試工具的開發和使用因此開發和使用自己的 JDWP 和 JDI 接口實現是可能的
Java 軟件開發包(SDK)標准版裡提供了 JPDA 三個層次的標准實現事實上調試工具開發人員還有很多其他開源實現可以選擇比如 Apache Harmony 提供了 JDWP 的實現而 JDI我們可以在 Eclipse 一個子項目 orgeclipsejdtdebug 裡找到其完整的實現(Harmony 也使用了這套實現作為其 JSE 類庫的一部分)通過標准協議Eclipse IDE 的調試工具就可以完全在 Harmony 的環境上運行
Java 調試接口的特點
Java 語言是第一個使用虛擬機概念的流行的編程語言正是因為虛擬機的存在使很多事情變得簡單而輕松掌握了虛擬機就掌握了內存分配線程管理即時優化等等運行態同樣的Java 調試的本質就是和虛擬機打交道通過操作虛擬機來達到觀察調試我們自己代碼的目的這個特點決定了 Java 調試接口和以前其他編程語言的巨大區別
以C/C++ 的調試為例目前比較流行的調試工具是 GDB 和微軟的 Visual Studio 自帶的 debugger在這種 debugger 中首先我們必須編譯一個 debug 模式的程序這個會比實際的 release 模式程序大很多其次在調試過程中debugger 將會深層接入程序的運行掌握和控制運行態的一些信息並將這些信息及時返回這種介入對運行的效率和內存占用都有一定的需求基於這些需求這些 Debugger 本身事實上是提供了或者說創建和管理了一個運行態因此他們的程序算法比較復雜個頭都比較大對於遠端的調試GDB 也沒有很好的默認實現當然C/C++ 在這方面也沒有特別大的需求
而Java 則不同由於 Java 的運行態已經被虛擬機所很好地管理因此作為 Java 的 Debugger 無需再自己創造一個可控的運行態而僅僅需要去操作虛擬機就可以了 Java 的 JPDA 就是一套為調試和優化服務的虛擬機的操作工具其中JVMTI 是整合在虛擬機中的接口JDWP 是一個通訊層而 JDI 是前端為開發人員准備好的工具和運行庫
從構架上說我們可以把 JPDA 看作成是一個 C/S 體系結構的應用在這個構架下我們可以方便地通過網絡在任意的地點調試另外一個虛擬機上的程序這個就很好地解決了部署和測試的問題尤其滿足解決了很多網絡時代中的開發應用的需求前端和後端的分離也方便用戶開發適合於自己的調試工具
從效率上看由於 Java 程序本身就是編譯成字節碼運行在虛擬機上的因此調試前後的程序內存占用都不會有大變化(僅僅是啟動一個 JDWP 所需要的內存)任意程度都可以很好地調試非常方便而 JPDA 構架下的幾個組成部分JDWP 和 JDI 都比較小主要的工作可以讓虛擬機自己完成
從靈活性上Java 調試工具是建立在強大的虛擬機上的因此很多前沿的應用比如動態編譯運行字節碼的實時替換等等都可以通過對虛擬機的改進而得到實現隨著虛擬機技術的逐步發展和深入各種不同種類不同應用領域中虛擬機的出現各種強大的功能的加入給我們的調試工具也帶來很多新的應用
總而言之一個先天的可控的運行態給 Java 的調試工作給 Java 調試接口帶來了極大的優勢和便利通過 JPDA 這個標准我們可以從虛擬機中得到我們所需要的信息完成我們所希望的操作更好地開發我們的程序
結束語
本文簡單介紹了 JPDA 的三個模塊以及它們如何和其它層次交互讓讀者在整體上對 JPDA 體系有了一個直觀的了解從而方便後面針對每個模塊具體介紹的學習這裡我們學習到
JPDA 定義了一套如何開發調試工具的接口和規范
JPDA 由三個獨立的模塊 JVMTIJDWPJDI 組成
調試者通過 JDI 發送接受調試命令
JDWP 定義調試者和被調試者交流數據的格式
JVMTI 可以控制當前虛擬機運行狀態
除了標准實現JPDA 還有許多開源實現供使用
Java 調試工具的優點
From:http://tw.wingwit.com/Article/program/Java/JSP/201311/19143.html