Daljinsko ispravljanje pogrešaka Java aplikacije
1. Pregled
Otklanjanje pogrešaka u udaljenom Java programu može biti korisno u više slučajeva.
U ovom uputstvu ćemo otkriti kako to učiniti pomoću JDK-ovog alata.
2. Prijava
Počnimo s pisanjem prijave. Pokrenut ćemo ga na udaljenom mjestu i lokalno ga ispraviti putem ovog članka:
javna klasa OurApplication {private static String staticString = "Statički niz"; private String instanceString; javna statička void main (String [] args) {for (int i = 0; i <1_000_000_000; i ++) {OurApplication app = new OurApplication (i); System.out.println (app.instanceString); }} public OurApplication (int index) {this.instanceString = buildInstanceString (index); } javni String buildInstanceString (int broj) {return broj + ". String String!"; }}
3. JDWP: Java protokol za ispravljanje pogrešaka
The Java protokol za ispravljanje pogrešakaje protokol koji se u Javi koristi za komunikaciju između ispravljača i otklanjanja pogrešaka. Program za otklanjanje pogrešaka je aplikacija koja se otklanja pogreškama, dok je program za uklanjanje pogrešaka aplikacija ili postupak koji se povezuje s aplikacijom koja se otklanja pogreške.
Obje aplikacije rade ili na istom stroju ili na različitim strojevima. Usredotočit ćemo se na ovo drugo.
3.1. Mogućnosti JDWP-a
Koristit ćemo JDWP u argumentima JVM naredbenog retka prilikom pokretanja aplikacije za otklanjanje pogrešaka.
Za njegovo pozivanje potreban je popis mogućnosti:
- prijevoz je jedina potpuno potrebna opcija. Definira koji će transportni mehanizam koristiti. dt_shmem radi samo na sustavu Windows i ako se oba procesa izvode na istom stroju dok dt_socket kompatibilan je sa svim platformama i omogućuje pokretanje procesa na različitim strojevima
- poslužitelju nije obavezna opcija. Ova zastavica, kada je uključena, definira način na koji se veže za program za ispravljanje pogrešaka. Ili izlaže postupak putem adrese definirane u adresa opcija. Inače, JDWP izlaže zadani
- obustaviti definira treba li JVM suspendirati i pričekati da se program za ispravljanje pogrešaka priključi ili ne
- adresa je opcija koja sadrži adresu, općenito priključak, koji je otkrio otklanjač pogrešaka. Također može predstavljati adresu prevedenu kao niz znakova (poput javadebug ako koristimo poslužitelj = y bez pružanja adresa na sustavu Windows)
3.2. Zapovjedništvo za lansiranje
Počnimo s pokretanjem udaljene aplikacije. Pružit ćemo sve ranije navedene opcije:
java -agentlib: jdwp = transport = dt_socket, server = y, suspend = n, address = 8000 OurApplication
Do Jave 5, argument JVM runjdwp morali koristiti zajedno s drugom opcijom otklanjanje pogrešaka:
java -Xdebug -Xrunjdwp: transport = dt_socket, poslužitelj = y, suspend = n, adresa = 8000
Ovaj način korištenja JDWP-a i dalje je podržan, ali će se odustati u budućim izdanjima. Radije ćemo upotrijebiti noviju notaciju kad god je to moguće.
3.3. Od Jave 9
Napokon, jedna od mogućnosti JDWP-a promijenila se izdavanjem verzije 9 Jave. Ovo je prilično mala promjena jer se odnosi samo na jednu opciju, ali učinit će promjenu ako pokušavamo otkloniti pogreške u udaljenoj aplikaciji.
Ova promjena utječe na način adresa ponaša se za udaljene aplikacije. Stariji zapis adresa = 8000 odnosi se samo na lokalnihost. Da bismo postigli staro ponašanje, upotrijebit ćemo zvjezdicu s dvotačkom kao prefiksom adrese (npr adresa = *: 8000).
Prema dokumentaciji, ovo nije sigurno i preporučuje se navođenje IP adrese programa za ispravljanje pogrešaka kad god je to moguće:
java -agentlib: jdwp = transport = dt_socket, poslužitelj = y, suspend = n, adresa = 127.0.0.1: 8000
4. JDB: Program za ispravljanje pogrešaka Java
JDB, Java program za ispravljanje pogrešaka, alat je uključen u JDK zamišljen da pruži prikladan klijent za uklanjanje pogrešaka iz naredbenog retka.
Za pokretanje JDB-a koristit ćemo priložiti način rada. Ovaj način spaja JDB na pokrenuti JVM. Postoje i drugi načini rada, poput slušati ili trčanje ali su uglavnom prikladni za otklanjanje pogrešaka u lokalno pokrenutoj aplikaciji:
jdb -attach 127.0.0.1:8000> Inicijalizacija jdb ...
4.1. Točke prijeloma
Nastavimo stavljanjem nekih prijelomnih točaka u aplikaciju predstavljenu u odjeljku 1.
Postavit ćemo točku prekida na konstruktor:
> zaustavite se u OurApplication.
Postavit ćemo još jedan u statičkoj metodi glavni, koristeći potpuno kvalificirani naziv Niz razred:
> zaustavite se u OurApplication.main (java.lang.String [])
Konačno, zadnju ćemo postaviti na metodu instance buildInstanceString:
> zaustavite se u OurApplication.buildInstanceString (int)
Sada bismo trebali primijetiti zaustavljanje poslužiteljske aplikacije i ispis sljedećeg u našoj konzoli za ispravljanje pogrešaka:
> Učitavanje točke prekida: "thread = main", OurApplication. (), Linija = 11 bci = 0
Dodajmo sada točku prekida na određenu liniju, onu gdje je varijabla app.instanceString se tiska:
> zaustavite se na OurApplication: 7
Primjećujemo to na koristi se nakon Stop umjesto u kada je točka prekida definirana na određenoj liniji.
4.2. Navigacija i procjena
Sad kad smo postavili svoje prijelomne točke, poslužimo se nast da nastavimo izvršavanje naše niti dok ne dosegnemo točku prekida na liniji 7.
U konzoli bismo trebali vidjeti sljedeće:
> Učitavanje točke prekida: "thread = main", OurApplication.main (), line = 7 bci = 17
Podsjećanja radi, zaustavili smo se na retku koji sadrži sljedeći dio koda:
System.out.println (app.instanceString);
Zaustavljanje na ovoj liniji moglo se izvršiti i zaustavljanjem na glavni metoda i tipkanje korak dvaput. korak izvršava trenutni redak koda i zaustavlja program za ispravljanje pogrešaka izravno na sljedećem retku.
Sad kad smo stali, debugee procjenjuje naše staticString, app‘S instanceString, lokalna varijabla ja i na kraju pogledavši kako vrednovati druge izraze.
Ispisujmo staticField na konzolu:
> eval OurApplication.staticString OurApplication.staticString = "Statički niz"
Izričito stavljamo ime klase ispred statičkog polja.
Ajmo sada ispisati polje instance app:
> eval app.instanceString app.instanceString = "68741. String niza!"
Dalje, pogledajmo varijablu ja:
> ispis i i = 68741
Za razliku od ostalih varijabli, lokalne varijable ne trebaju navesti klasu ili instancu. To također možemo vidjeti ispis ima potpuno isto ponašanje kao eval: oboje procjenjuju izraz ili varijablu.
Procijenit ćemo novu instancu NašaPrimjena za koji smo proslijedili cijeli broj kao parametar konstruktora:
> ispisati novu našuApplication (10) .instanceString novu našuApplication (10) .instanceString = "10. Instance String!"
Sad kad smo procijenili sve varijable koje su nam trebale, htjet ćemo izbrisati prije postavljene točke prekida i pustiti da nit nastavi s obradom. Da bismo to postigli, poslužit ćemo se naredbom čisto nakon čega slijedi identifikator točke prekida.
Identifikator je potpuno isti kao onaj koji je ranije korišten s naredbom Stop:
> obriši OurApplication: 7 Uklonjeno: točka prekida OurApplication: 7
Upotrijebit ćemo kako bismo provjerili je li točka prekida ispravno uklonjena čisto bez argumenata. Ovo će prikazati popis postojećih točaka prekida bez one koju smo upravo izbrisali:
> jasno postavljene točke prekida: točka prekida OurApplication. točka prekida OurApplication.buildInstanceString (int) točka prijeloma OurApplication.main (java.lang.String [])
5. Zaključak
U ovom brzom članku otkrili smo kako koristiti JDWP zajedno s JDB, oba JDK alata.
Više informacija o alatima naravno može se naći u njihovim odgovarajućim referencama: JDWP-ima i JDB-ima - kako bi se dublje ušlo u alat.