Wiem, że to może być głupie pytanie dla doświadczonych programistów. Ale mam bibliotekę (klienta http), której wymagają niektóre inne frameworki / pliki JAR używane w moim projekcie. Ale wszystkie wymagają różnych głównych wersji, takich jak:
httpclient-v1.jar => Required by cralwer.jar
httpclient-v2.jar => Required by restapi.jar
httpclient-v3.jar => required by foobar.jar
Czy Classloader jest wystarczająco inteligentny, aby je jakoś rozdzielić? Najprawdopodobniej nie? W jaki sposób Classloader radzi sobie z tym w przypadku, gdy klasa jest taka sama we wszystkich trzech słoikach. Który jest załadowany i dlaczego?
Czy Classloader pobiera tylko dokładnie jeden słoik, czy też dowolnie miesza klasy? Na przykład, jeśli klasa jest ładowana z pliku Version-1.jar, wszystkie inne klasy ładowane z tego samego modułu ładującego klasy trafią do tego samego pliku jar?
Jak radzisz sobie z tym problemem?
Czy jest jakaś sztuczka, aby w jakiś sposób „włączyć” słoiki do pliku „required.jar”, tak aby były one postrzegane jako „jedna jednostka / opakowanie” Classloader
lub w jakiś sposób połączone?
źródło
Każde ładowanie klas wybiera dokładnie jedną klasę. Zwykle pierwszy znaleziony.
OSGi ma na celu rozwiązanie problemu wielu wersji tego samego słoika. Equinox i Apache Felix to typowe implementacje Open Source dla OSGi.
źródło
Classloader załaduje klasy z pliku jar, który przypadkowo znalazł się jako pierwszy w ścieżce klas. Zwykle niekompatybilne wersje biblioteki będą miały różnice w pakietach, ale w mało prawdopodobnym przypadku są one naprawdę niekompatybilne i nie można ich zastąpić jednym - spróbuj jarjar.
źródło
Classloadery ładują klasę na żądanie. Oznacza to, że klasa wymagana najpierw przez aplikację i powiązane biblioteki zostanie załadowana przed innymi klasami; żądanie załadowania klas zależnych jest zwykle wysyłane podczas procesu ładowania i łączenia klasy zależnej.
Prawdopodobnie napotkasz komunikat
LinkageError
stwierdzający, że napotkano zduplikowane definicje klas dla programów ładujących klasy, zazwyczaj nie podejmuje się próby określenia, która klasa powinna zostać załadowana jako pierwsza (jeśli istnieją dwie lub więcej klas o tej samej nazwie obecne w ścieżce klas modułu ładującego). Czasami program ładujący klasy ładuje pierwszą klasę występującą w ścieżce klas i ignoruje zduplikowane klasy, ale zależy to od implementacji modułu ładującego.Zalecaną praktyką rozwiązywania tego rodzaju błędów jest użycie osobnego modułu ładującego klasy dla każdego zestawu bibliotek, które mają sprzeczne zależności. W ten sposób, jeśli program ładujący klasy spróbuje załadować klasy z biblioteki, klasy zależne zostaną załadowane przez ten sam program ładujący klasy, który nie ma dostępu do innych bibliotek i zależności.
źródło
Możesz użyć
URLClassLoader
for require, aby załadować klasy z wersji jar diff-2:źródło