29 sierpnia 2006

Java EE 5 - wpływ projektów wolnodostępnych na uproszczenie specyfikacji

10 komentarzy
Najnowsza wersja specyfikacji Java Platform Enterprise Edition (w skrócie Java EE czy JEE) to wersja 5. Każda ze specyfikacji wprowadzała użytkownika języka Java w coraz to bardziej zaawansowane arkana sztuki tworzenia aplikacji przemysłowych. Niestety szło to w parze z koniecznością poznania wielu zawiłości specyfikacji składowych (przede wszystkim Enterprise JavaBeans (EJB)). Stanowiło to nie lada wyzwanie nawet dla zaawansowanych programistów.

Jednym z podstawowych problemów nie tylko dla świeżych adeptów poprzednich wersji Java EE (nazywanych poprzednio Java 2 Enterprise Edition - J2EE) było utrzymywanie plików pomocniczych wymaganych przez poszczególne specyfikacje, m.in. deskryptory instalacji i dodatkowe klasy pomocnicze. Ich istnienie było krytykowane, ponieważ nie dostarczały wartości dodanej, a osoby korzystające z usług serwerów aplikacyjnych J2EE musiały borykać się z utrzymywaniem dodatkowych plików, powiązanych jedynie w środowisku uruchomieniowym. Była to bezpardonowa walka nie tylko dla osób dopiero wkraczających na teren J2EE (zauważ na skrót, który wskazuje na wersje specyfikacji wcześniejszych od Java EE 5, np. J2EE 1.4). Szczęśliwie pojawiło się panaceum. Środkiem zaradczym stały się projekty wolnodostępne, np. XDoclet, których cykl wytwórczy był krótszy i wdrożenia udogodnień następowały na bieżąco. XDoclet pozwalał na opisanie kodu źródłowego aplikacji i utworzenie plików pomocniczych automatycznie podczas budowania aplikacji. Opisywanie kodu źródłowego następowało za pomocą znaczników JavaDoc, które precyzowały stosowanie naszych klas. Pozwalało to na znaczne uproszczenie tworzenia aplikacji J2EE kosztem wprowadzenia do cyklu wytwarzania narzędzi pomocniczych. Koszt nie był wielki, a z pewnością zdecydowanie mniejszy niż realizowanie zadania na własną rękę. XDoclet stał się de facto standardem - narzędziem wykorzystywanym podczas tworzenia aplikacji J2EE (świadomie używam skrótu poprzedniej specyfikacji) w każdym zespole, który niwelował potrzebę utrzymywania niezliczonej ilości plików pomocniczych. Ci, którzy nie stosowali XDoclet najczęściej znajdowali inne rozwiązania semi-J2EE. Tak, czy owak stosowanie J2EE sprowadziło się głównie do budowania aplikacji z użyciem Java Servlets i JavaServer Pages (choć i dla nich znaleziono również alternatywne rozwiązania). Szczęśliwie, zalety stosowania narzędzi wspierających tworzenie aplikacji, jak XDoclet, dostrzeżono nie tylko w zespołach rozwijających specyfikację Java 2 Enterprise Edition, ale również i samego języka Java. W najnowszej produkcyjnej odsłonie języka Java SE 5 wprowadzono mechanizm anotacji (ang. annotations) zwanego również meta-danymi. Tym samym anotacje stały się częścią języka Java, co powodowało, że stał się on powszechnie stosowanym rozwiązaniem opisu kodu źródłowego na podstawie, którego można tworzyć inne artefakty projektowe, np. deskryptory instalacji. Ważny podkreślenia jest fakt udostępnienia tego mechanizmu nie tylko dla osób związanych z platformą Java EE, ale przede wszystkim Java SE (Java Standard Edition 5), czyli w samym języku Java (!) Zaletę stosowania anotacji każdy z nas, programujących w Javie, dostrzegł już wcześniej korzystając ze znaczników JavaDoc do opisywania kodu źródłowego. W ten sposób tworzono dodatkowy artefakt projektowy jakim jest dokumentacja publicznego interfejsu (API) projektu. Za pomocą JavaDoc, niewielkim kosztem można stworzyć dokumentację, której układ i znaczenie znane są każdemu użytkownikowi aplikacji Java. Dla wielu, problemy związane z dokumentacją już nie istnieją, albo sprowadzają się jedynie do utrzymywania JavaDoc (co i tak niestety jeszcze dla wielu stanowi wyzwanie). Grupa standaryzująca specyfikację Java EE 5 wykorzystała dobrodziejstwa płynące z wdrożenia anotacji do opisywania klas tak, aby na ich podstawie utworzyć pozostałe części składowe aplikacji JEE. Życie twórcy aplikacji przemysłowych w Javie stało się zauważalnie prostsze. Na uwagę zasługuje fakt, że stosowanie anotacji stało się tak popularne, że już nie ma osób, które nie korzystają, albo nie planują z nich skorzystać. W naturalny sposób programiści języka Java nabyli użytecznej umiejętności utrzymywania dodatkowych, zewnętrznych plikach aplikacji w ryzach implementacyjnych bez konieczności nauki dodatkowej (i zazwyczaj niepotrzebnej) wiedzy o niskopoziomowych zasadach działania specyfikacji J2EE (ponownie uwaga na akronim). W zasadzie można było stwierdzić, że stosowanie J2EE "zanieczyszczało" nam nasz projekt i dlatego stosowanie projektów wolnodostępnych jako antidotum na bolączki wdrożenia zasad J2EE zdobywało uznanie. Powoli znikały "czyste" aplikacje J2EE i pojawiały się rozwiązania alternatywne, łatwiejsze w implementacji i utrzymaniu. Serwer aplikacyjny J2EE stał się jedynie zbędnym dodatkiem do środowiska uruchomieniowego udostępniającym wiele z usług, których użycie sprowadzało się do wykorzystania kontenera serwletów (jako łącznika ze światem zewnętrznym) i zarządcy transakcji. Reszta istniała bez większego wykorzystania.

"Wpływowych" projektów wolnodostępnych rewolucjonizującymi tworzenie aplikacji przemysłowych z wykorzystaniem języka Java było wiele. Na uwagę jednakże zasługują dwa: Hibernate oraz Spring Framework. Nie były doskonałe, ale ich wdrożenie nie nastręczało trudności i stosunkowo szybko reagowały na zmieniające się wymagania użytkowników (w przeciwieństwie do serwerów aplikacyjnych J2EE nie wspominając już samej specyfikacji J2EE). Oba uzupełniają się i tworzą kompletną platformę do tworzenia aplikacji przemysłowych poza ramami J2EE. Oba projekty były odpowiedzią na rosnącą komplikację i trudność w pomyślnym zastosowaniu specyfikacji J2EE (ponowie uwaga na skrót). I na szczęście oba wpłynęły na ostateczny wizerunek specyfikacji Java EE 5. Pierwszy z nich Hibernate był podwaliną dla powstania uproszczonej specyfikacji Enterprise JavaBeans (EJB) w wersji 3.0 w obszarze nazywanym Java Persistence, natomiast drugi Spring Framework upowszechnił stosowanie wzorca Wstrzeliwanie Zależności (ang. DI = Dependency Injection bądź IoC = Inversion Of Control). Oba korzystały z udogodnień wprowadzanych "u innych", aż wypracowano niepisany standard korzystania z rozwiązań specyfikacji JavaBeans (nie mylić ze specyfikacją Enterprise JavaBeans!) dostępnych bezpośrednio w języku Java do tworzenia aplikacji. I to bez konieczności wdrażania serwerów aplikacyjnych J2EE, które były trudne w administracji a ilość informacji do przyswojenia "wykańczała" niejeden zespół projektowy. Pojawił się termin POJO.

POJO (ang. Plain Old Java Object), czyli stary, dobry obiekt Javy jest klasą Javy ze zbiorem metod do ustawiania i pobierania właściwości obiektu (tzw. settery i gettery). Brak wymagania na dziedziczenie klas, czy implementację interfejsów szkieletu programistycznego (ang. framework) był strzałem w dziesiątkę. Krzywa uczenia znacznie się spłaszczyła, a zalet stosowania POJO nie trzeba było nikomu przedstawiać. Zacznijmy od najważniejszej - brak wplatania własnych klas w hierarchię klas wykorzystywanego szkieletu, np. tak jak to było na platformie J2EE. Brak konieczności realizacji interfejsów i klas pomocniczych uniezależnia aplikację od docelowego środowiska uruchomieniowego. Korzystanie z POJO pozwala na tworzenie aplikacji w zespołach, których jedynym tematem dyskusji jest realizacja wymagań biznesowych a nie wymagań tej czy innej platformy. Temat wdrożenia aplikacji na daną platformę uruchomieniową pozostawiany jest architektom i administratorom. Zespół programistów koncentruje się wyłącznie na aspektach biznesowych projektu a nie implementacyjnych docelowej platformy. Mimo tak oczywistych zalet istnieje jeszcze jedna, często tak oczywista, że się o niej po prostu zapomina. Każdy programista Java potrafi stworzyć POJO. Nie ma potrzeby wdrażać zespołów do stosowania POJO (chyba że, aby zastosować szkolenie jako terapię wstrząsową po wielomiesięcznych projektach J2EE). Technologia JavaBeans istniała od zawsze w Javie, przede wszystkim w arsenale programistów aplikacji graficznych, ale teraz powraca do łask twórców aplikacji przemysłowych. Istnienie rozwiązań opartych o POJO wymaga jednakże specjalizowanego środowiska, którym nie był serwer aplikacyjny J2EE (ponownie uwaga na skrót). Wymagano kontenerów IoC/DI, które wstrzeliwały zadeklarowane zależności. Można powiedzieć, że podobnie było w przypadku serwerów J2EE, gdzie deklarowało się zależność w deskryptorze instalacji, z tą jednak różnicą, że w kontenerze IoC wystarczy jedynie dostarczyć publiczny setter bądź odpowiedni konstruktor i otrzymuje się gotową do użycia zależność (bez jej wyszukiwania jak to miało miejsce w J2EE, np. wyszukiwanie komponentów EJB w JNDI). Wraz z wdrożeniem kontenera IoC i zastosowania POJO w projekcie, kod korzystający ze specyficznych rozwiązań środowiska zewnętrznego maleje. Operujemy wyłącznie na publicznym interfejsie, co dodatkowo go uelastycznia. Wynika to ze sposobu działania kontenera IoC - zadeklarowana zależność za pomocą anotacji (preferowany sposób), czy pliku konfiguracyjnego musi być dostępna zanim aplikacja zostanie w pełni uruchomiona. Druga zaleta to brak konieczności wyszukiwania zależności. To nie aplikacja ich szuka, ale kontener, który podaje je (wstrzeliwuje) podczas inicjalizacji aplikacji. Stąd bierze się określenie wzorca programowania - Odwórcenie kontroli znanego również jako Wstrzeliwanie zależności. Z nim związana jest zasada nazwana Hollywood Principle, które odzwierciedla istotę jego działania (jak i istnienia samego Hollywood): Don't call us we'll call you, co oznacza Nie dzwoń do nas, to my zadzwonimy do Ciebie. W kontenerze IoC nasza aplikacja deklaruje zależności i ich oczekuje. Wstrzeliwanie zależności odbywa się za pomocą konstruktora (podczas tworzenia obiektu jeden z parametrów jest zależnością), albo za pomocą metody-settera (po stworzeniu obiektu wywoływany jest setter zanim nastąpi wywołanie innych metod biznesowych). Zalety stosowania zasady Hollywood (m.in. w Spring Framework) dostrzeżono w grupie standaryzującej platformę Java EE 5 i wdrożono ją m.in. w specyfikacji JavaServer Faces (nowość w specyfikacji Java EE, gdzie - obok Java Servlets i JavaServer Pages - jest kolejnym szkielet do budowania aplikacji internetowych, aczkolwiek specyfikacja wykracza poza zakres środowiska aplikacji internetowych), czy Enterprise JavaBeans (komponenty biznesowe reprezentujące procesy biznesowe, w tym i trwałe dane aplikacji przy współpracy innych usług serwera aplikacyjnego JEE, m.in. usługi bezpieczeństwa, czy monitorowania transakcji).

Kolejną innowacją w środowisku Java EE 5, która wspaniala spisywaly się na rynku aplikacji pisanych w języku Java na długo zanim sfinalizowano specyfikację JEE było uproszczenie zarządzania trwałymi danymi. Prym w tej dziedzinie wiódł projekt Hibernate (rozwiązanie należące do rodziny JBoss Enterprise Middleware Suite (JEMS)). Prostota dostępu i modyfikacji danymi trwałymi przechowywanymi w relacyjnych bazach danych za pomocą Hibernate była wprost porażająca w porównaniu z wykorzystaniem niezwykle skomplikowanego rozwiązania Enterprise JavaBeans 2.1, a szczególnie jej części dotyczącej dostępu do danych - Container-Managed Persistence (CMP) entity beans. Komponenty CMP są komponentami biznesowymi, które odpowiadają za obiektową reprezentację relacyjnych danych. Zastosowanie J2EE (uwaga na skrót) wymagało serwera aplikacyjnego, gdzie otrzymywano skomplikowany mechanizm dostępu do relacyjnych danych podczas, gdy Hibernate nie narzucał takich obostrzeń i mógł być stosowany i w aplikacjach desktopowych i przemysłowych, czyli wszędzie. Jedynym zauważalnym problemem było poznanie produktu Hibernate (poza , które nie było trywialne, ale alternatywą było stosowanie jeszcze bardziej nietrywialnych komponentów CMP (rozpatrując jedynie Hibernate i J2EE) i to wyłącznie w pewnych zastosowaniach - wyłącznie w rozwiązaniach przemysłowych. W aplikacjach desktopowych realizację dostępu do bazy danych dostarczał standardowy mechanizm JDBC, który jednak był zbyt niskopoziomowy w stosunku do możliwości Hibernate. Te i inne dobrodziejstwa Hibernate spowodowały odejście programistów Java od stosowania kolejnego ustandaryzowanego rozwiązania J2EE. Hibernate, podobnie jak Spring Framework, korzysta z POJO, aby "przenosić" dane obiektowe z i do relacyjnej bazy danych. Oba rozwiązania współpracują ze sobą, co stanowiło poważną alternatywę dla platformy J2EE. Z wprowadzeniem specyfikacji JEE (uwaga - zmiana akronimu) wielu programistów zapewne ponownie rozpatrzy zastosowanie Spring Framework + Hibernate versus platforma Java EE 5 szczególnie, że Hibernate realizuje specyfikację Java Persistence i może występować w roli dostawcy usługi. Byłoby niestosownym nie wspomnieć o możliwości uruchomienia implementacji Java Persistence poza środowiskiem Java EE, więc nasze aplikacje staną się jeszcze bardziej modularne i jedynie jednym z wielu implementacji (a nie jedyną) stanie się Hibernate. Spodziewam się przechylenia szali zainteresowania ze stosowania Hibernate na rzecz ustandaryzowanych rozwiązań realizujących specyfikację Java Persistence, którą pokreślam jedną z wielu jest Hibernate.

Nie sądzę, aby pojawienie się serwerów zgodnych ze specyfikacją Java EE 5 spowodowało znaczny spadek zainteresowania rozwiązaniem Spring Framework + Hibernate, czy podobnych. Sądzę jednak, że najnowsza odsłona platformy Java EE 5 stanowi interesującą alternatywę dla tego zestawienia. Wykorzystanie w JEE konstrukcji dostępnych bezpośrednio w języku Java do budowania aplikacji przemysłowych znacznie zmniejszy wymagania początkowe dla poznania specyfikacji Java EE 5 i znacząco zwiększy zainteresowanie platformą programistów innych rozwiązań, a nawet języków programowania. Taki stan rzeczy musi przełożyć się na jeszcze większą konkurencyjność projektów wolnodostępnych i ich komercyjnych odpowiedników. Nadszedł czas na zapoznanie się z Java EE 5 w praktyce.