2013-02-28 14 views
7

Chcę mieć hot-code wymiany między aktualizacjami projektu, ale nie znalazłem żadnych informacji o tym, jak załadować pliki .class dynamicznie. Dokładniej, chcę coś takiego:Clojure hot swap dla uberjars/.classes

  1. Marka lein uberjar, uzyskać some-client-0.0.0-standalone.jar.
  2. Uruchom z java -jar some-client-0.0.0-standalone.jar.
  3. Wprowadź zmiany w projekcie. Uzyskaj nową wersję programu, some-client-0.0.1-standalone.jar, skopiuj ją do katalogu some-client-0.0.0-standalone.jar.
  4. Klient otrzymuje sekwencję poleceń potrzebnych do aktualizacji do nowej wersji.
  5. (opcjonalnie) Aktualizuje zasoby. Zasoby ze starego słoika nie są już używane.
  6. (opcjonalnie) some-client-0.0.0-standalone.jar można teraz usunąć.
+2

Myślę, że ** znacznie ** łatwiej będzie zrestartować klienta. Dlaczego nie możesz go ponownie uruchomić? –

+2

@NikitaBeloglazov Jeśli chodziło o ładowanie kodu podczas rozwijania, chciałbym ładować źródła lub restartować. Ale chciałbym zamienić coś w stylu erlangu na wymianę kliencką dla aplikacji klienckiej. I tak, wiem, że to nie jest dobre i może łatwo zawiesić mój program, ale jest to coś, co chcę wypróbować. – desudesudesu

Odpowiedz

2

Do ponownego ładowania w czasie wykonywania wyłącznie z plików jar może być konieczne przejrzenie OSGi class loaders. Dla kodu Clojure można zacząć nrepl w kliencie, który nasłuchuje na porcie lokalnym, a następnie, gdy chcesz, aby przeładować kod podłączyć do tego portu i zatelefonować do load-file

+0

Spróbuję tego. Pomogą w tym udane przykłady użycia go w clojure. – desudesudesu

5

Plug-in podejście ramy

Powiedziałeś, że chcesz mieć zamiany hot-code, ale to, czego potrzebujesz, to luźno połączone moduły i zdolność do rozwiązywania problemów w czasie wykonywania. Mówiąc szczerze, pomocna może być dowolna struktura wtyczek, w tym starsze wersje OSGi (zostaną omówione poniżej).

enter image description here

Ponieważ robisz jakąś PoC Proponuję przejrzeć następujący przykład:

  1. masz meta aplikacji z niektórych punktów rozszerzeń (metaphor explanation) zdefiniowany
  2. funkcjonalność być zaktualizowane lub zastąpione będą implementowane jako luźno powiązane moduły (wtyczki)
  3. meta aplikacja wykonuje rozstrzygnięcie na żądanie lub automatycznie w celu znalezienia zaktualizowanej "funkcjonalności" (Zgodnie z określonymi punktami przedłużających)

Mając które definiują simlle uaktualnić scenariusz można zaproponować:

  1. użytkownik korzysta z aplikacji
  2. Instaluje użytkownika (kopie) słoiku (inny rodzaj wiązki) z nowa implementacja jednego lub kilku punktów rozszerzeń
  3. użytkownik wyzwala globalne rozpoznanie systemu lub skanowanie systemu w poszukiwaniu nowych aktualizacji lub wykonania systemu postanawia, że ​​każdy użytkownik urządzenia próbuje uzyskać dostęp do jakiejś funkcjonalności

W taki sposób aplikacja meta będzie mogła zapewnić nową lub zaktualizowaną funkcjonalność bez ponownego uruchamiania.Więc można:

  1. spróbować użyć jakiś prosty plug-in Java ramy (jak, na przykład, Java Simple Plugin Framework. 5 minutes and it works. No XML. Takie podejście wydaje się być trochę brzydki
  2. wykorzystanie dynamicznego charakteru Clojure, jak sugerowano here

Możesz również przejrzeć i przyjąć Waterfront (Clojure edytor oparty na Clojure) wnioski (to może być potrzebne w celu wzmocnienia zarządzania cyklem życia, etc)

pod względem wykonania, Wybrzeże opiera się na kontekście wzorca. Pozwala to programom obsługi zdarzeń komunikować się w sposób funkcjonalny ( ) (bez efektu ubocznego). Oprócz tego istnieje mechanizm plug-loader ładujący wtyczki określone w pliku konfiguracyjnym Waterfront o numerze . Oznacza to, że można łatwo dodać funkcjonalność lub usunąć (bardzo przydatne przy debugowaniu!).

podejście OSGI

Jak sugerowano OSGi wydaje się być dobrym sposobem na rozwiązanie problemu. Należy również pamiętać, OSGi jest dobry, dojrzały i dostarcza wielu rzeczy po wyjęciu z pudełka, ale jest również nieco skomplikowane:

enter image description here

BTW, OSGi jest długoterminowym celem dla społeczności Clojure. Można sprawdzić Clojure Todo:

> better modularization for OSGi etc 
> * names 
> * no single namespace pool 
> * namespaces found via classes, thus tracks classloader and modules 
> * deal with import proxying a la Class.forName stack walk? 

Istnieją pewne rozwiązania już dostępne:

  1. clojure-osgi-utils
  2. clojure.osgi

Drugi projekt świadczy przykład Producent konsumentów za pomocą Clojure i OSGi:

Szczęśliwy kodowania.

+0

http: // stackoverflow.com/questions/1810231/defining-a-spi-in-clojure - próbowałem (podczas true (wątek/uśpienie 5000) (ładowanie "/ class_that_changes") (println (eval 'class_that_changes/hello)) (eval' (chass_that_changes/hello))). Ponownie ładuje .clj, ale nie ładuje ponownie plików .class. class_that_changes/hello wskazuje na ten sam obiekt. Czy robię to źle? jspf - Może to być opcja, ale wymaga to pisania rzeczy w Javie. Opcja Java interop jest nadal opcją. – desudesudesu

+1

A clojure.osgi nie jest projektem lein, a to mnie zasmuca. – desudesudesu

+0

nabrzeże wykorzystuje plik obciążenia, który "Odczytuje i ocenia zestaw formularzy zawartych w pliku". '' .clj'', znowu nie ".class". – desudesudesu