Chciałbym zaimplementować aplikację java (aplikację serwerową), która może pobrać nową wersję (plik .jar) z podanego adresu URL, a następnie zaktualizować się w czasie wykonywania.
Jaki jest najlepszy sposób na zrobienie tego i czy jest to możliwe?
Domyślam się, że aplikacja może pobrać nowy plik .jar i go uruchomić. Ale jak mam wykonać przekazanie, np. Wiedzieć, kiedy nowa aplikacja jest uruchomiona, a następnie wyjść. Czy jest na to lepszy sposób?
Odpowiedzi:
Podstawowa struktura rozwiązania jest następująca:
Istnieje główna pętla odpowiedzialna za wielokrotne ładowanie najnowszej wersji aplikacji (jeśli jest wymagana) i jej uruchamianie.
Aplikacja robi swoje, ale okresowo sprawdza adres URL pobierania. Jeśli wykryje nową wersję, wraca do programu uruchamiającego.
Można to wdrożyć na wiele sposobów. Na przykład:
Program uruchamiający może być skryptem opakowującym lub aplikacją binarną, która uruchamia nową maszynę JVM w celu uruchomienia aplikacji z zastępowanego pliku JAR.
Program uruchamiający może być aplikacją Java, która tworzy moduł ładujący klasy dla nowego pliku JAR, ładuje klasę punktu wejścia i wywołuje na niej jakąś metodę. Jeśli zrobisz to w ten sposób, musisz uważać na wycieki pamięci klasy ładującej, ale to nie jest trudne. (Musisz tylko upewnić się, że żadne obiekty z klasami załadowanymi z pliku JAR nie są osiągalne po ponownym uruchomieniu).
Zalety podejścia zewnętrznego opakowania to:
Drugie podejście wymaga dwóch plików JAR, ale ma następujące zalety:
„Najlepszy” sposób zależy od konkretnych wymagań.
Należy również zauważyć, że:
Automatyczne aktualizowanie wiąże się z zagrożeniami bezpieczeństwa. Ogólnie rzecz biorąc, jeśli serwer udostępniający aktualizacje jest zagrożony lub mechanizmy zapewniające aktualizacje są podatne na atak, automatyczne aktualizowanie może doprowadzić do naruszenia bezpieczeństwa klienta (ów).
Rozesłanie aktualizacji do klienta, która wyrządzi klientowi szkodę, może wiązać się z ryzykiem prawnym oraz zagrozić reputacji Twojej firmy.
Byłoby dobrze, gdybyś mógł znaleźć sposób, aby uniknąć ponownego wynalezienia koła. Zobacz inne odpowiedzi, aby uzyskać sugestie.
źródło
Obecnie pracuję nad demonem JAVA Linux i miałem też potrzebę zaimplementowania mechanizmu automatycznej aktualizacji. Chciałem ograniczyć swoją aplikację do jednego pliku jar i znalazłem proste rozwiązanie:
Spakuj aplikację aktualizującą do samej aktualizacji.
Aplikacja : gdy aplikacja wykryje nowszą wersję, wykonuje następujące czynności:
ApplicationUpdater : gdy aktualizator jest uruchomiony, wykonuje następujące czynności:
Mam nadzieję, że to komuś pomoże.
źródło
To znany problem i odradzam wymyślanie na nowo koła - nie pisz własnego hacka, po prostu użyj tego, co zrobili już inni.
Dwie sytuacje, które musisz wziąć pod uwagę:
Aplikacja musi mieć możliwość samodzielnej aktualizacji i działać nawet podczas aktualizacji (aplikacja serwerowa, aplikacje wbudowane). Idź z OSGi: Bundles lub Equinox p2 .
Aplikacja to aplikacja komputerowa z instalatorem. Istnieje wiele instalatorów z opcją aktualizacji. Sprawdź listę instalatorów .
źródło
Niedawno stworzyłem update4j, który jest w pełni kompatybilny z systemem modułów Java 9.
Nowa wersja bezproblemowo uruchomi się bez restartu.
źródło
Napisałem aplikację Java, która może ładować wtyczki w czasie wykonywania i natychmiast zacząć ich używać, zainspirowana podobnym mechanizmem w jEdit. jEdit jest open source, więc możesz sprawdzić, jak to działa.
Rozwiązanie wykorzystuje niestandardowy ClassLoader do ładowania plików z jar. Po załadowaniu możesz wywołać jakąś metodę z nowego jar, która będzie działać jako
main
metoda. Następnie trudna część polega na tym, aby pozbyć się wszystkich odniesień do starego kodu, aby można go było usunąć jako śmieci. Nie jestem ekspertem w tej kwestii, udało mi się, ale nie było to łatwe.źródło
NetworkClassLoader
w JavaDoc dla ClassLoaderźródło
Niekoniecznie jest to najlepszy sposób, ale może zadziałać dla Ciebie.
Możesz napisać aplikację ładującą (ala program uruchamiający World of Warcraft, jeśli grałeś w WoW). Ten bootstrap jest odpowiedzialny za sprawdzanie aktualizacji.
Dzięki temu nie musisz się martwić wymuszeniem zamknięcia aplikacji.
Jeśli Twoja aplikacja jest oparta na sieci Web i ważne jest, aby miała aktualnego klienta, możesz również sprawdzać wersję podczas działania aplikacji. Możesz to robić w odstępach czasu, podczas normalnej komunikacji z serwerem (niektóre lub wszystkie połączenia) lub jedno i drugie.
W przypadku produktu, nad którym ostatnio pracowałem, sprawdzaliśmy wersję po uruchomieniu (bez aplikacji do bootowania, ale przed pojawieniem się okna głównego) i podczas połączeń z serwerem. Kiedy klient był nieaktualny, polegaliśmy na tym, że użytkownik zakończył pracę ręcznie, ale zabroniliśmy jakichkolwiek działań przeciwko serwerowi.
Pamiętaj, że nie wiem, czy Java może wywołać kod interfejsu użytkownika, zanim otworzysz główne okno. Używaliśmy C # / WPF.
źródło
Jeśli tworzysz swoją aplikację przy użyciu wtyczek Equinox , możesz skorzystać z systemu P2 Provisioning, aby uzyskać gotowe rozwiązanie tego problemu. Będzie to wymagało ponownego uruchomienia serwera po aktualizacji.
źródło
Widzę problem bezpieczeństwa podczas ściągania nowego jar (itp.), Np. Atak man in the middle. Zawsze musisz podpisać aktualizację do pobrania.
Na JAX2015 Adam Bien opowiedział o używaniu JGit do aktualizacji binariów. Niestety nie mogłem znaleźć żadnych tutoriali.
Źródło w języku niemieckim.
Adam Bien stworzył aktualizator, patrz tutaj
Tutaj rozwidliłem to z jakimś interfejsem javaFX. Pracuję również nad automatycznym podpisem.
źródło