Získajte názvy tried v súbore JAR

1. Prehľad

Väčšina knižníc Java je k dispozícii ako súbory JAR. V tomto tutoriáli sa budeme venovať tomu, ako získať názvy tried v danom súbore JAR z príkazového riadku a z programu Java.

Potom sa pozrieme na príklad Java programu načítania tried z daného súboru JAR za behu.

2. Ukážkový súbor JAR

V tomto výučbe sa pozrieme na pruh-0.0.1-SNAPSHOT.jar súbor ako príklad riešenia problému, ako získať názvy tried v súbore JAR:

3. Pomocou jar Velenie

JDK sa dodáva s jar príkaz. Tento príkaz môžeme použiť s t a f možnosti vypísať obsah súboru JAR:

$ jar tf stripe-0.0.1-SNAPSHOT.jar META-INF / META-INF / MANIFEST.MF ... templates / result.html templates / checkout.html application.properties com / baeldung / stripe / StripeApplication.class com / baeldung / stripe / ChargeRequest.class com / baeldung / stripe / StripeService.class com / baeldung / stripe / ChargeRequest $ Currency.class ...

Pretože nás zaujíma iba *.trieda súborov v archíve, môžeme výstup filtrovať pomocou grep príkaz:

$ jar tf stripe-0.0.1-SNAPSHOT.jar | grep '\ .class $' com / baeldung / stripe / StripeApplication.class com / baeldung / stripe / ChargeRequest.class com / baeldung / stripe / StripeService.class com / baeldung / pruh /ChargeController.class com / baeldung / stripe / CheckoutController.class

Získate tak zoznam súborov triedy v súbore JAR.

4. Získanie názvov tried súboru JAR v prostredí Java

Pomocou jar príkaz na vytlačenie názvov tried zo súboru JAR je dosť priamy. Niekedy však chceme načítať niektoré triedy zo súboru JAR v našom programe Java. V takom prípade výstup z príkazového riadku nestačí.

Aby sme dosiahli náš cieľ, musíme skenovať súbor JAR z programu Java a získajte názvy tried.

Poďme sa pozrieť na to, ako extrahovať názvy tried z nášho ukážkového súboru JAR pomocou JarFile a JarEntry triedy:

public static Set getClassNamesFromJarFile (File givenFile) vyvolá IOException {Set classNames = new HashSet (); try (JarFile jarFile = new JarFile (givenFile)) {Enumeration e = jarFile.entries (); while (e.hasMoreElements ()) {JarEntry jarEntry = e.nextElement (); if (jarEntry.getName (). endsWith (". class")) {String className = jarEntry.getName () .replace ("/", ".") .replace (". class", ""); classNames.add (className); }} vrátiť classNames; }} 

Teraz sa pozrime bližšie na kód vo vyššie uvedenej metóde a pochopme, ako funguje:

  • skúste (JarFile jarFile = nový JarFile (givenFile)) - Tu sme na získanie príkazu try-with-resources použili príkaz jarFile z daného Súbor objekt
  • if (jarEntry.getName (). endsWith (“. class”)) {…} - Berieme každú hodinu jarEntrya zmeňte cestu k súboru triedy na kvalifikovaný názov triedy, napríklad change „Balíček1 / balík2 / SomeType.class“ do „Package1.package2.SomeType“

Poďme overiť, či metóda môže extrahovať názvy tried z nášho príkladu súboru JAR prostredníctvom metódy testovania jednotky:

private static final String JAR_PATH = "example-jar / stripe-0.0.1-SNAPSHOT.jar"; súkromná statická konečná množina EXPECTED_CLASS_NAMES = Sets.newHashSet ("com.baeldung.stripe.StripeApplication", "com.baeldung.stripe.ChargeRequest", "com.baeldung.stripe.StripeService", "com.baeldung.stripe.ChargeRequest $ "," com.baeldung.stripe.ChargeController "," com.baeldung.stripe.CheckoutController "); @Test public void givenJarFilePath_whenLoadClassNames_thenGetClassNames () vyvolá IOException, URISyntaxException {File jarFile = new File (Objects.requireNonNull (getClass (). GetClassLoader (). GetResource (JAR_PATH))). Nastaviť classNames = GetClassNamesFromJar.getClassNamesFromJarFile (jarFile); Assert.assertEquals (EXPECTED_CLASS_NAMES, názvy tried); } 

5. Získanie tried zo súboru JAR v prostredí Java

Už sme videli, ako získať názvy tried zo súboru JAR. Niekedy chceme načítať niektoré triedy zo súboru JAR za behu dynamicky.

V takom prípade môžeme najskôr získať názvy tried z daného súboru JAR pomocou nášho getClassNamesFromJarFile metóda.

Ďalej môžeme vytvoriť a ClassLoader načítať požadované triedy podľa mena:

public static Set getClassesFromJarFile (File jarFile) throws IOException, ClassNotFoundException {Set classNames = getClassNamesFromJarFile (jarFile); Nastaviť triedy = nový HashSet (classNames.size ()); try (URLClassLoader cl = URLClassLoader.newInstance (nová URL [] {nová URL ("jar: file:" + jarFile + "! /")}))) {pre (Názov reťazca: classNames) {Class clazz = cl.loadClass ( názov); // Načíta triedu podľa jej názvu classes.add (clazz); }} návratové triedy; }

Vo vyššie uvedenej metóde sme vytvorili a URLClassLoader objekt na načítanie tried. Implementácia je dosť jednoduchá.

Pravdepodobne však stojí za to trochu vysvetliť syntax adresy URL JAR. Platná adresa URL JAR obsahuje tri časti: „nádoba: + [umiestnenie súboru JAR] + !/”.

Koncová „!/”Označuje, že adresa URL JAR odkazuje na celý súbor JAR. Pozrime sa na niekoľko príkladov JAR URL:

jar: //www.example.com/some_jar_file.jar! / jar: file: /local/path/to/some_jar_file.jar! / jar: file: / C: /windows/path/to/some_jar_file.jar! /

V našom getClassesFromJarFile metódou je súbor JAR umiestnený v lokálnom súborovom systéme, preto je predpona adresy URL „spis:“.

Poďme teraz napísať testovaciu metódu na overenie, či naša metóda môže splniť všetky očakávania Trieda objekty:

@Test public void givenJarFilePath_whenLoadClass_thenGetClassObjects () vyvolá IOException, ClassNotFoundException, URISyntaxException {File jarFile = new File (Objects.requireNonNull (getClass (). GetClassLoader (). GetResource (). GetResource (). Nastaviť triedy = GetClassNamesFromJar.getClassesFromJarFile (jarFile); Nastaviť názvy = classes.stream (). Map (Class :: getName) .collect (Collectors.toSet ()); Assert.assertEquals (EXPECTED_CLASS_NAMES, mená); } 

Keď už máme požadované Trieda objekty, môžeme pomocou Java reflexie vytvoriť inštancie tried a vyvolať metódy.

6. Záver

V tomto článku sme sa naučili dva rôzne prístupy, ako získať názvy tried z daného súboru JAR.

The jar príkaz môže vytlačiť názvy tried. Je to celkom užitočné, ak potrebujeme skontrolovať, či súbor JAR obsahuje danú triedu. Ak však potrebujeme získať názvy tried zo spusteného programu Java, JarFile a JarEntry nám to môže pomôcť dosiahnuť.

Nakoniec sme videli aj príklad programu Java na načítanie tried zo súboru JAR za behu programu.

Celý zdrojový kód článku je ako vždy k dispozícii na GitHub.