Programování

Java Tip 105: Zvládnutí cesty ke třídě s JWhich

Vývojáři v té či oné době pociťují frustraci při jednání s třídou Java. Není vždy jasné, kterou třídu zavaděč tříd načte, zvláště když je classpath vaší aplikace zaplaven adresáři a soubory. V tomto článku představím nástroj, který dokáže zobrazit absolutní cestu k načtenému souboru třídy.

Základy třídní cesty

Virtuální stroj Java (JVM) zaměstnává zavaděč tříd k načítání tříd používaných aplikací podle potřeby. The CLASSPATH Proměnná prostředí říká zavaděči tříd, kde najít třídy třetích stran a uživatelem definované třídy. Classpath pro každou aplikaci můžete určit také pomocí -classpath Argument příkazového řádku JVM, který přepíše cestu ke třídě uvedenou v souboru CLASSPATH proměnná prostředí.

Položky třídy Classpath mohou být adresáře, které obsahují soubory tříd pro třídy, které nejsou v balíčku, kořenový adresář balíčku pro třídy v balíčku, nebo archivní soubory (například soubory .zip nebo .jar), které obsahují třídy. Položky třídy Classpath jsou v systémech typu Unix odděleny dvojtečkou a v systémech MS Windows odděleny středníkem.

Zavaděče tříd jsou organizovány v hierarchii delegování, přičemž každý zavaděč tříd má zavaděč tříd rodičů. Když je zavaděč třídy vyzván k vyhledání třídy, nejprve deleguje požadavek na svého zavaděče nadřazené třídy, než se pokusí najít samotnou třídu. Zavaděč systémových tříd, výchozí zavaděč tříd poskytovaný JDK nebo JRE nainstalovanými ve vašem systému, načítá třídy třetích stran a uživatelem definované třídy pomocí CLASSPATH proměnná prostředí nebo -classpath Argument příkazového řádku JVM. Zavaděč systémových tříd deleguje na třídu rozšíření načtení tříd, které používají mechanismus rozšíření Java. Zavaděč třídy rozšíření deleguje na zavaděč třídy bootstrap (tu se buck zastaví!), Aby načetl základní třídy JDK.

Můžete vyvinout specializované zavaděče tříd, abyste přizpůsobili, jak JVM dynamicky načítá třídy. Například většina servletových strojů používá zavaděč vlastních tříd k dynamickému opětovnému načtení tříd servletů, které se změnily v adresářích určených ve vlastní třídě cesty.

Zejména důležité a velké zděšení zavaděč tříd načte třídy v pořadí, v jakém se objevují v cestě ke třídě. Počínaje prvním záznamem classpath navštěvuje zavaděč třídy každý zadaný adresář nebo archivní soubor a pokouší se najít třídu k načtení. Načte se první třída, kterou najde se správným názvem, a všechny zbývající položky cesty ke třídě jsou ignorovány.

Zní to jednoduše, že?

Podvod třídy

Ať už si to připouštějí nebo ne, začátečníci i veteráni Java vývojáři byli v určitém okamžiku (obvykle v nejhorším možném okamžiku!) Podvedenou obtížnou cestou oklamáni. Jak se pro aplikaci zvyšuje počet závislých tříd třetích stran a uživatelem definovaných tříd a classpath se stává skládkou pro všechny myslitelné adresáře a archivní soubory, není vždy zřejmé, kterou třídu zavaděč tříd načte jako první. To platí zejména v nešťastné události, že classpath obsahuje duplicitní položky třídy. Nezapomeňte, že zavaděč tříd načte první správně pojmenovanou třídu, kterou najde ve třídě, a efektivně „skryje“ všechny ostatní správně pojmenované třídy nižší priority.

Je až příliš snadné se stát obětí této trikové cesty ke třídě. Po dlouhém dni otrokování přes horkou klávesnici připojíte adresář do classpath ve snaze získat nejnovější a nejlepší verzi třídy načtené do aplikace, aniž byste věděli, že jiná verze třídy je umístěna v adresáři vyšší priorita v cestě ke třídě. Mám tě!

JWhich: Jednoduchý nástroj pro cestu ke třídě

Problém priority inherentní deklaraci ploché cesty není pro třídu Java jedinečný. Hledání řešení problému vyžaduje pouze to, abyste stáli na bedrech legendárních softwarových gigantů. Operační systém Unix který příkaz vezme jméno a zobrazí cestu k souboru, který by byl spuštěn, kdyby byl název vydán jako příkaz. V podstatě prochází CESTA proměnná prostředí k vyhledání prvního výskytu příkazu. To zní také jako mocný nástroj pro správu třídy Java. Inspirován touto představou jsem se pustil do psaní nástroje Java, který by mohl převzít název třídy Java a zobrazit absolutní cestu k souboru třídy, který by načetl zavaděč třídy, jak předepisuje classpath.

Následující příklad použití JKterý zobrazí absolutní cestu prvního výskytu com.clarkware.ejb.ShoppingCartBean třída, která má být načtena zavaděčem třídy, který je náhodou v adresáři:

 > java JWhich com.clarkware.ejb.ShoppingCartBean Class 'com.clarkware.ejb.ShoppingCartBean' nalezený v '/home/mclark/classes/com/clarkware/ejb/ShoppingCartBean.class' 

Následující příklad použití JKterý zobrazí absolutní cestu prvního výskytu javax.servlet.http.HttpServlet třída, která se má načíst zavaděčem třídy, který se stane zabaleným v archivním souboru:

 > Java JWhich javax.servlet.http.HttpServlet Class 'javax.servlet.http.HttpServlet' found in 'file: /home/mclark/lib/servlet.jar! /javax/servlet/http/HttpServlet.class' 

Jak JKteré funguje

Chcete-li jednoznačně určit, která třída bude načtena jako první v cestě ke třídě, musíte se dostat do mysli zavaděče tříd. To není tak obtížné, jak to zní - jednoduše se zeptáte! Příslušný zdrojový kód pro JKterý následuje. Úplný zdrojový kód najdete v tématu zdroje.

1: public class JWhich {2: 3: / ** 4: * Vytiskne absolutní cestu k souboru třídy 5: * obsahující zadaný název třídy, jak je předepsáno 6: * aktuální třídou. 7: * 8: * @param className Název třídy. 9: * / 10: public static void 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: "' nalezen v \ n '" + classUrl.getFile () + "'"); 24:} else {25: System.out.println ("\ nClass '" + className + 26: "' nebyl nalezen v \ n '" + 27: System.getProperty ("java.class.path") + "' "); 28:} 29:} 30: 31: public static void main (String args []) {32: if (args.length> 0) {33: JWhich.which (args [0]); 34:} else {35: System.err.println ("Použití: java JWhich"); 36:} 37:} 38:} 

Nejprve musíte trochu namasírovat název třídy, abyste získali přijetí zavaděčem třídy (řádky 12-16). Příprava znaku „/“ na název třídy dává instrukci zavaděči třídy, aby doslovně odpovídal názvu třídy v rámci cesty třídy, místo aby se pokusil implicitně předřadit název balíčku vyvolávající třídy. Převod každého výskytu „.“ na „/“ naformátuje název třídy jako platný název prostředku URL požadovaný zavaděčem třídy.

Dále je dotazován zavaděč třídy (řádky 18-19) pro prostředek odpovídající správně naformátovanému názvu třídy. Každý Třída objekt udržuje odkaz na ClassLoader objekt, který jej načetl, takže zavaděč třídy, který jej načetl JKterý samotná třída je zde vyslýchána. The Class.getResource () metoda ve skutečnosti deleguje na zavaděč třídy, který načetl třídu, vrací adresu URL pro čtení prostředku souboru třídy, nebo nula pokud nebyl v aktuální třídě nalezen prostředek souboru třídy se zadaným názvem třídy.

Nakonec se zobrazí absolutní cesta k souboru třídy obsahující zadaný název třídy, pokud byla nalezena v aktuální cestě ke třídě (řádky 21–24). Jako ladicí pomůcka, pokud nebyl soubor třídy nalezen v aktuální třídě, získáte hodnotu cesta java.class.path vlastnost systému pro zobrazení aktuální cesty ke třídě (řádky 24-28).

Je snadné si představit, jak lze tento jednoduchý kus kódu vyvolat v servletu Java pomocí třídy cesty servletu nebo Enterprise JavaBean (EJB) pomocí cesty třídy EJB serveru. Pokud JKterý Například třída byla načtena pomocí vlastního zavaděče tříd v servletovém motoru, pak by se k vyhledání tříd použil zavaděč třídy servletového motoru. Pokud zavaděč tříd servletového motoru není schopen najít třídu, bude delegován na zavaděč své nadřazené třídy. Obecně, když JKterý je načten zavaděčem tříd, je schopen najít všechny třídy načtené jeho zavaděčem tříd nebo jakýmkoli zavaděčem nadřazené třídy.

Závěr

Pokud je nutnost matkou všeho vynálezu, pak nástroj, který pomáhá spravovat cestu ke třídě Java, je již dávno zpožděn. Diskusní skupiny a e-mailové seznamy související s jazykem Java jsou plné otázek týkajících se cesty ke třídě. Musíme snížit bariéru vstupu nových vývojářů, abychom mohli všichni pokračovat v práci na vyšších úrovních abstrakce. JKterý je jednoduchý, ale výkonný nástroj, který vám pomůže zvládnout cestu ke třídě Java v jakémkoli prostředí.

Mike Clark je nezávislým konzultantem společnosti Clarkware Consulting se specializací na architekturu, design a vývoj založenou na Javě pomocí technologií J2EE. Nedávno dokončil vývoj a nasazení serveru pro výměnu dat mezi podniky (B2B) XML a v současné době je konzultantem projektu budování produktu pro správu výkonu J2EE.

Další informace o tomto tématu

  • Získejte úplný zdrojový kód pro tento článek

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

  • Plně vybavená verze JWhich, včetně validátoru třídy, je k dispozici na

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

  • Oficiální dokumentace pro Sun JDK a informace o tom, jak řeší cestu ke třídě pro různé oficiálně podporované platformy, je k dispozici na

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

  • Podrobnosti o tom, jak nastavit cestu ke třídě na platformách Unix a Windows, najdete v části „Nastavení cesty ke třídě“ na adrese:
  • Unix

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

  • Okna

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

  • Zobrazit všechny předchozí Tipy pro Java a odešlete vlastní

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

  • Chcete-li získat další triky Java, přihlaste se k odběru ITworld.com zdarma Java Tutor zpravodaj

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

  • Promluvte v diskusi Java Beginner, kterou moderuje JavaWorld autor Geoff Friesen

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

Tento příběh „Java Tip 105: Mastering the classpath with JWhich“ původně publikoval JavaWorld.