Osztályok nevének beolvasása egy JAR fájlba

1. Áttekintés

A legtöbb Java könyvtár JAR fájlként érhető el. Ebben az oktatóanyagban kitérünk arra, hogyan lehet lekérdezni az osztályok nevét egy adott JAR fájlban a parancssorból és a Java programból.

Ezután megnézünk egy Java programot, amely az adott JAR fájlból futtatja az osztályokat futás közben.

2. Példa JAR fájlra

Ebben az oktatóanyagban a csík-0.0.1-SNAPSHOT.jar fájl példaként az osztálynevek JAR fájlba való beolvasására:

3. A befőttes üveg Parancs

A JDK a befőttes üveg parancs. Használhatjuk ezt a parancsot a t és f opciók a JAR fájl tartalmának felsorolásához:

$ 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 ...

Mivel minket csak a *.osztály fájlokat az archívumban, a kimenetet a grep parancs:

$ jar tf strip-0.0.1-SNAPSHOT.jar | grep '\ .class $' com / baeldung / csík / StripeApplication.class com / baeldung / csík / ChargeRequest.class com / baeldung / csík / StripeService.class com / baeldung / csík / ChargeRequest $ Currency.class com / baeldung / csík /ChargeController.class com / baeldung / stripe / CheckoutController.class

Ez megadja nekünk a JAR fájlban található osztályfájlok listáját.

4. JAR fájlok osztályneveinek megszerzése Java-ban

Használni a befőttes üveg az osztálynevek JAR fájlból történő kinyomtatására szolgáló parancs elég egyszerű. Néha azonban néhány osztályt egy JAR fájlból szeretnénk betölteni a Java programunkba. Ebben az esetben a parancssori kimenet nem elég.

Célunk eléréséhez meg kell beolvasni a JAR fájlt egy Java programból és megkapja az osztályneveket.

Vessünk egy pillantást arra, hogyan lehet kibontani az osztályneveket a példa JAR fájlból használni a JarFile és JarEntry osztályok:

public static set getClassNamesFromJarFile (File megadottFile) dobja az IOException {Set classNames = new HashSet (); try (JarFile jarFile = új JarFile (adottFile)) {Enumeráció e = jarFile.entries (); while (e.hasMoreElements ()) {JarEntry jarEntry = e.nextElement (); if (jarEntry.getName (). endWith (". class")) {String className = jarEntry.getName () .replace ("/", ".") .replace (". class", ""); classNames.add (className); }} return classNames; }} 

Most nézzük meg közelebbről a fenti módszer kódját, és értsük meg, hogyan működik:

  • próbáld ki (JarFile jarFile = új JarFile (megadottFile)) - Itt egy try-with-resources nyilatkozatot használtunk a jarFile az adottból File tárgy
  • if (jarEntry.getName (). endWith-tel (“.. osztály”)) {…} - Minden osztályt felveszünk jarEntry, és módosítsa például az osztályfájl elérési útját minősített osztálynévre „Package1 / package2 / SomeType.class” -ba „Package1.package2.SomeType”

Ellenőrizzük, hogy a módszer képes-e kivonni az osztályneveket a JAR példafájlunkból az egység teszt módszerével:

privát statikus végső karakterlánc JAR_PATH = "példa-jar / csík-0.0.1-SNAPSHOT.jar"; privát statikus végleges készlet EXPECTED_CLASS_NAMES = Sets.newHashSet ("com.baeldung.stripe.StripeApplication", "com.baeldung.stripe.ChargeRequest", "com.baeldung.stripe.StripeService", "com.baeldung.stripe.striest.Chripe.stripe.Commerce "," com.baeldung.stripe.ChargeController "," com.baeldung.stripe.CheckoutController "); @Test public void givenJarFilePath_whenLoadClassNames_thenGetClassNames () dobja az IOException, URISyntaxException {File jarFile = új fájl (Objects.requireNonNull (getClass (). GetClassLoader (). GetResource (JAR_PAT) Set classNames = GetClassNamesFromJar.getClassNamesFromJarFile (jarFile); Assert.assertEquals (EXPECTED_CLASS_NAMES, osztálynév); } 

5. Osztályok megszerzése JAR fájlból Java-ban

Láttuk, hogyan lehet megszerezni az osztályneveket egy JAR fájlból. Néha dinamikusan futás közben szeretnénk betölteni néhány osztályt egy JAR fájlból.

Ebben az esetben először az adott JAR fájlból szerezhetjük be az osztályneveket a mi használatunkkal getClassNamesFromJarFile módszer.

Ezután létrehozhatunk egy ClassLoader a szükséges osztályok név szerinti betöltése:

public static set getClassesFromJarFile (File jarFile) dobja az IOException, ClassNotFoundException {Set classNames = getClassNamesFromJarFile (jarFile); Set class = new HashSet (classNames.size ()); try (URLClassLoader cl = URLClassLoader.newInstance (új URL [] {új URL ("jar: fájl:" + jarFile + "! /")}))) {for (Karakterlánc neve: classNames) {Osztály clazz = cl.loadClass ( név); // Töltse be az osztályt a neve alapján class.add (clazz); }} visszatérő osztályok; }

A fenti módszerrel létrehoztuk a URLClassLoader objektum az osztályok betöltéséhez. A megvalósítás elég egyszerű.

Valószínűleg azonban érdemes egy kicsit elmagyarázni a JAR URL szintaxisát. Az érvényes JAR URL három részből áll: „befőttes üveg: + [a JAR fájl helye] + !/”.

A megszűnő „!/”Azt jelzi, hogy a JAR URL egy teljes JAR fájlra vonatkozik. Nézzünk meg néhány JAR URL-példát:

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! /

Miénkben getClassesFromJarFile metódus esetén a JAR fájl a helyi fájlrendszeren található, ezért az URL előtagjafájl:“.

Most írjunk egy tesztmódszert annak ellenőrzésére, hogy a módszerünk képes-e minden elvártra Osztály tárgyak:

@Test public void givenJarFilePath_whenLoadClass_thenGetClassObjects () dobja az IOException, ClassNotFoundException, URISyntaxException {File jarFile = új fájl (Objects.requireNonNull (getClass (). Get) CLASSLoadUR (). Set class = GetClassNamesFromJar.getClassesFromJarFile (jarFile); Set names = class.stream (). Map (Class :: getName) .collect (Collectors.toSet ()); Assert.assertEquals (EXPECTED_CLASS_NAMES, nevek); } 

Ha megvan a szükséges Osztály objektumokat, a Java tükrözéssel osztályok példányait hozhatjuk létre és metódusokat hívhatunk meg.

6. Következtetés

Ebben a cikkben két különböző megközelítést tanultunk meg az osztálynevek megszerzéséhez egy adott JAR fájlból.

A befőttes üveg paranccsal kinyomtathatja az osztályneveket. Nagyon hasznos, ha ellenőriznünk kell, hogy egy JAR fájl tartalmaz-e egy adott osztályt. Ha azonban egy futó Java programból kell megszereznünk az osztályneveket, JarFile és JarEntry segíthet elérni ezt.

Végül láttunk egy példát egy Java programra is, amely futás közben JAR fájlból töltött osztályokat.

Mint mindig, a cikk teljes forráskódja elérhető a GitHubon.