03 maja 2010

Nauka Java EE 6 CDI (JSR-299) - relacja z lektury pierwszych dwóch rozdziałów specyfikacji

Od jakiegoś czasu przymierzam się do Java EE 6 (JEE6), ale ogrom zmian i nowości sprawia mi trochę problemów od czego zacząć. Mam już środowisko programistyczne - NetBeans IDE 6.9 i mam już środowisko uruchomieniowe (wykonawcze) - IBM WebSphere Application Server V8. Możnaby zatem powiedzieć, że mam wszystko, ale baczne oko zauważy, że nie mam najważniejszego - planu rozpoznania zestawu technologicznego, który kryje się pod niewinnie brzmiącym akronimem JEE6. Śmiało można powiedzieć, że nie ma specyfikacji w JEE6, która nie zostałaby zmieniona przez ciało standaryzujące, choćby nieznacznie. A pojawiły się również nowe, chociażby Contexts and Dependency Injection for the Java EE platform (dawniej znanej jako Web Beans, co już po tym kątem może wprowadzać w zakłopotanie). I właśnie od niej postanowiłem zacząć moją naukę, chyba przede wszystkim dlatego, że całkowicie nowa.

Specyfikacja Contexts and Dependency Injection for the Java EE platform (w skrócie CDI) miała swój początek w entuzjastycznym przyjęciu szkieletu webowego JBoss Seam, który stał się jakby domyślnie domem dla implementacji referencyjnej Weld (nota bene doskonale dobrana nazwa związana semantycznie z Seam, bo oba oznaczają mniej więcej "złączanie").

Mam za sobą pierwsze 2 rozdziały specyfikacji - 1. Architecture i 2. Concepts - i raczej, więcej pytań niż odpowiedzi. Mam wrażenie, jakby strona Weld była bardziej składnie pisana niż sama specyfikacja.

Lektura specyfikacji uzmysłowiła mi powód, dla którego warto poznawać nowe specyfikacje bez konieczności ich "odwzorowywania" na zastosowania biznesowe. Przynajmniej nie na etapie jej rozpoznawania. Jeszcze nie tak dawno, pisałem o potrzebie własnego rozwoju technologicznego pod kątem zastosowań biznesowych, w projekcie i dopasowywać rozwiązanie do problemu, a nie odwrotnie. Pamiętam jednak, że ktoś przypominał mi, że jak można dopasowywać coś, czego się jeszcze nie zna?! I tu jest pies pogrzebany. Uczenie się nowych technologii, to nauka technik, których potrzeby moglibyśmy nie być nawet w stanie określić i sprecyzować. Biorąc na warsztat CDI nie mam pojęcia, po co mi alternatives czy stereotypes (pojęcia z CDI), więc jak miałbym przedstawiać je w świetle potencjalnych zastosowań?! W ten sposób znalazłem uzasadnienie dla prezentacji stricte technologicznych, gdzie uczę się samej technologii, po których przyjdzie zastosowanie biznesowe. Pewnie, że możnaby postrzegać listę problem-rozwiązanie jako ułatwienie, ale czy wtedy nasze projekty nie straciłyby na swojej unikalności, gdyby wiadomo było, że skoro mamy projekt X to będzie technologia Y. Nuda. Zresztą mogłoby to wstrzymać postęp, gdyby nie próbować naginać rozwiązań do realizacji swoich wizji. To jest różnica między specyfikacją a książkami, które zwykle prezentują specyfikację przez zastosowania biznesowe, realizując konkretny projekt. Znalazłem tym samym sens istnienia artykułów i prezentacji czysto technicznych jako pierwszy krok wtajemniczenia oraz artykułów i prezentacji będących mieszanką technologii i zastosowania biznesowego jako kolejny etap. Najwyższym etapem wtajemniczenia widzę w świadomym wybraniu tego jednego rozwiązania z wielu dostępnych, często całkowicie niezwiązanych ze sobą. Denerwowało mnie to podczas dotychczasowej lektury specyfikacji CDI, gdzie przedstawiano "jak użyć" bez "po co", ale mając to wyjaśnienie jest mi dużo lżej na duszy :-)

Pierwsze 2 rozdziały specyfikacji CDI, które zajmują niecałe 20 stron, to w zasadzie górnolotne wprowadzenie w temat, które upstrzone jest odnośnikami do kolejnych rozdziałów. Jako podsumowanie rozdziału 1. Architecture możnaby napisać, że nie warto go czytać i od razu można przejść do kolejnego 2. Concepts, który de facto też nie wypada lepiej. Pierwszy rozdział raczej kłopotliwy w zrozumieniu i podpierając się odnośnikami do kolejnych nie zasługuje nawet na miano wprowadzającego. A tyle się mówi o tym, aby nie mieć zbyt dużych oczekiwań, bo można się niemile rozczarować, całkiem niepotrzebnie.

Ważne do zapamiętania jest, aby rozpatrywać CDI jako zbioru uzupełniających się usług, które razem tworzą platformę DI (ang. dependency injection). Brakujące 'C' w nazwie specyfikacji nadaje przestrzeń, w której żyją zarządzane byty - kontekst. Ktoś mógłby powiedzieć, że to Spring Framework i pewnie niewiele by się pomylił (na stan obecnej mojej wiedzy o CDI). Nie potrafię umiejscowić Spring Framework (SF) i Guice w świetle CDI, ale komuś najwyraźniej zamarzyło się posiadanie ich cech na platformie Java EE i skoro znalazł się chętny (zespół JBoss Seam), którego niewielu postrzegało jako konkurent SF, to z CDI zmieni się to zauważalnie.

Mamy więc dobrze określone przestrzenie (ang. context) działania naszych zarządzanych bytów (ang. managed beans) i ot całe CDI. Reszta jest jedynie spisaniem praw i obowiązków programisty oraz środowiska realizującego specyfikację, co biorąc pod uwagę obowiązkowość w Java EE 6, a nawet jej podzbioru Web profile znaczy, że wszyscy muszą realizować tę specyfikację chcąć się mienić zgodnością z JEE6.

Zbiór kontekstów jest rozszerzalny, czyli mamy 3 znane z Java EE obszary - żądanie (ang. request), sesja (ang. session) i aplikacja (ang. application), a z CDI dochodzi kolejny konwersacja (ang. conversation). Chcemy kolejny, np. wspomniany w specyfikacji proces biznesowy, mamy prawo go utworzyć i oczekiwać działania na dowolnym kontenerze CDI.

Zależności są przekazywane (wstrzeliwane) ze względu na tryb uruchomienia aplikacji - rozwojowy czy produkcyjny bez, jak to ujęto, wyrafinowanej konfiguracji.

Integracja z Unified Expression Language (EL) umożliwia użycie CDI z JSF czy JSP, co wyznacza ścieżkę dalszej nauki JEE6 - po CDI warto zajrzeć do zmian w JSF 2.0.

CDI udostępnia również możliwość dekorowania przekazywanych obiektów, definiowania interceptorów i użycia modelu zdarzeń.

Obiekty, które podlegają zarządzaniu przez kontener CDI zawierają ziarna sesyjne EJB3, ziarna zarządzane JSF oraz zasoby JEE. Nazywane są ogólnie ziarnami (ang. beans), a ich instancje związane z kontekstem - instancjami kontekstowymi (ang. contextual instances). Programista określa co i gdzie będzie przekazane przez usługę DI w postaci adnotacji lub deskryptora XML.

Tym samym, dzięki CDI ziarna sesyjne EJB3 mogą być ziarnami zarządzanymi JSF (coś co było możliwe w JBoss Seam, jak i Spring Framework z jego rozszerzeniami).

Aplikacja korzystająca z CDI może działać na platformie Java EE oraz...Java SE. Użycie usług typu transakcje czy utrwalanie (ang. persistence) w CDI na Java SE jest co najwyżej takie, jak dostępne we wbudowanym trybie EJB 3.1. Kolejna specyfikacja na ścieżce poznawania JEE6, po JSF 2.0.

Wszystkie klasy podlegające mechanizmowi wstrzeliwania zależności w JEE6 są możliwe do użycia z ziarnami CDI. W ten sposób, CDI rozszerza dotychczasowe specyfikacje JEE, np. EJB3 o pojęcie kontekstu, spajając specyfikacje prezentacyjne z biznesowymi.

Kontekst wyznacza obszar działania i widoczności. Kontener tworzy instancje obiektów, kiedy są potrzebne, a niszczy, kiedy kontekst kończy swój żywot (pachnie literaturą, więc powinienem był napisać "swoje istnienie").

Adnotacja @Inject określa pole instancji zwane injected field (pole injekcji?), które jest inicjowane przez CDI podczas inicjowania ziarna CDI lub metodę początkową/inicjalną (ang. initializer method) uruchamianą po zainicjowaniu ziarna CDI z wstrzelonymi parametrami (zaraz wysiądę przez te tłumaczenia). Warto zajrzeć do specyfikacji, do sekcji 1.3 Introductory examples, aby przez przykłady poczuć sens specyfikacji. Wyjaśnienia są lakoniczne i raczej technologiczne niż po co i dlaczego.

Rozdział 2. Concepts omawia...następnym razem :-)

6 komentarzy:

  1. Jest jeszcze pseudo-kontekst - @Dependent.
    Co do samej specyfikacji to masz racje - rowniez jak ja zaczynalem czytac mialem wiecej pytan niz odpowiedzi. Jednak w trakcie czytania (prawie) wszystko sie rozjasnialo. Po skonczeniu polecam przeczytac Welda Reference Guide, nastepnie troche pokodowac, a pozniej wrocic do czesci specyfikacji ktorych sie nie rozumialo (ja ponownie przeczytalem cala) i naprawde mozna juz zrozumiec. Same CDI uwazam za swietne, po prostu Spring sie tutaj nie umywa - chodzi mi oczywiscie tylko o DI, o dekoratory, oraz o cale to type-safety, dzieki adnotacjom. Uzywamy tego w nowym projekcie od poczatku grudnia (zanim wiec Java EE6 byla final), oraz uzywamy Weld SE w naszym wlasnym frameworku testowym (TestNG + our stuff).
    Samo uzywanie CDI bardziej mi przypominalo Guice niz Spring (jakos tak mam ze Spring == XML, Guice == kod; tak tak wiem ze Spring ma adnotacje od 2.5). Pare rzeczy mi brakuje (mozliwosc wyspecyfikowania klas ktore moglyby byc Beanami w sensie CDI ale nie chce zeby nimi byly (aktualnie trzeba napisac rozszerzenie i uzyc veta), ale ogolnie wielki fun z pisania aplikacji w ten sposob.
    Co do poznania technologii zanim sie powie ze sie ja zastosuje i w jaki sposob - to wydaje mi sie ze nie ma innej drogi? To mi przypomina mojego obecnego szefa zespolu, ktory nie czyta specow ani tutoriali ("nie mam czasu"), uczyc sie przestal w 2004 (przed genericsami, wiec chce z nich korzystac ale nie umie i pisze glupoty) ale jak to mowi: "zakladam ze to tak dziala" i jak jednak dziala inaczej to jest wielce rozczarowany bo okazuje sie ze jego miesieczna praca jest o kant dupy roztluc.

    OdpowiedzUsuń
  2. "Programista określa co i gdzie będzie przekazane przez usługę DI w postaci adnotacji lub deskryptora XML."

    Nie do konca jest to prawda - w beans.xml mozna zrobic bardzo niewiele - wlaczyc dekoratory, interceptory i alternatywy (w postaci pojedyncztch klas lub stereotypow), nic wiecej. Nie ma w standardzie mozliwosci definicji DI w XML - ale jest portable extension przy projekcie Seam 3 ktore wypelnia luke.

    OdpowiedzUsuń
  3. Człon nazwy 'Context' wydaje się być chłytem marketingowym - po prostu głupio tak w 2010 roku wyskoczyć z samym DI ;PPP

    Szkoda, że jak zwykle nie wszystko zostało do końca zaczerpnięte z community.

    A co do braku DI w XML to też szkoda - czasem się przydaje gdy potrzeba osiągnąć wyższy poziom IoC niż hardkowanie zależności w kodzie.

    OdpowiedzUsuń
  4. Sławek - a czytales specyfikacje, wiesz o co dokladnie chodzi w Contexts? To nie jest po prostu byle slowo by tylko dodac cos do DI - to jest usluga ktora zarzadza cyklem zycia obiektow. Dodam ze bardzo latwo rozszerzalna.

    OdpowiedzUsuń
  5. Używając stereotypów można zależności stworzone zadeklarowane przez adnotacje przenieść na wyższy poziom abstrakcji. Poprzez ich zastosowanie można zmieniać metadane klas bez zmian w kodzie samych klas.. taki meta-meta-programming.
    http://docs.jboss.org/cdi/spec/1.0/html/concepts.html#stereotypes

    OdpowiedzUsuń
  6. @Wujeak - tak, jakiś czas temu miałem wolny wieczór i zmusiłem się do lektury:)

    Muszę przyznać rację Jackowi - ciężka sprawa. (Mam tu na myśli evalution dla developerów aplikacji a nie spec dla vendorów - tam spodziewam się czystego autyzmu).Ewidentnie nikomu nie zależało na przystępności. Jednak z doświadczeniem z Seam można szybko odnaleźć analogie i łatwo sobie "zamapować" na przykłady biznesowe. Przy okazji przykłady w specyfikacji evalutaion są miejscami bezensowne (globalna lista wszystkich produktów).

    Co do kontekstu to pociągnę temat. Kontekst to coś co nadaje nowe znaczenie, nałożenie kontekstu wnosi coś nowego do sprawy. W przypadku CDI obiekty zarządzające życiem instancji kontekstowych to "obiekty zarządzające życiem" zgodnie z pewnym zasięgiem (plus kilka fajnych ficzerów).

    Natomiast kontekst z prawdziwego zdarzenia mamy np w silnikach implementujących paradygmat DCI (Data Context Interaction).

    OdpowiedzUsuń