W Javie klasy są ładowane do pamięci przez specjalne obiekty — loader'y klas (class loaders). Każdy loader klas tworzy swoją własną przestrzeń widoczności klas.
Rodzaje loaderów klas:
$JAVA_HOME/lib/ext.Cechy szczególne:
Czy można załadować kilka wersji tej samej klasy w procesie JVM, i jak to zrobić?
Odpowiedź: Tak, jest to możliwe, jeśli użyjesz różnych loaderów klas. Klasy z tym samym FQDN, załadowane przez różne loadery, są uważane za różne typy dla JVM.
Przykład:
ClassLoader loader1 = new URLClassLoader(new URL[]{...}); ClassLoader loader2 = new URLClassLoader(new URL[]{...}); Class clazz1 = loader1.loadClass("com.example.MyClass"); Class clazz2 = loader2.loadClass("com.example.MyClass"); System.out.println(clazz1 == clazz2); // false
Historia
W dużym systemie serwerowym korzystano z wtyczek, z których każda była łączona przez osobny custom classloader. Wtyczki wymieniały obiekty przez wspólny interfejs, również załadowany przez swój classloader. Wystąpił ClassCastException przy rzutowaniu typów, ponieważ interfejs 'PluginApi' z classloader'a wtyczki i głównego systemu był uważany za różne typy.
Historia
Próba „gorącego” ponownego ładowania serwletu przez custom classloader doprowadziła do wycieków pamięci — stara klasa nie była usuwana z pamięci, ponieważ w zmiennych statycznych gdzieś pozostawał wskaźnik. W rezultacie PermGen szybko się przepełniał.
Historia
Produkt wspierający dynamiczne ładowanie modułów niejawnie używał systemowego loadera klas, a deweloperzy przypadkowo podmienili jego rodzica, tracąc dostęp do podstawowych klas (np. z JDK). Objawiło się to w awariach, gdy nowy moduł nie mógł załadować standardowych klas Javowych, takich jak
java.sql.Driver.