Java Savjet 105: Ovladavanje stazom kroz JWhich

U jednom ili drugom trenutku programeri doživljavaju frustraciju kada se bave Java stazom. Nije uvijek jasno koju će klasu učitati učitavač klasa, posebno kada put predavanja vaše aplikacije postane preplavljen direktorijima i datotekama. U ovom ću članku predstaviti alat koji može prikazati apsolutni naziv puta učitane datoteke klase.

Osnove razredne staze

Java virtualni stroj (JVM) zapošljava učitavač klasa za učitavanje klasa koje aplikacija koristi prema potrebi. CLASSPATHVarijabla okruženja govori klase utovarivač gdje naći treće strane i korisnički definirane klase. Također možete odrediti stazu klasa po aplikaciji s -classpathargumentom JVM naredbenog retka, koji poništava put klase naveden u CLASSPATHvarijabli okruženja.

Unosi Classpath-a mogu biti direktoriji koji sadrže datoteke klasa za klase koje nisu u paketu, korijenski direktorij paketa za klase u paketu ili arhivske datoteke (poput .zip ili .jar datoteka) koje sadrže klase. Unosi putova predavanja odvojeni su dvotočkom na sustavima tipa Unix i tačkom i zarezom na MS Windows sustavima.

Učitavači razreda organizirani su u hijerarhiji delegiranja, pri čemu svaki učitavač razreda ima učitavač nadređene klase. Kada se od učitača klase zatraži da pronađe klasu, prvo delegira zahtjev svom učitelju roditeljske klase prije nego što pokuša pronaći samu klasu. Učitavač sistemske klase, zadani učitavač klase koji pruža JDK ili JRE instaliran na vašem sustavu, učitava treće i korisnički definirane klase pomoću CLASSPATHvarijable okoline ili -classpathargumenta JVM naredbenog retka. Učitavač sistemske klase delegira u klasu proširenja za učitavanje klasa koje koriste mehanizam Java Extension. Učitavač klase ekstenzije delegira učitavač klase bootstrap (back se ovdje zaustavlja!) Kako bi učitao osnovne JDK klase.

Možete razviti učitavače specijaliziranih klasa kako biste prilagodili način na koji JVM dinamički učitava klase. Na primjer, većina servlet motora koristi prilagođavač prilagođenih klasa za dinamičko ponovno učitavanje klasa servleta koji su se promijenili u direktorijima navedenim u prilagođenoj stazi klasa.

Od osobite je važnosti i mnogo zaprepaštenja, učitavač klasa učit će klase redoslijedom kojim se pojavljuju na putu predavanja. Počevši od prvog unosa puta klase, učitavač klase posjećuje svaki navedeni direktorij ili arhivsku datoteku pokušavajući pronaći klasu za učitavanje. Učitava se prva klasa koju pronađe s vlastitim imenom, a svi preostali unosi puta klase se zanemaruju.

Zvuči jednostavno, zar ne?

Prevara s putovima u razredu

Bi li oni to priznali ili ne, početnike i veterane Java programere u jednom je trenutku (obično u najgorem mogućem trenutku!) Prevario teški put predavanja. Kako se broj aplikacijskih klasa nezavisnih i korisnički definiranih klasa povećava, a put klasa postaje odlagalište za svaki zamislivi direktorij i arhivsku datoteku, nije uvijek očito koju će klasu učitavač klasa prvo učitati. To je osobito istinito u nesretnom slučaju da put predavanja sadrži dvostruke unose klase. Zapamtite, učitavač klasa učitava prvu pravilno imenovanu klasu koju pronađe u stazi razreda i učinkovito "skriva" sve ostale pravilno imenovane klase nižeg prioriteta.

Previše je lako postati žrtvom ovog trika s putovima u razredu. Nakon dugog dana robovanja preko vruće tipkovnice, dodate dodavanje direktorija na stazu u pokušaju da se najnovija i najveća verzija klase učita u aplikaciju, a pritom niste svjesni da se druga inačica klase nalazi u direktoriju veći prioritet u razrednoj stazi. Imam te!

JWhich: Jednostavan alat za put kroz nastavu

Problem prioriteta svojstven deklaraciji ravnog puta nije jedinstven za Java classpath. Da biste pronašli rješenje problema, potrebno je samo da stojite na ramenima legendarnih softverskih divova. Naredba operativnog sustava Unix whichuzima ime i prikazuje naziv puta datoteke koja bi se izvršila da je ime izdano kao naredba. U osnovi prelazi PATHvarijablu okoline da bi locirao prvu pojavu naredbe. To također zvuči kao moćan alat za upravljanje Java stazom. Inspiriran tim pojmom, počeo sam pisati Java uslužni program koji bi mogao uzeti naziv Java klase i prikazati apsolutni naziv puta datoteke klase koju bi učitavač klase učitao, kako je propisao classpath.

Sljedeći primjer upotrebe JWhichprikazuje apsolutni naziv puta prve pojave com.clarkware.ejb.ShoppingCartBeanklase koju učitavač klase učitava, a koja se nalazi u direktoriju:

 > java JWhich com.clarkware.ejb.ShoppingCartBean Class 'com.clarkware.ejb.ShoppingCartBean' pronađen u '/home/mclark/classes/com/clarkware/ejb/ShoppingCartBean.class' 

Sljedeći primjer upotrebe JWhichprikazuje apsolutni naziv puta prvog pojavljivanja javax.servlet.http.HttpServletklase koju učitava učitava učitava, a koje je pakirano u arhivsku datoteku:

 > java JWhich javax.servlet.http.HttpServlet Class 'javax.servlet.http.HttpServlet' pronađen u 'file: /home/mclark/lib/servlet.jar! /javax/servlet/http/HttpServlet.class' 

Kako JWhich djeluje

Da biste nedvosmisleno odredili koja će se klasa učitati prva na putu predavanja, morate ući u um učitavača klasa. Ovo nije tako teško koliko zvuči - samo pitajte! Relevantni izvorni kod za JWhichslijedi. Potpuni izvorni kod potražite u odjeljku Resursi.

1: javna klasa JWhich {2: 3: / ** 4: * Ispisuje apsolutni naziv puta datoteke klase 5: * koji sadrži navedeno ime klase, kako je propisano 6: * trenutnom stazom razreda. 7: * 8: * @param className Naziv klase. 9: * / 10: javna statička praznina which (String className) {11: 12: if (! ClassName.startsWith ("/")) {13: className = "/" + className; 14:} 15: className = className.replace ('.', '/'); 16: className = className + ".class"; 17: 18: java.net.URL classUrl = 19: new JWhich (). GetClass (). GetResource (className); 20: 21: if (classUrl! = Null) {22: System.out.println ("\ nClass '" + className + 23: "' pronađen u \ n '" + classUrl.getFile () + "'"); 24:} else {25: System.out.println ("\ nClass '" + className + 26: "' nije pronađen u \ n '"+ 27: System.getProperty (" java.class.path ") +" '"); 28:} 29:} 30: 31: javna statička void glavna (String args []) {32: if (args.length > 0) {33: JWhich.which (args [0]); 34:} else {35: System.err.println ("Upotreba: java JWhich"); 36:} 37:} 38:}

Prvo trebate malo izmasirati naziv razreda kako biste postigli prihvaćanje učitavača klase (retci 12-16). Dodavanje znaka "/" na ime klase upućuje učitavač klase da se ime klase doslovno podudara unutar puta klase, umjesto da pokušava implicitno dodati ime paketa pozivajuće klase. Pretvaranje svake pojave "." to "/" formatira naziv klase kao valjano ime resursa URL-a koje traži učitavač klase.

Zatim se učitavač klase ispituje (retci 18-19) za resurs koji odgovara ispravno formatiranom nazivu klase. Svaki Classobjekt održava referencu na ClassLoaderobjekt koji ga je učitao, pa se JWhichovdje ispituje učitavač klase koji je učitao samu klasu. Class.getResource()Metoda zapravo delegati u razred utovarivač koji učitava klasa, vraća URL za čitanje klase datoteke resursa, ili nullako klasa datoteka resursa s navedenim nazivom klase ne može se naći u aktualnom CLASSPATH.

Napokon, prikazuje se apsolutni naziv puta datoteke klase koja sadrži navedeno ime klase, ako je pronađena u trenutnoj stazi klase (retci 21-24). Kao pomoć pri otklanjanju pogrešaka, ako datoteka klase nije pronađena u trenutnom putu klase, dobit ćete vrijednost java.class.pathsvojstva sustava za prikaz trenutne staze razreda (retci 24-28).

Lako je zamisliti kako bi se ovaj jednostavni komad koda mogao pozvati u Java servletu pomoću staze motora servleta ili Enterprise JavaBean (EJB) koristeći stazu EJB poslužitelja. Ako je JWhichklasu učitao prilagođavač prilagođene klase u servlet mehanizmu, na primjer, tada bi se učitavač klase servlet motora koristio za pronalaženje klasa. Ako učitavač klase motora servleta ne može pronaći klasu, on će delegirati svom učitatelju nadređene klase. Općenito, kada JWhichga učita učitavač klase, on može pronaći sve klase učitane učitačem svoje klase ili bilo kojim učitavačima roditeljske klase.

Zaključak

Ako je nužnost majka cijelog izuma, tada je alat koji pomaže u upravljanju stazom Java razreda već odavno prekasan. Grupe vijesti i popisi za slanje povezane s Javom prepuni su pitanja koja se odnose na put predavanja. Moramo spustiti prepreku ulasku za nove programere kako bismo svi mogli nastaviti raditi na višim razinama apstrakcije. JWhichje jednostavan, ali moćan alat koji će vam pomoći u svladavanju Java staze u bilo kojem okruženju.

Mike Clark neovisni je savjetnik za Clarkware Consulting, specijaliziran za arhitekturu, dizajn i razvoj zasnovan na Javi koristeći J2EE tehnologije. Nedavno je završio razvoj i implementaciju poslovnog (B2B) XML poslužitelja za razmjenu, a trenutno je savjetnik za projekt izgradnje J2EE proizvoda za upravljanje učinkom.

Saznajte više o ovoj temi

  • Obtain the full source code for this article

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

  • A full-featured version of JWhich, including a classpath validator, is available at

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

  • Official documentation for the Sun JDK and how it deals with the classpath for the various officially supported platforms is available at

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

  • For details on how to set the classpath on Unix and Windows platforms, see "Setting the classpath" at:
  • Unix

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

  • Windows

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

  • View all previous Java Tips and submit your own

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

  • Za više Java trikova pretplatite se na ITworld.com besplatni bilten Java Tutor

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

  • Govorite u raspravi o početnicima Java, moderirao autor JavaWorlda Geoff Friesen

    //www.itworld.com/jump/jw-javatip105/forums.itworld.com/[email protected]@.ee6b804/1195!skip=1125

Ovu priču, "Java tip 105: Ovladavanje putovima predavanja s JWhich" izvorno je objavio JavaWorld.