מבוא לממשק Debug Java (JDI)

1. סקירה כללית

אנו עשויים לתהות כיצד מזהי IDE מוכרים כמו IntelliJ IDEA ו- Eclipse מיישמים תכונות ניפוי באגים. כלים אלה מסתמכים במידה רבה על ארכיטקטורת הבאגים של Java Platform (JPDA).

במאמר מקדים זה נדון בממשק ה- API של ממשק Debug Java (JDI) הזמין תחת JPDA.

באותו הזמן, נכתוב תוכנית ניפוי באגים מותאמת אישית צעד אחר צעד, הכרות עם ממשקי JDI שימושיים.

2. מבוא ל- JPDA

ארכיטקטורת הבאגים של Java Platform (JPDA) היא קבוצה של ממשקים ופרוטוקולים מעוצבים המשמשים לניפוי באגים ב- Java.

הוא מספק שלושה ממשקים שתוכננו במיוחד, כדי להטמיע את הבאגים המותאמים אישית עבור סביבת פיתוח במערכות שולחן עבודה.

ראשית, ממשק כלי המחשב הווירטואלי של Java (JVMTI) מסייע לנו לקיים אינטראקציה ולשלוט בביצוע יישומים הפועלים ב- JVM.

לאחר מכן, יש את פרוטוקול Java Debug Wire (JDWP) המגדיר את הפרוטוקול המשמש בין היישום הנבדק (debuggee) לבין הבאגים.

לבסוף, ממשק Java Debug (JDI) משמש ליישום יישום הבאגים.

3. מה זה JDI?

ממשק ה- API של Debug Interface ל- Java הוא מערכת ממשקים שמספקת Java, כדי ליישם את הקצה הקדמי של הבאגים. JDI הוא השכבה הגבוהה ביותר ב- JPDA.

ניפוי באגים שנבנה עם JDI יכול לנקות באגים ביישומים הפועלים בכל JVM שתומך ב- JPDA. יחד עם זאת, אנו יכולים לחבר אותו לכל שכבת ניפוי באגים.

הוא מספק את האפשרות לגשת ל- VM ולמצבו יחד עם גישה למשתנים של ניפוי הבאגים. יחד עם זאת, היא מאפשרת להגדיר את נקודות ההפסקה, דריכה, נקודות תצפית וטיפול בחוטים.

4. התקנה

נצטרך שתי תוכניות נפרדות - ניפוי באגים ובאגים - כדי להבין את היישומים של JDI.

ראשית, נכתוב תוכנית לדוגמא כמתקן ניפוי הבאגים.

בואו ניצור JDIExampleDebuggee כיתה עם כמה חוּט משתנים ו println הצהרות:

מחלקה ציבורית JDIExampleDebuggee {public static void main (String [] args) {String jpda = "Java Platform Debugger Architecture"; System.out.println ("היי כולם, ברוכים הבאים ל-" + jpda); // הוסף כאן נקודת שבירה // הוסף כאן נקודת שבירה וגם נכנס לכאן טקסט מחרוזת = "היום נצלול לתוך" + jdi; System.out.println (טקסט); }}

לאחר מכן נכתוב תוכנית ניפוי באגים.

בואו ניצור JDIExampleDebugger מחלקה עם מאפיינים להחזקת תוכנית ניפוי באגים (debugClass) ומספרי קו לנקודות הפסקה (breakPointLines):

מחלקה ציבורית JDIExampleDebugger {debugClass class class; פרטי int [] breakPointLines; // גטרים וקובעים}

4.1. LaunchingConnector

בהתחלה, איתור באגים דורש מחבר כדי ליצור קשר עם מכונת הווירטואלית היעד (VM).

לאחר מכן, נצטרך להגדיר את ניפוי הבאגים כמחבר רָאשִׁי טַעֲנָה. סוף סוף, המחבר אמור להפעיל את ה- VM לצורך איתור באגים.

לשם כך, JDI מספק א Bootstrap בכיתה שנותנת מופע של LaunchingConnector. ה LaunchingConnector מספק מפה של ארגומנטים המוגדרים כברירת מחדל, שבה אנו יכולים להגדיר את ה- רָאשִׁי טַעֲנָה.

לכן, בואו נוסיף את connectAndLaunchVM שיטה ל JDIDebuggerExample מעמד:

ציבורי VirtualMachine connectAndLaunchVM () זורק חריג {LaunchingConnector launchingConnector = Bootstrap.virtualMachineManager (). defaultConnector (); ארגומנטים של מפה = launchingConnector.defaultArguments (); argument.get ("ראשי"). setValue (debugClass.getName ()); החזר launchingConnector.launch (טיעונים); }

כעת נוסיף את ה- רָאשִׁי שיטה ל JDIDebuggerExample בכיתה לניפוי באגים JDIExampleDebuggee:

סטטי ציבורי ריק ריק (String [] args) זורק חריג {JDIExampleDebugger debuggerInstance = JDIExampleDebugger חדש (); debuggerInstance.setDebugClass (JDIExampleDebuggee.class); int [] breakPoints = {6, 9}; debuggerInstance.setBreakPointLines (breakPoints); VirtualMachine vm = null; נסה {vm = debuggerInstance.connectAndLaunchVM (); vm.resume (); } לתפוס (חריג e) {e.printStackTrace (); }}

בואו נערך את שני השיעורים שלנו, JDIExampleDebuggee (ניפוי באגים) ו JDIExampleDebugger (מנפה):

javac -g -cp "/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/lib/tools.jar" com / baeldung / jdi / *. java

בואו נדון ב ג'אוואק הפקודה המשמשת כאן, בפירוט.

ה -g אפשרות מייצרת את כל המידע על ניפוי באגים שבלעדיו, אנו עשויים לראות AbsentInformationException.

וגם -cp יוסיף את tools.jar בנתיב הכיתה כדי להרכיב את השיעורים.

כל ספריות JDI זמינות תחת tools.jar של הג'וינט. לכן, דאג להוסיף את ה- tools.jar בנתיב הכיתה גם בהידור וגם בביצוע.

זהו זה, עכשיו אנחנו מוכנים לבצע את הבאגים המותאמים אישית שלנו JDIExampleDebugger:

java -cp "/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/lib/tools.jar :." JDIExampleDebugger

שים לב ל":. " עם tools.jar. זה יצורף tools.jar לשביל הכיתה לזמן הריצה הנוכחי (השתמש ב- ";." בחלונות).

4.2. Bootstrap ו ClassPrepareRequest

ביצוע תוכנית הבאגים כאן לא יביא תוצאות מכיוון שלא הכנו את הכיתה לאיתור באגים והגדרנו את נקודות ההפסקה.

ה מכונה וירטואלית בכיתה יש את eventRequestManager שיטה ליצור בקשות שונות כמו ClassPrepareRequest, BreakpointRequest, ו StepEventRequest.

אז בואו נוסיף את enableClassPrepareRequest שיטה ל JDIExampleDebugger מעמד.

זה יסנן את JDIExampleDebuggee בכיתה ומאפשר את ClassPrepare בקשה:

בטל ציבורי enableClassPrepareRequest (VirtualMachine vm) {ClassPrepareRequest classPrepareRequest = vm.eventRequestManager (). createClassPrepareRequest (); classPrepareRequest.addClassFilter (debugClass.getName ()); classPrepareRequest.enable (); }

4.3. ClassPrepareEvent ו BreakpointRequest

פַּעַם, ClassPrepareRequest בשביל ה JDIExampleDebuggee המחלקה מופעלת, תור האירועים של ה- VM יתחיל לקבל מקרים של ClassPrepareEvent.

באמצעות ClassPrepareEvent, אנחנו יכולים לגרום למיקום לקבוע נקודת הפסקה ויוצר a BreakPointRequest.

לשם כך, נוסיף את ה- setBreakPoints שיטה ל JDIExampleDebugger מעמד:

set-BreakingPoints (vM VirtualMachine, אירוע ClassPrepareEvent) זורק את הציבור הריק זורק את AbsentInformationException {ClassType classType = (ClassType) event.referenceType (); עבור (int lineNumber: breakPointLines) {מיקום מיקום = classType.locationsOfLine (lineNumber) .get (0); BreakpointRequest bpReq = vm.eventRequestManager (). CreateBreakpointRequest (מיקום); bpReq.enable (); }}

4.4. BreakPointEvent ו StackFrame

עד כה הכנו את הכיתה לאיתור באגים וקבענו את נקודות ההפסקה. עכשיו, אנחנו צריכים לתפוס את BreakPointEvent ולהציג את המשתנים.

JDI מספק את StackFrame בכיתה, כדי לקבל את רשימת כל המשתנים הגלויים של ניפוי הבאגים.

לכן, בואו נוסיף את ה- תצוגה משתנה שיטה ל JDIExampleDebugger מעמד:

display public void displayVariables (LocatableEvent event) זורק IncompatibleThreadStateException, AbsentInformationException {StackFrame stackFrame = event.thread (). frame (0); אם (stackFrame.location (). toString (). מכיל (debugClass.getName ())) {Map visibleVariables = stackFrame .getValues ​​(stackFrame.visibleVariables ()); System.out.println ("משתנים ב-" + stackFrame.location (). ToString () + ">"); עבור (Map.Entry entry: visibleVariables.entrySet ()) {System.out.println (entry.getKey (). name () + "=" + entry.getValue ()); }}}

5. איתור באגים

בשלב זה כל מה שאנחנו צריכים הוא לעדכן את רָאשִׁי שיטת ה- JDIExampleDebugger כדי להתחיל באגים.

לפיכך, נשתמש בשיטות שכבר דנו בהן כמו enableClassPrepareRequest, setBreakPoints, ו תצוגה משתנה:

נסה {vm = debuggerInstance.connectAndLaunchVM (); debuggerInstance.enableClassPrepareRequest (vm); EventSet eventSet = null; בעוד ((eventSet = vm.eventQueue (). remove ())! = null) {עבור (אירוע אירוע: eventSet) {if (אירוע למשל של ClassPrepareEvent) {debuggerInstance.setBreakPoints (vm, (ClassPrepareEvent) אירוע); } אם (אירוע מופע של BreakpointEvent) {debuggerInstance.displayVariables ((BreakpointEvent) אירוע); } vm.resume (); }}} לתפוס (VMDisconnectedException e) {System.out.println ("המחשב הווירטואלי מנותק."); } לתפוס (חריג e) {e.printStackTrace (); }

ראשית, בואו נערך את JDIDebuggerExample בכיתה שוב עם כבר דנו ג'אוואק פקודה.

ולבסוף, נבצע את תוכנית הבאגים יחד עם כל השינויים כדי לראות את הפלט:

משתנים ב- com.baeldung.jdi.JDIExampleDebuggee: 6> args = מופע של java.lang.String [0] (id = 93) משתנים ב- com.baeldung.jdi.JDIExampleDebuggee: 9> jpda = "אדריכלות פלטפורמת הבאגים של Java" טוענת = מופע של java.lang.String [0] (id = 93) המחשב הווירטואלי מנותק.

הורא! ניפחנו ניפוי בהצלחה ב- JDIExampleDebuggee מעמד. במקביל, הצגנו את ערכי המשתנים במיקומי נקודת השבר (שורה מספר 6 ו- 9).

לכן, הבאגים המותאמים אישית שלנו מוכנים.

5.1. שלב בקשה

ניפוי באגים גם דורש לעבור על הקוד ולבדוק את מצב המשתנים בשלבים הבאים. לכן, ניצור בקשת צעד בנקודת ההפסקה.

בעת יצירת המופע של שלב בקש, עלינו לספק את הגודל והעומק של המדרגה. נגדיר STEP_LINE ו לדרוך מעל בהתאמה.

בוא נכתוב שיטה להפעלת בקשת הצעד.

למען הפשטות, נתחיל לצעוד בנקודת השבירה האחרונה (שורה מספר 9):

public void enableStepRequest (VirtualMachine vm, BreakpointEvent event) {// אפשר בקשת שלב לנקודת הפסקה אחרונה אם (event.location (). toString (). מכיל (debugClass.getName () + ":" + breakPointLines [breakPointLines.length- 1])) {StepRequest stepRequest = vm.eventRequestManager () .createStepRequest (event.thread (), StepRequest.STEP_LINE, StepRequest.STEP_OVER); stepRequest.enable (); }}

כעת נוכל לעדכן את רָאשִׁי שיטת ה- JDIExampleDebugger, כדי לאפשר את בקשת הצעד כאשר היא א BreakPointEvent:

אם (אירוע מופע של BreakpointEvent) {debuggerInstance.enableStepRequest (vm, (BreakpointEvent) אירוע); }

5.2. StepEvent

דומה ל BreakPointEvent, אנו יכולים גם להציג את המשתנים ב- StepEvent.

בואו נעדכן את רָאשִׁי השיטה בהתאם:

אם (אירוע מופע של StepEvent) {debuggerInstance.displayVariables (((StepEvent) אירוע); }

לבסוף נבצע את הבאגים בכדי לראות את מצב המשתנים תוך כדי מעבר בקוד:

משתנים ב- com.baeldung.jdi.JDIExampleDebuggee: 6> args = מופע של java.lang.String [0] (id = 93) משתנים ב- com.baeldung.jdi.JDIExampleDebuggee: 9> args = מופע של java.lang.String [0] (id = 93) jpda = "אדריכלות הבאגים לפלטפורמת Java" במשתנים com.baeldung.jdi.JDIExampleDebuggee: 10> args = מופע של java.lang.String [0] (id = 93) jpda = "פלטפורמת Java אדריכלות ניפוי באגים "jdi =" ממשק איתור באגים של Java "במשתנים com.baeldung.jdi.JDIExampleDebuggee: 11> args = מופע של java.lang.String [0] (id = 93) jpda =" אדריכלות פלטפורמת הבאגים של Java "jdi =" ממשק ניפוי באגים של ג'אווה "text =" היום, נצלול למשתנים של ממשק ניפוי באגים של ג'אווה ב- com.baeldung.jdi.JDIExampleDebuggee: 12> args = מופע של java.lang.String [0] (id = 93) jpda = " ארכיטקטורת הבאגים לפלטפורמת Java "jdi =" ממשק Debug Java "text =" היום נצלול לממשק ניפוי הבאגים של Java "המחשב הווירטואלי מנותק.

אם נשווה את הפלט, נבין ש- Debugger נכנס משורה מספר 9 ומציג את המשתנים בכל השלבים הבאים.

6. קרא פלט ביצוע

אולי נבחין בכך println הצהרות של JDIExampleDebuggee class לא היה חלק מפלט הבאגים.

בהתאם לתיעוד JDI, אם נפעיל את ה- VM דרך LaunchingConnector, זרמי הפלט והשגיאה שלו חייבים להיקרא על ידי תהליך לְהִתְנַגֵד.

לכן, בואו נוסיף את זה ל- סוף כל סוף סעיף שלנו רָאשִׁי שיטה:

סוף סוף {InputStreamReader reader = InputStreamReader חדש (vm.process (). getInputStream ()); כותב OutputStreamWriter = OutputStreamWriter חדש (System.out); char [] buf = char חדש [512]; reader.read (buf); author.write (buf); writer.flush (); }

כעת, הפעלת תוכנית הבאגים תוסיף גם את println הצהרות מאת JDIExampleDebuggee מחלקה לפלט איתור באגים:

שלום לכולם, ברוך הבא לארכיטקטורה של Debugger Java Platform היום, נצלול לממשק Debug Java

7. מסקנה

במאמר זה, בחנו את ממשק ה- Java Debug Interface (JDI) הזמין תחת ארכיטקטורת הבאגים של Java Platform (JPDA).

על הדרך בנינו ניפוי באגים מותאם אישית המשתמש בממשקים שימושיים שמספקים JDI. במקביל, הוספנו גם יכולת דריכה לבאגים.

מכיוון שזו הייתה רק מבוא ל- JDI, מומלץ לבחון את היישומים של ממשקים אחרים הזמינים תחת JDI API.

כרגיל, כל יישומי הקוד זמינים ב- GitHub.


$config[zx-auto] not found$config[zx-overlay] not found