21 września 2008

Spring Dynamic Modules a aplikacje webowe

Już pisałem o tym 4 maja 2008 w Aplikacja webowa jako pakunek OSGi ze Spring Dynamic Modules, ale po sobie widzę, że warto wspomnieć o tym jeszcze raz.

Rozdział 8. Web Support nie pozostawia złudzeń, czego możemy dodatkowo oczekiwać od Spring Dynamic Modules (Spring-DM) poza podstawową cechą jako jest wsparcie dla tworzenia pakunków OSGi korzystając ze Spring Framework. Mowa w nim o wsparciu dla aplikacji webowych (będącymi dystrybuowane jako war - plik jar z odpowiednią strukturą katalogową, np. konieczność istnienia WEB-INF/web.xml) będącymi de facto pakunkami OSGi. Jeśli ktokolwiek zastanawiał się nad sensownością zastosowania OSGi w swoich aplikacjach, to przynajmniej obszar aplikacji webowych powinien być już rozwikłany z pomocą tego rozdziału. Spring-DM łączy cechy OSGi z Korporacyjną Javą udostępniając niezbędne elementy jako pakunki OSGi - kontener servletów jak i samą aplikację webową - które wiąże mechanizmami OSGi. Spring-DM to po prostu warstwa wspierająca uruchamianie aplikacji springowych oraz webowych na Platformie OSGi.

Przyjrzyjmy się dokładniej, co takiego oferuje Spring-DM, czego nie znajdziemy w innych środowiskach. Do poprawnego uruchomienia aplikacji webowej potrzebny jest kontener servletów (być może z jsp, ale kto by tego obecnie używał?!). Podstawowym bytem Platformy OSGi jest pakunek. Jeśli cokolwiek miałoby być uruchomione na Platformie OSGi musi być pakunkiem. Pakunek OSGi to zwykły plik jar z odpowiednimi nagłówkami w META-INF/MANIFEST.MF i stąd wypływa niezwykłość OSGi - niby nic szczególnego, a za darmo mamy możliwości niebagatelnej wartości, m.in. wersjonowanie, dedykowane ładowarki klas, uprawnienia, co z kolei składa się na funkcjonalność uktualniania aplikacji bez konieczności jej zatrzymywania. Połączenie elementów Java EE z OSGi polega na udostępnieniu tych pierwszych jako pakunków OSGi i...tyle. Już możemy okrzyknąć nasze rozwiązanie jako zgodne z pryncypiami OSGi. Do tego wcale nie potrzeba Spring-DM. Gdzie dostrzeżemy zaletę jego wykorzystania, to w sposobie integracji trzech (!) technologii OSGi, Java EE oraz Spring Framework - podczas uruchomienia pakunku OSGi z rozszerzeniem pliku .war, lub zawierającego specyficzne dla Spring-DM nagłówki w manifeście, nastąpi ich automatyczne "związanie" z pakunkiem będącym kontenerem servletów (obecnie Tomcat i Jetty). Właśnie owe rozszerzenie Platformy OSGi o funkcjonalność rozpoznawania pakunków będących faktycznie aplikacjami korporacyjnymi - aplikacjami webowymi - jest wartością Spring-DM. Wprowadzając Spring-DM do naszej aplikacji wprowadzamy jednocześnie cechy OSGi, Spring Framework oraz Java EE. Takie 3-w-1, albo po prostu OSprin-JEE-i.

Porównując wsparcie Spring-DM dla uruchamiania aplikacji springowych a aplikacjami webowymi (potencjalnie korzystającymi z elementów springowych) można zauważyć, że w przypadku aplikacji webowych są one jedynie rozpoznawane i przekazywane do kontenera servletów (który uruchomiony jest na Platformie OSGi jako pełnoprawny pakunek OSGi). Nic poza rozpoznaniem aplikacji webowych nie pozostaje w gestii Spring-DM. Tymczasem rozpoznanie aplikacji springowych skutkuje wzbudzeniem Spring-DM Extender, który wykonuje całą pracę uruchomienia pełnej maszyneri springowej.

Jest kilka istotnych kwestii do zapamiętania, aby aplikację webową uruchomić w ramach Spring-DM, które są implikowane przez prawa rządzące OSGi - kwestia widoczności klas. Domyślnie klasy należące do pakietów javax.servlet.*, WEB-INF/lib/*.jar oraz WEB-INF/classes są widoczne dla aplikacji webowej w "zwykłym" kontenerze servletów. Dodatkowo kontener ma możliwość zdefiniowania wspólnej przestrzeni klas/bibliotek dołączanych do aplikacji webowych, o którą ją rozszerza. W przypadku środowiska OSGi obowiązują bardziej restrykcyjne reguły wymagające, aby pakunek deklarował swoją przestrzeń klas przez nagłówki Import-Package oraz Bundle-Classpath w manifeście. Za ich pomocą należy skonstruować wymaganą przestrzeń klas - zawartość ładowarki klas związanej z pakunkiem. Bez nich zasady obowiązujące w specyfikacji Java Servlet są niepełne w środowisku Spring-DM. Zgodnie z adnotacją w 8. Web Support możnaby oczekiwać, aby owe deklaracje były automatycznie dodawane do pakunku przez Spring-DM, ale póki co, taka funkcjonalność nie jest dostępna. Cechą, która jest niezwykle interesująca, a wręcz wskazana, przy konstruowaniu aplikacji webowej w ramach OSGi (za pomocą Spring-DM) jest wyniesienie bibliotek aplikacji poza jej strukturę katalogową, co przy bardzo radykalnym podejściu skończy się pustymi katalogami WEB-INF/lib oraz WEB-INF/classes, a ich zawartość zostanie uruchomiona w ramach OSGi jako osobne pakunki związane z aplikacją przez nagłówki Import-Package (opcjonalnie Require-Bundle) w manifeście. Uaktualnienie aplikacji o nową funkcjonalność, bądź wdrożenie poprawek, to wyłącznie uaktualnienie pakunków OSGi. Niezwykle potężne oręże upraszczające tworzenie aplikacji webowych ze Spring-DM.

5 komentarzy:

  1. Czyli z tego można rozumieć, że wersjonowaniu podlega cała aplikacja (cały plik war) i nie ma możliwości podziału samej aplikacji Webowej na pakunki?
    Chyba, że plik war zawiera tylko pliki JSP (warstwę prezentacji), a klasy aplikacji są podzielone na pakunki OSGi, to chyba jedyna możliwość...
    Co i tak ogranicza podział aplikacji na niezależne części, gdzie możemy dołączać lub wyłączać poszczególne elementy aplikacji (włącznie z warstwą prezentacji) w razie potrzeb.

    OdpowiedzUsuń
  2. A ja chętnie poczytałbym o połączeniu Spring-DM z jpa. W dokumentacji jakoś nie ma informacji o wsparciu. Może niech to będzie pomysł na przyszły artykuł;)

    OdpowiedzUsuń
  3. Witam

    Nie do konca rozumiem zdanie: "Dodatkowo kontener ma możliwość zdefiniowania wspólnej przestrzeni klas/bibliotek dołączanych do aplikacji webowych, o którą ją rozszerza."

    Czy chodzi to o tzw utility jar ktore to leża sobie (jako jary) obok war i odwołujemy się do nich poprzez wpisy dla nagłówka Class-Path w Manifest.mf ?

    OdpowiedzUsuń
  4. @Łukasz - wersjonowaniu podlega pakunek. Pytanie jak bardzo podzielona może być aplikacja webowa na pakunki. Odpowiedź, którą wiem (teoretycznie) jest, że cała aplikacja to może być pakunek oraz wszystkie jej biblioteki, tak że WEB-INF/classes oraz WEB-INF/lib będą puste. Już niedługo zaprezentuję temat dokładniej w kolejnej notce na blogu.

    p.s. JSP może być również samodzielnym pakunkiem...częściowym, albo równouprawnionym, jeśli JSP przekompilujemy do klas i dystrybuujemy jako pakunek. Zdaje się, że tylko wyobraźnia staje się ograniczeniem ;-)

    @Kozerski - Już niedługo. Wspaniały temat, aczkolwiek, jeśli spojrzysz na niego w odpowiedni sposób, to zauważysz, że nie ma w nim nic odkrywczego. Po prostu aplikacja springowa z JPA dzięki Spring-DM stanie się pakunkiem. Może nie będę się rozpisywał tu i teraz - cierpliwości, artykuł nadchodzi.

    @miluch - miałem tutaj na myśli dodatkowe, wspólne dla całego kontenera (serwera) biblioteki, np. tomcatowy lib/commons. Tomcat gwarantuje, że są widoczne w hierarchi ładowarek klas (są zawsze na górze). Twój przykład jest również dobry, acz wtedy aplikacja musiałaby być dystrybuowana jako EAR, a to nie jest wspierane przez kontenery servletów.

    OdpowiedzUsuń
  5. Ten komentarz został usunięty przez autora.

    OdpowiedzUsuń