Java Classloader

Java futtató környezet része

A Java Classloader (magyarul Java osztálybetöltő), amely dinamikusan tölti be a Java osztályokat a Java virtuális gépbe, része a Java futtató környezetnek (angolul: Java Runtime Environment).[1] Az osztályok betöltése a Java virtuális gépbe igény szerint történik. A Java futtatható környezetnek nem kell ismernie a fájlok elhelyezkedését vagy fájl rendszert, mivel ezek felderítését a classloader végzi. A classloader megértéséhez fontos megérteni a delegáció fogalmát.

A szoftverkönyvtár a kapcsolódó objektum kódok egy gyűjteménye. A Java programozási nyelv könyvtárai tipikusan JAR fájlba vannak csomagolva. A könyvtárak különböző objektum típusokat tárolnak. A legfontosabb objektum típus a java osztály jar fájlban. Az osztály nem más, mint a kód egy nevesített egysége. A classloader felelős a könyvtárak megtalálásáért, olvasásáért, és az osztályok különböző könyvtárakból való betöltésért. A betöltés tipikusan kérésre hajtódik végre. Az osztály betöltése nem hajtódik végre használaton kívüli osztályoknál, vagy nem hajtódik végre még egyszer, ha az adott osztályt egy másik program már használja. Egy osztály egy adott nevén egy időben csak egyszer töltődhet be egy adott classloaderrel.

Minden java osztályt egy classloader tölt be.[2] Továbbá a Java programok igénybe vehetnek külső könyvtárakat (azaz olyan könyvtárakat, amelyeket más által írt és támogatott forrástól származnak) vagy legalább részben külső forrásokból származó könyvtárakat.

A java futtató környezet indulásához három classloadert használ:[3][4]

  1. Bootstrap classloader
  2. Extensions classloader
  3. System classloader

A bootstrap classloader betölti a főbb java könyvtárakat,[5] melyek a <JAVA_HOME>/jre/lib mappában helyezkednek el. Ezt a classloadert, amely része a Java virtuális gépnek, natív kódban írták.

Az extensions classloader betölti a kódot az extensions(kiterjesztés) mappából (<JAVA_HOME>/jre/lib/ext, vagy bármilyen olyan mappából, amelyet a java.ext.dirs meghatároz). Ezt a sun.misc.Launcher$ExtClassLoader osztály valósítja meg.

A system classloader betölti a java.class.path változó által meghatározott osztályokat, amelyet a rendszer CLASSPATH-ára map-olja le. Ezt a sun.misc.Launcher$AppClassLoader osztály valósítja meg.

Felhasználó által definiált classloader szerkesztés

A Java class loader-t java-ban írják. Ilyen módon lehetséges saját class loadert írni a Java virtuális gép mélyebb ismerete nélkül. Minden Java class loadernek van egy szülő class loader-e, amely meghatározása akkor történik meg, amikor az új class loader példányosítása ill. beállítása a virtuális gép alapértelmezett rendszer class loaderére megtörténik.

Mindez lehetővé teszi a következőket (pl):

  • betölteni, vagy betöltetlenné tenni osztályokat futási időben (példa a dinamikus osztály betöltésre a HTTP resource). Ez egy fontos tulajdonság a következőkhöz:
    • script nyelv implementálásához, mint például Jython
    • bean buildereknél,
    • felhasználó engedélyezésekhez kiterjesztéséhez
    • A több névtér kommunikációjához. Ezen alapszik a CORBA / RMI protokoll, például.
  • megváltoztatni annak a módját, ahogy a bájtkód betöltődik (pl. lehetséges kódolt Java class bájt kódot használni[6]).
  • megváltoztatni a bájt kód betöltésének útvonalát.
  • módosítani a bájt kód betöltést.

Classloader-ek a JEE-ben szerkesztés

A Java Platform, Enterprise Edition (JEE) alkalmazás szerver tipikusan WAR fájlból tölti be vagy EAR faként csomagolt class loader, elszigeteli az alkalmazást más alkalmazásoktól, de megossza a modult a telepített modulok közt. Úgynevezett "servlet gyűjtemények" tipikusan összetett class loader-ekhez vannak implementálva.[2][7]

JAR hell szerkesztés

JAR hell nagyon hasonlóan a DLL hell-hez leírja az összes lehetséges utat, amellyel az osztály betöltő funkció megállhat.[8] Három út amely JAR hell-t okozhat:

  • Az első változat amikor a fejlesztő vagy a telepítő véletlenül két különböző verziójú könyvtárt csinál az elérhető rendszerben. Ezt a rendszer nem fogja hibaként kijelezni. Inkább megpróbálja a rendszer betölteni az egyikből, vagy egy teljesen másikból. Új könyvtár hozzáadása a régiek mellé, ahelyett hogy kicserélődne a régi az újra, ezért az alkalmazás a régi könyvtárat fogja használni a frissebb helyett.
  • Másik verzió probléma mikor két könyvtár egy harmadikat szeretne használni, de eltérő verzióval. Ha mindkét verzióban ugyanazokat az osztályneveket használják, nincs lehetőség betölteni az osztályt ugyanazzal az osztálybetöltővel.
  • A legkomplexebb JAR hell probléma előfordulás akkor, amikor ki akarják használni az osztálybetöltő rendszer által nyújtott előnyöket. A Java program nem követeli meg, hogy egyetlen osztálybetöltő működjön. Osztályokat betölthetünk több más osztálybetöltővel, amelyek egymásba vannak ágyazva, és együttműködnek egymással. A több osztálybetöltővel betöltött osztályok kölcsönhatásba kerülnek egymással, amelyet a fejlesztő nem biztos, hogy tud követni. Ez megmagyarázhatatlan hibákhoz vezet.[9]

Az OSGi szövetség lerögzített , és JSR 8 néven 1998-ban kiadott egy moduláris keretrendszert, amely megoldja a JAR hell problémát jelenleg és a jövőben a Java SE, ME és EE számára is. A JAR fájl manifestjében levő metaadatok alapján a JAR fájl egy csomagonkénti bázishoz tartozik. A JAR fájl korlátlanul exportálhat, importál csomagokat, az import csomagok megőrzik az alapvető konstrukciójukat, modularitásukat, és verziózott függőségüket.

A gyógyír a JAR hell problémákra a Java Community Process - jsr 277, amelyet 2005-ben hívtak életre. Határozat született az új forgalmazási formátumra (Java Platform Module System), modul verzió sémára, és közös modultárolókra., hasonlóan a Microsoft .NET's Global Assembly Cache-hez. 2008 decemberében a Sun bejelentette, hogy megtartja a JSR 277-et.[10] A Java Module Systemet később project Jigsaw néven indították újra, melyet a Java 9 beépítetten tartalmaz.[11]

Lásd még szerkesztés

Jegyzetek szerkesztés

  1. Mcmanis, Chuck: The basics of Java class loaders. JavaWorld, 1996. október 1. [2008. január 20-i dátummal az eredetiből archiválva]. (Hozzáférés: 2008. január 26.)
  2. a b Christudas, Binildas: Internals of Java Class Loading. onjava.com, 2005. január 26. (Hozzáférés: 2009. október 2.)
  3. Understanding Extension Class Loading. java.sun.com, 2008. február 14. (Hozzáférés: 2009. december 8.)
  4. Sosnoski, Dennis: Classes and class loading. ibm.com, 2003. április 29. (Hozzáférés: 2008. január 26.)
  5. Ezek a könyvtárak a következő Jar fájlokban helyezkednek el: rt.jar, core.jar, server.jar, etc.
  6. Roubtsov, Vladimir: Cracking Java byte-code encryption. javaworld.com, 2003. május 9. [2008. május 2-i dátummal az eredetiből archiválva]. (Hozzáférés: 2008. január 26.)
  7. J2EE Class Loading Demystified. ibm.com, 2002. augusztus 21. (Hozzáférés: 2008. január 26.)
  8. http://incubator.apache.org/depot/version/jar-hell.html
  9. http://articles.qos.ch/classloader.html
  10. Archivált másolat. [2012. március 2-i dátummal az eredetiből archiválva]. (Hozzáférés: 2012. május 20.)
  11. Project Jigsaw. Oracle Corporation. (Hozzáférés: 2015. november 29.)

Külső hivatkozások szerkesztés

Fordítás szerkesztés

Ez a szócikk részben vagy egészben a Java Classloader című angol Wikipédia-szócikk fordításán alapul. Az eredeti cikk szerkesztőit annak laptörténete sorolja fel. Ez a jelzés csupán a megfogalmazás eredetét és a szerzői jogokat jelzi, nem szolgál a cikkben szereplő információk forrásmegjelöléseként.