ClassLoader — to specjalny komponent w JVM, odpowiedzialny za ładowanie bajt-kodu klas do pamięci przy ich pierwszym użyciu. Pozwala na dynamiczne ładowanie klas z różnych źródeł (systemu plików, sieci, archiwów itp.).
Typy loaderów klas:
jre/lib/ext.ClassLoader implementuje delegację: najpierw próbuje załadować klasę z loadera rodzica (parent-first), dopiero jeśli się nie uda — szuka sam.
Izolacja klas: Każdy loader klas tworzy swoją "dziedzinę widoczności" klas. Dwie klasy o tej samej nazwie, załadowane przez różne loadery, są uważane za różne typy w JVM.
Przykład stworzenia własnego loadera:
class MyClassLoader extends ClassLoader { @Override protected Class<?> findClass(String name) throws ClassNotFoundException { // Twój kod do wyszukiwania i ładowania bajt-kodu klasy return super.findClass(name); } }
Czy dwie klasy o tej samej nazwie, załadowane przez różne loadery, mogą być uważane za tę samą klasę w JVM?
Odpowiedź: Nie! JVM uważa klasę za unikalną na podstawie pary (pełna nazwa klasy, loader klas). Dlatego te same klasy, załadowane przez różne loadery, będą uważane za różne.
Historia
W aplikacji enterprise z obsługą architektury plug-in wtyczki były ładowane przez oddzielne loaderzy klas. W rezultacie próba przesyłania obiektu typu interfejsu (PluginInterface) między główną aplikacją a wtyczką powodowała ClassCastException, ponieważ ten sam interfejs był ładowany przez różne loadery.
Historia
W przypadku użycia niestandardowego loadera klas nie zrealizowano delegacji do loadera rodzica. Doprowadziło to do ponownego ładowania standardowych klas bibliotecznych, co wywołało dziwne błędy ClassCastException i LinkageError.
Historia
Na dużym serwerze Java EE różne aplikacje ładowały swoje wersje tej samej biblioteki. Niedbałość w konfiguracji łańcucha loaderów spowodowała, że klasy krzyżowały się między aplikacjami, co pewnego razu doprowadziło do massive memory leak i awarii z powodu konfliktów wersji.