Java alkalmazás távoli hibakeresése
1. Áttekintés
A távoli Java-alkalmazások hibakeresése több esetben is hasznos lehet.
Ebben az oktatóanyagban megtudhatjuk, hogyan lehet ezt megtenni a JDK eszközeivel.
2. Az alkalmazás
Kezdjük egy pályázat megírásával. Futtatjuk egy távoli helyen, és helyi hibakeresést végezünk a cikk segítségével:
public class OurApplication {private static String staticString = "Static String"; privát String instanceString; public static void main (String [] args) {for (int i = 0; i <1_000_000_000; i ++) {OurApplication alkalmazás = új OurApplication (i); System.out.println (app.instanceString); }} public OurApplication (int index) {this.instanceString = buildInstanceString (index); } public String buildInstanceString (int szám) {visszatérési szám + ". Példány karakterlánc!"; }}
3. JDWP: A Java Debug Wire protokoll
A Java Debug Wire Protocolegy olyan protokoll, amelyet a Java használ a debuggee és a debugger közötti kommunikációra. A hibakereső a hibakeresés alatt álló alkalmazás, míg a hibakereső a hibakeresés alatt álló alkalmazáshoz csatlakozó alkalmazás vagy folyamat.
Mindkét alkalmazás ugyanazon a gépen vagy különböző gépeken fut. Utóbbira fogunk koncentrálni.
3.1. A JDWP opciói
A JDWP-t a JVM parancssori argumentumokban fogjuk használni, amikor elindítjuk a hibakereső alkalmazást.
Meghívásához a következő lehetőségek listája szükséges:
- szállítás az egyetlen teljesen szükséges lehetőség. Meghatározza, hogy melyik szállítási mechanizmust használja. dt_shmem csak Windows rendszeren működik, és ha mindkét folyamat ugyanazon a gépen fut míg dt_socket kompatibilis az összes platformmal, és lehetővé teszi a folyamatok különböző gépeken történő futtatását
- szerver nem kötelező opció. Ha be van kapcsolva, akkor ez a jelző meghatározza a hibakeresőhöz való kapcsolódás módját. Vagy felfedi a folyamatot a címben megadott címen keresztül cím választási lehetőség. Ellenkező esetben a JDWP kitesz egy alapértelmezettet
- függessze fel meghatározza, hogy a JVM-nek fel kell-e függesztenie és várnia kell egy hibakereső csatolását vagy sem
- cím az opció, amely tartalmazza a hibakereső által kitett címet, általában egy portot. Ez egy címet is képviselhet karakterláncként (például javadebug ha használjuk szerver = y anélkül, hogy egy cím Windows rendszeren)
3.2. Indítsa el a Parancsot
Kezdjük a távoli alkalmazás elindításával. Megadjuk az összes korábban felsorolt lehetőséget:
java -agentlib: jdwp = transport = dt_socket, server = y, suspend = n, address = 8000 OurApplication
Java 5-ig a JVM argumentum runjdwp a másik lehetőséggel együtt kellett használni hibakeresés:
java -Xdebug -Xrunjdwp: szállítás = dt_socket, szerver = y, felfüggesztés = n, cím = 8000
A JDWP használatának ez a módja továbbra is támogatott, de a jövőbeni kiadásokban elvetik. Lehetőség szerint előnyben részesítjük az újabb jelölések használatát.
3.3. Mivel a Java 9
Végül a JDWP egyik lehetősége megváltozott a Java 9-es verziójának kiadásával. Ez meglehetősen csekély változás, mivel csak egy opciót érint, de változást hoz, ha egy távoli alkalmazást próbálunk hibakeresni.
Ez a változás befolyásolja az utat cím távoli alkalmazások esetén viselkedik. A régebbi jelölés cím = 8000 csak a helyi kiszolgáló. A régi viselkedés elérése érdekében kettőspontot tartalmazó csillagot fogunk használni a cím előtagaként (pl cím = *: 8000).
A dokumentáció szerint ez nem biztonságos, ezért ajánlatos a hibakereső IP-címét megadni, amikor csak lehetséges:
java -agentlib: jdwp = transport = dt_socket, szerver = y, suspend = n, address = 127.0.0.1: 8000
4. JDB: A Java hibakereső
A JDB, a Java hibakereső, egy olyan eszköz, amelyet a JDK tartalmaz, amelynek célja a kényelmesebb hibakereső kliens biztosítása a parancssorból.
A JDB elindításához a csatolni mód. Ez a mód a JDB-t egy futó JVM-hez csatolja. Egyéb futási módok léteznek, például hallgat vagy fuss de többnyire kényelmesek egy helyben futó alkalmazás hibakeresésénél:
jdb -attach 127.0.0.1:8000> A jdb inicializálása ...
4.1. Töréspontok
Folytassuk néhány töréspont beillesztésével az 1. szakaszban bemutatott alkalmazásba.
Beállítunk egy töréspontot a kivitelezőn:
> álljon meg a mi alkalmazásunkban.
A statikus módszerrel beállítunk egy másikat fő-, a teljes minősítésű név használatával Húr osztály:
> állj meg a OurApplication.main fájlban (java.lang.String [])
Végül beállítjuk az utolsó példánymódszert buildInstanceString:
> megáll a OurApplication.buildInstanceString (int)
Most észre kell vennünk, hogy a kiszolgálóalkalmazás leáll, és a következőket nyomtatják a hibakereső konzolunkba:
> Töréspont találat: "thread = main", OurApplication. (), Line = 11 bci = 0
Most adjunk hozzá egy töréspontot egy adott vonalhoz, azt, ahol a változó app.instanceString nyomtatás alatt áll:
> álljon meg a mi alkalmazásunknál: 7
Ezt észrevesszük nál nél után használják álljon meg ahelyett ban ben amikor a töréspontot egy adott vonalon definiálják.
4.2. Navigálás és értékelés
Most, hogy beállítottuk a töréspontjainkat, használjuk folytatás hogy folytassuk szálunk végrehajtását, amíg el nem érjük a töréspontot a 7. vonalon.
A következőket kell látnunk nyomtatni a konzolon:
> Töréspont találat: "thread = main", OurApplication.main (), line = 7 bci = 17
Emlékeztetőül megálltunk a következő kódot tartalmazó soron:
System.out.println (app.instanceString);
Ezen a vonalon történő megállást a megállónál is meg lehetett volna tenni fő- módszer és gépelés lépés kétszer. lépés végrehajtja az aktuális kódsort, és közvetlenül a következő sorban állítja le a hibakeresőt.
Most, hogy abbahagytuk, a hibakereső értékeli a dolgunkat staticString, a kb’S instanceString, a helyi változó én és végül egy pillantást vetünk a többi kifejezés értékelésére.
Nyomtassunk staticField a konzolhoz:
> eval OurApplication.staticString OurApplication.staticString = "Statikus karakterlánc"
Az osztály nevét kifejezetten a statikus mező elé tesszük.
Most nyomtassuk ki a kb:
> eval app.instanceString app.instanceString = "68741. Példány-karakterlánc!"
Ezután nézzük meg a változót én:
> i nyomtatás = 68741
A többi változóval ellentétben a helyi változók nem igényelnek osztályt vagy példányt. Ezt is láthatjuk nyomtatás pontosan ugyanúgy viselkedik, mint eval: mindkettő értékel egy kifejezést vagy egy változót.
Értékelni fogjuk a A mi alkalmazásunk amelyhez egy egész számot adtunk meg konstruktorként:
> nyomtassa ki az új OurApplication (10) .instanceString új OurApplication (10) .instanceString = "10. Példány karakterlánc!"
Miután kiértékeltük az összes szükséges változót, törölni akarjuk a korábban beállított töréspontokat, és hagyjuk, hogy a szál folytassa a feldolgozását. Ennek eléréséhez a parancsot fogjuk használni egyértelmű amelyet a töréspont azonosítója követ.
Az azonosító pontosan megegyezik a paranccsal korábban használt azonosítóval álljon meg:
> törölje a mi Alkalmazásunkat: 7 Eltávolítva: töréspont A mi alkalmazásunk: 7
Annak ellenőrzésére, hogy a töréspontot megfelelően eltávolították-e, használjuk egyértelmű érvek nélkül. Ez megjeleníti a meglévő töréspontok listáját anélkül, hogy az imént töröltük volna:
> egyértelmű töréspontok beállítása: töréspont OurApplication. töréspont OurApplication.buildInstanceString (int) töréspont OurApplication.main (java.lang.String [])
5. Következtetés
Ez a rövid cikk felfedeztük, hogyan lehet a JDWP-t használni a JDB-vel, mindkét JDK eszközzel.
A szerszámozásról további információk természetesen megtalálhatók a megfelelő referenciákban: JDWP-k és JDB-k - hogy jobban belemerülhessünk az eszközökbe.