Program ładujący klasy Java — Java Classloader

Java klasy Loader jest częścią Java Runtime Environment , który ładowany dynamicznie klas Java do Java Virtual Machine . Zazwyczaj klasy są ładowane tylko na żądanie . System środowiska wykonawczego Java nie musi wiedzieć o plikach i systemach plików, ponieważ jest to delegowane do programu ładującego klasy.

Biblioteką oprogramowania to zbiór powiązanych kodu wynikowego . W języku Java biblioteki są zazwyczaj pakowane w pliki JAR . Biblioteki mogą zawierać obiekty różnego typu. Najważniejszym typem obiektu zawartego w pliku Jar jest klasa Java . Klasę można traktować jako nazwaną jednostkę kodu. Loader klas jest odpowiedzialny za lokalizowanie bibliotek, odczytywanie ich zawartości i ładowanie klas zawartych w bibliotekach. To ładowanie jest zwykle wykonywane „na żądanie”, w tym sensie, że nie występuje, dopóki klasa nie zostanie wywołana przez program. Klasa o podanej nazwie może być załadowana tylko raz przez dany ładowacz klas.

Każda klasa Java musi być ładowana przez program ładujący klasy. Ponadto programy Java mogą korzystać z bibliotek zewnętrznych (tj. bibliotek napisanych i dostarczonych przez kogoś innego niż autor programu) lub mogą składać się, przynajmniej częściowo, z kilku bibliotek.

Po uruchomieniu JVM używane są trzy programy ładujące klasy:

  1. Ładowarka klasy Bootstrap
  2. Moduł ładujący klasy rozszerzeń
  3. Ładowarka klasy systemowej

Program ładujący klasy ładowania początkowego ładuje podstawowe biblioteki Java znajdujące się w <JAVA_HOME>/jre/libkatalogu. Ten program ładujący klasy, który jest częścią podstawowej JVM, jest napisany w kodzie natywnym.

Program ładujący klasy rozszerzeń ładuje kod w katalogach rozszerzeń ( <JAVA_HOME>/jre/lib/extlub w dowolnym innym katalogu określonym przez java.ext.dirswłaściwość systemową).

Program ładujący klasy systemowe ładuje kod znaleziony na java.class.path, który jest mapowany na CLASSPATH zmienną środowiskową .

Ładowacze klas zdefiniowane przez użytkownika

Program ładujący klasy Java jest napisany w języku Java. Dzięki temu możliwe jest stworzenie własnego programu ładującego klasy bez zrozumienia drobniejszych szczegółów wirtualnej maszyny Javy. Każdy ładowacz klas Java ma nadrzędny ładowacz klas, definiowany podczas tworzenia instancji nowego ładowacza klas lub ustawiany na domyślny ładowacz klas systemu maszyny wirtualnej.

Umożliwia to (na przykład):

  • do ładowania lub rozładowywania klas w czasie wykonywania (na przykład do dynamicznego ładowania bibliotek w czasie wykonywania, nawet z zasobu HTTP ). Jest to ważna funkcja dla:
    • implementacja języków skryptowych, takich jak Jython
    • za pomocą budowniczych fasoli
    • umożliwianie rozszerzalności zdefiniowanej przez użytkownika
    • umożliwienie komunikowania się wielu przestrzeniom nazw . Jest to na przykład jeden z fundamentów protokołów CORBA / RMI .
  • aby zmienić sposób ładowania kodu bajtowego (na przykład możliwe jest użycie zaszyfrowanego kodu bajtowego klasy Java).
  • do modyfikowania załadowanego kodu bajtowego (na przykład do tkania aspektów w czasie ładowania podczas korzystania z programowania aspektowego ).

Ładowarki klas w Dżakarcie EE

Serwery aplikacji Jakarta EE (dawniej Java EE i J2EE) zazwyczaj ładują klasy z wdrożonego archiwum WAR lub EAR za pomocą drzewa programów ładujących klasy , izolując aplikację od innych aplikacji, ale dzieląc klasy między wdrożonymi modułami. Tak zwane „ kontenery serwletów ” są zazwyczaj implementowane w postaci wielu programów ładujących klasy.

JAR piekło

JAR hell jest terminem podobnym do DLL hell, używanym do opisania różnych sposobów, w jakie proces ładowania klas może nie działać. Trzy sposoby, w jakie może wystąpić piekło JAR, to:

  • Przypadkowa obecność dwóch różnych wersji biblioteki zainstalowanej w systemie. Nie zostanie to uznane przez system za błąd. Zamiast tego system załaduje klasy z jednej lub drugiej biblioteki. Dodanie nowej biblioteki do listy dostępnych bibliotek zamiast jej zastępowania może spowodować, że aplikacja nadal będzie zachowywać się tak, jakby stara biblioteka była w użyciu, co równie dobrze może być.
  • Wiele bibliotek lub aplikacji wymaga różnych wersji biblioteki foo . Jeśli wersje biblioteki foo używają tych samych nazw klas, nie ma możliwości załadowania wersji biblioteki foo za pomocą tego samego programu ładującego klasy.
  • Najbardziej złożone problemy z piekłem JAR powstają w okolicznościach, które wykorzystują pełną złożoność systemu ładowania klas. Program Java nie musi używać tylko jednego "płaskiego" programu ładującego klasy, ale zamiast tego może składać się z kilku (potencjalnie bardzo wielu) zagnieżdżonych, współpracujących programów ładujących klasy. Klasy ładowane przez różne programy ładujące klasy mogą wchodzić w interakcje w złożone sposoby, które nie są w pełni zrozumiałe przez programistę, co prowadzi do błędów lub błędów, które są trudne do przeanalizowania, wyjaśnienia i rozwiązania.

Organizacja OSGi Alliance określiła (począwszy od JSR 8 w 1998 r.) strukturę modularności, która ma na celu rozwiązanie piekła JAR dla obecnych i przyszłych maszyn wirtualnych w ME, SE i EE, która jest powszechnie stosowana. Używając metadanych w manifeście JAR , pliki JAR (nazywane pakietami) są łączone na podstawie poszczególnych pakietów. Pakiety mogą eksportować pakiety, importować pakiety i utrzymywać pakiety jako prywatne, zapewniając podstawowe konstrukcje modułowości i wersjonowanego zarządzania zależnościami.

Aby zaradzić piekielnym problemom JAR,  w 2005 r. zainicjowano Java Community Process — JSR 277. Rezolucja — Java Platform Module System  — miała na celu wprowadzenie nowego formatu dystrybucji, schematu wersjonowania modułów oraz wspólnego repozytorium modułów (podobnie Microsoft .NET „s Global Assembly Cache ). W grudniu 2008 roku Sun ogłosił, że JSR 277 został wstrzymany. Java Module System został później zrestartowany jako „projekt Jigsaw”, który został dołączony do Javy 9 .

Zobacz też

Przypisy

Bibliografia

Zewnętrzne linki