Ohjelmointi

Java-vinkki 105: Luokkatien hallitseminen JWhichin avulla

Kerran kehittäjät kokevat turhautumista käsitellessään Java-luokkatietä. Ei ole aina selvää, minkä luokan luokan kuormaaja lataa, varsinkin kun sovelluksesi luokkatie tulvii hakemistoista ja tiedostoista. Tässä artikkelissa esitän työkalun, joka voi näyttää ladatun luokkatiedoston absoluuttisen polun.

Luokkatien perusteet

Java-virtuaalikone (JVM) käyttää luokan kuormaajaa lataamaan sovellusten käyttämiä luokkia tarpeen mukaan. CLASSPATH ympäristömuuttuja kertoo luokan lataajalle, mistä löytää kolmannen osapuolen ja käyttäjän määrittämät luokat. Voit myös määrittää luokan polun sovelluskohtaisesti -polku JVM-komentoriviargumentti, joka ohittaa ryhmässä määritetyn luokan polun CLASSPATH ympäristömuuttuja.

Classpath-merkinnät voivat olla hakemistoja, jotka sisältävät luokkatiedostoja luokille, jotka eivät ole paketissa, paketin juurihakemistoa paketeissa oleville luokille tai arkistotiedostoja (kuten .zip- tai .jar-tiedostoja), jotka sisältävät luokkia. Luokkatien merkinnät on erotettu kaksoispisteillä Unix-tyyppisissä järjestelmissä ja puolipisteillä erotettuina MS Windows -järjestelmissä.

Luokkakuormaajat on järjestetty delegointihierarkiaan, ja jokaisella luokkakuormaajalla on yläluokan kuormaaja. Kun luokan lataajaa pyydetään etsimään luokka, se delegoi pyynnön ensin vanhemman luokan lataajalleen ennen kuin hän yrittää löytää luokan itse. Järjestelmäluokkakuormaaja, järjestelmään asennetun JDK: n tai JRE: n tarjoama oletusluokkakuormaaja, lataa kolmannen osapuolen ja käyttäjän määrittämät luokat käyttämällä CLASSPATH ympäristömuuttuja tai -polku JVM-komentoriviargumentti. Järjestelmäluokkakuormaaja delegoi laajennusluokan lataamaan luokkia, jotka käyttävät Java-laajennusmekanismia. Laajennusluokan kuormaaja valtuuttaa bootstrap-luokan kuormaajan (pumppu pysähtyy täällä!) Lataamaan ydin JDK-luokat.

Voit kehittää erikoistuneita luokan kuormaajia mukauttamaan sitä, miten JVM lataa luokkia dynaamisesti. Esimerkiksi useimmat servlet-moottorit käyttävät mukautettua luokan kuormaajaa dynaamisesti uudelleen servlet-luokkiin, jotka ovat muuttuneet mukautetulla luokkatiedolla määritetyissä hakemistoissa.

Erityisen tärkeätä ja paljon huolta aiheuttava luokkakuormaaja lataa luokat siinä järjestyksessä kuin ne näkyvät luokkapolulla. Ensimmäisestä luokan polun merkinnästä alkaen luokan latausohjelma käy jokaisessa määritetyssä hakemistossa tai arkistotiedostossa yrittäen löytää luokan, jonka ladataan. Ensimmäinen sen löytämä luokka, jolla on oikea nimi, ladataan, ja kaikki jäljellä olevat luokkatiedon merkinnät ohitetaan.

Kuulostaa yksinkertaiselta, eikö?

Luokkatien huijaaminen

Huolimatta siitä, myöntävätkö he sen vai eivät, sekä aloittelija että veteraani Java-kehittäjä on jossakin vaiheessa (yleensä pahimmalla mahdollisella hetkellä!) Huijata raskaalla luokkatietä. Kun riippuvien kolmansien osapuolten ja käyttäjien määrittelemien luokkien määrä kasvaa sovelluksessa ja luokan polusta tulee kaatopaikka jokaiselle mahdolliselle hakemistolle ja arkistotiedostolle, ei ole aina selvää, minkä luokan luokan lataaja lataa ensin. Tämä pätee erityisesti valitettavassa tapauksessa, että luokan polku sisältää päällekkäisiä luokan merkintöjä. Muista, että luokan kuormaaja lataa ensimmäisen oikein nimetyn luokan, jonka se löytää luokalta ja tehokkaasti "piilottaa" kaikki muut oikein nimetyt alemman prioriteetin luokat.

On aivan liian helppoa joutua tämän luokkatien huijaamisen uhriksi. Pitkän orjuuden jälkeen kuumalla näppäimistöllä, lisäät hakemiston luokkatielle yrittäessäsi saada sovelluksen uusin ja suurin versio luokasta, vaikka et tiedä, että luokan toinen versio sijaitsee hakemistossa korkeampi etusija luokassa. Gotcha!

JWhich: Yksinkertainen luokkatien työkalu

Litteän polun ilmoitukseen liittyvä prioriteettiongelma ei ole ainutlaatuinen Java-luokan polulle. Ratkaisun löytäminen ongelmaan edellyttää vain, että seisot legendaaristen ohjelmistojättien harteilla. Unix-käyttöjärjestelmä mikä command ottaa nimen ja näyttää sen tiedoston polun, joka suoritettaisiin, jos nimi annettaisiin komentona. Se käytännössä kulkee PATH ympäristömuuttuja komennon ensimmäisen esiintymisen paikantamiseksi. Se kuulostaa tehokkaalta työkalulta myös Java-luokan polun hallintaan. Tämän ajatuksen innoittamana aloin kirjoittaa Java-apuohjelman, joka voisi ottaa Java-luokan nimen ja näyttää luokkatiedoston absoluuttisen polun, jonka luokan lataaja lataa, kuten classpath määrää.

Seuraava esimerkki JWhich näyttää absoluuttisen polun nimen ensimmäisestä esiintymisestä com.clarkware.ejb.ShoppingCartBean luokka, jonka luokan lataaja lataa, joka sattuu olemaan hakemistossa:

 > java JWhich com.clarkware.ejb.ShoppingCartBean Class 'com.clarkware.ejb.ShoppingCartBean' löydetty kansiosta /home/mclark/classes/com/clarkware/ejb/ShoppingCartBean.class 

Seuraava esimerkki JWhich näyttää absoluuttisen polun nimen ensimmäisestä esiintymisestä javax.servlet.http.HttpServlet luokan lataaja lataa luokan, joka sattuu olemaan pakattu arkistotiedostoon:

 > java JWichich javax.servlet.http.HttpServlet Class 'javax.servlet.http.HttpServlet' löytyi tiedostosta: /home/mclark/lib/servlet.jar! /javax/servlet/http/HttpServlet.class ' 

Kuinka JWhich toimii

Jotta voit yksiselitteisesti määrittää, mikä luokka ladataan ensin luokkatietä varten, sinun on mentävä luokan kuormaajan mieleen. Tämä ei ole niin vaikeaa kuin miltä se kuulostaa - sinä vain kysyt sitä! Asiaankuuluva lähdekoodi JWhich seuraa. Katso täydellinen lähdekoodi kohdasta Resurssit.

1: julkinen luokka JJoka {2: 3: / ** 4: * Tulostaa luokkatiedoston 5: * absoluuttisen polun nimen, joka sisältää määritetyn luokan nimen, kuten 6: * määrittelee nykyisellä luokkatiedolla. 7: * 8: * @param className Luokan nimi. 9: * / 10: public static void which (String luokanNimi) {11: 12: if (! ClassName.startsWith ("/")) {13: className = "/" + className; 14:} 15: className = className.replace ('.', '/'); 16: luokan nimi = luokan nimi + ".luokka"; 17: 18: java.net.URL classUrl = 19: uusi JWhich (). GetClass (). GetResource (className); 20: 21: if (classUrl! = Null) {22: System.out.println ("\ nClass '" + luokanNimi + 23: "' löydetty \ n '" + classUrl.getFile () + "'" "); 24:} else {25: System.out.println ("\ nClass '" + className + 26: "' ei löydy \ n '" + 27: System.getProperty ("java.class.path") + "' "); 28:} 29:} 30: 31: public static void main (String args []) {32: if (args.pituus> 0) {33: JWhich.which (args [0]); 34:} else {35: System.err.println ("Käyttö: java JWhich"); 36:} 37:} 38:} 

Ensinnäkin sinun on hierottava luokan nimeä hieman saadaksesi luokan kuormaaja hyväksynnän (rivit 12-16). "/": N valmistelu luokan nimelle ohjaa luokan kuormaajaa vastaamaan luokan nimeä sanatarkasti luokan polulla sen sijaan, että yritetään implisiittisesti ennakoida kutsuvan luokan paketin nimeä. Muuntaa jokaisen "." Esiintymän. to "/" muotoilee luokan nimen kelvolliseksi URL-resurssin nimeksi, jonka luokan lataaja vaatii.

Seuraavaksi luokan lataajaa kysytään (rivit 18-19) resurssilta, joka vastaa oikein muotoiltua luokan nimeä. Joka Luokka objekti säilyttää viittauksen ClassLoader objektin, joka latasi sen, joten luokan lataaja, joka latasi sen JWhich luokka itse kuulustellaan täällä. Class.getResource () menetelmä delegoi tosiasiallisesti luokan lataajan, joka latasi luokan, palauttaen URL-osoitteen luokan tiedostoresurssin lukemiseksi tai tyhjä jos luokkatiedoston resurssia, jolla on määritetty luokan nimi, ei löydy nykyiseltä luokkaradalta.

Lopuksi näytetään määritetyn luokan nimen sisältävän luokkatiedoston absoluuttinen polunimi, jos se löydettiin nykyiseltä luokkaradalta (rivit 21-24). Virheenkorjauksen apuvälineenä, jos luokkatiedostoa ei löydy nykyiseltä luokkatiedolta, saat arvon java.class.path järjestelmän ominaisuus näyttää nykyisen luokkatien (rivit 24-28).

On helppo kuvitella, kuinka tämä yksinkertainen koodinpätkä voitaisiin kutsua Java-servletiin servlet-moottorin luokkatietä tai Enterprise JavaBean (EJB) -käyttöjärjestelmää käyttämällä EJB-palvelimen luokkatietä. Jos JWhich luokat ladattiin mukautetun luokan kuormaajan avulla esimerkiksi servlet-moottoriin, sitten servlet-moottorin luokan kuormaajaa käytettiin luokkien löytämiseen. Jos servlet-moottorin luokkakuormaaja ei pysty löytämään luokkaa, se delegoi sen vanhemmalle luokkakuormaajalle. Yleensä milloin JWhich on luokan kuormaaja ladattu, se pystyy löytämään kaikki luokkansa tai minkä tahansa vanhemman luokan kuormaajan lataamat luokat.

Johtopäätös

Jos välttämättömyys on kaikkien keksintöjen äiti, työkalu, joka auttaa hallitsemaan Java-luokkatietä, on kauan sitten myöhässä. Java-aiheiset uutisryhmät ja postituslistat ovat täynnä luokan polkuun liittyviä kysymyksiä. Meidän on alennettava uusien kehittäjien pääsyn este, jotta voimme kaikki jatkaa työskentelyä korkeammalla abstraktiotasolla. JWhich on yksinkertainen, mutta tehokas työkalu, joka auttaa hallitsemaan Java-luokkatietä missä tahansa ympäristössä.

Mike Clark on Clarkware Consultingin riippumaton konsultti, joka on erikoistunut Java-pohjaiseen arkkitehtuuriin, suunnitteluun ja J2EE-tekniikoita hyödyntävään kehitykseen. Hän on äskettäin saanut päätökseen yritysten välisen (B2B) XML -vaihtopalvelimen kehittämisen ja käyttöönoton ja on tällä hetkellä konsultti projektissa, joka rakentaa J2EE-suorituskyvyn hallintatuotetta.

Lisätietoja tästä aiheesta

  • Hanki tämän artikkelin koko lähdekoodi

    //images.techhive.com/downloads/idge/imported/article/jvw/2000/12/jwhich.zip

  • JWhichin monipuolinen versio, mukaan lukien luokkatien vahvistaja, on saatavana osoitteesta

    //www.clarkware.com/software/jwhich.zip

  • Virallinen dokumentaatio Sun JDK: sta ja siitä, miten se käsittelee luokkarataa useille virallisesti tuetuille alustoille, on saatavilla osoitteesta

    //java.sun.com/j2se/1.3/docs/tooldocs/findingclasses.html

  • Lisätietoja luokkatien asettamisesta Unix- ja Windows-alustoille, katso "Luokkatien asettaminen" osoitteessa:
  • Unix

    //java.sun.com/j2se/1.3/docs/tooldocs/solaris/classpath.html

  • Windows

    //java.sun.com/j2se/1.3/docs/tooldocs/win32/classpath.html

  • Näytä kaikki edelliset Java-vinkkejä ja lähetä oma

    //www.javaworld.com/javatips/jw-javatips.index.html

  • Jos haluat lisää Java-temppuja, tilaa ITworld.comin ilmainen Java-ohjaaja uutiskirje

    //www.itworld.com/cgi-bin/subcontent12.cgi

  • Puhu Java-aloittelijan keskustelussa, jonka moderaattori on JavaWorld kirjailija Geoff Friesen

    //www.itworld.com/jump/jw-javatip105/forums.itworld.com/webx?14@@.ee6b804/1195!skip=1125

Tämän tarinan "Java Tip 105: Luokkatien hallitseminen JWhichillä" julkaisi alun perin JavaWorld.

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