22 marca 2008

Komentarz do komentarza w sprawie Spring Framework a Java EE 5

Czy powinienem był oczekiwać czegoś innego? Tak już chyba zostanie, że kiedykolwiek dotknę Spring Framework publicznie, to mogę spodziewać się, że wcześniej czy później przyciągnie to i uwagę Waldiego (w innych, mniej javowych kręgach znanego również jako Waldemar Kot). W ostatniej notatce o zniesieniu adnotacji @Transactional w celu pozbycia się zależności od świata zewnętrznego w tworzonej aplikacji - Słów kilka o transakcjach w Spring Framework napisałem:

W tym sensie jego [=Spring Framework] bogate acz "rozproszone" możliwości mogą być zabójcze dla wielu, niekoniecznie początkujących programistów, którzy postawieni przed wyborem swojej platformy dla następnej aplikacji z pewnością wybiorą serwer aplikacyjny Java EE ze względu na jego "gotowość" (oczywiście znajdzie się wielu odważnych, którzy początkowe trudności w zestawieniu serwera aplikacji z użyciem Springa zrekompensują sobie późniejszą elastrycznością architektury). Możnaby powiedzieć, że serwer aplikacyjny Java EE to aplikacja oparta o Spring Framework ze wszystkimi jego usługami już zestawionymi do poprawnej realizacji wymagań stawianych przez specyfikację Java EE.

Nie trzeba było długo czekać, aby uwaga Waldiego została skierowana właśnie ku niej, gdzie odpowiedział:

Biorąc pod uwagę nasze przekomarzania, pewnie się tego Jacek spodziewasz, ale oczywiście IMHO linia podziału przebiega między Spring a EJB (dokładnie częścią EJB czyli Session Bean i Message Driven Bean, czyli bez JPA), a NIE między Spring a Java EE.
Nie widzę też w Springu tego "wiele" na jego poprawne zestawienie (ani też nie widzę tego "bez większego wysiłku umysłowego" w EJB).
A już w żadnej mierze - o czym zresztą jakiś czas temu na grupie WJUG [=Warszawa JUG - mój dopisek] było - nie można przeciwstawiać serwera aplikacyjnego i Spring. Kombinacja serwer aplikacyjny JEE + Spring jest bardzo mocną platformą na której można budować serwerowe aplikacje.
Trzymałbym się też rzeczywistości, która jasno pokazuje, że "model Spring" w sposób absolutny zdominował "model EJB" i do "zabójstw" nie dochodzi ;-). Wręcz przeciwnie - dzisiaj wielu (większość ???) programistów szczególną uwagę przywiązuje do możliwości łatwego testowania swojego kodu - problem, którego akurat EJB3 (znowu dotyczy Session i Message-Driven Beans) wciąż nie rozwiązuje i nic "gotowego" tu nie oferuje.
Aby podtrzymać DOBRĄ praktykę przekomarzania się, to przyznam, że Twojej analogii o app serwerze jako "aplikacji opartej o Spring" nie załapałem ;-).

I tu wymagany jest mój komentarz do komentarza Waldiego, a że zainteresowany jestem zdaniem innych osób postanowiłem "ubrać" dyskusję w szaty wpisu do Notatnika (ciekawym, czy kiedykolwiek doczekam się dnia, gdzie tego typu dyskusje będą prowadzone na prywatnych blogach, podobnie jak to było swego czasu w pewnym nurcie muzyki, gdzie kolejny kawałek był odpowiedzią na inny - nie pamiętam które to kapele ze sobą w ten sposób rywalizowały, ale było ciekawie - to były jakieś hiphopowe, polskie kapele, które wzorowały się na ich zachodnich odpowiednikach).

Jak ja widzę sprawę Spring Framework a Java EE a może powinienem nawet napisać Spring Framework vs Java EE. Do tej pory spotykam się ze zdaniem, że jakkolwiek połączenie Spring Framework i Java EE to bardzo bogate funkcjonalnie podejście, to ostatecznie większość naszych aplikacji "migruje" w kierunku platformy, gdzie głównym i zazwyczaj jedynym graczem w naszych rozwiązaniach jest Spring, w ramach którego uruchomione (uaktywnione) są inne usługi - utrwalanie danych za pomocą Hibernate, bezpieczeństwo przejmuje Acegi (obecnie Spring Security), szkielet webowy to Spring MVC, bądź podobny, który dobrze integruje się ze Springiem i ostatecznie z całej gamy usług Java EE pozostaje...kontener servletów, którym jest zazwyczaj Apache Tomcat. Zgodzę się, że Spring oferuje wiele i jest ciekawą platformą. Zgodzę się również, że nie wszyscy idą w tym kierunku (acz jest to znacząca większość). Nie mogę się zgodzić i pogodzić z powszechnym przekonaniem, że takie architektury powinno się oferować klientom jako ostateczne. Powód? Większość z tego dobrodziejstwa należy "zestawić" samodzielnie. I tutaj upatruję "wyższości" Java EE nad Springiem. To nazwałem w swojej notatce jako "rozproszone" możliwości. W przeciwieństwie do serwera aplikacji Java EE, usługi w Springu należy najpierw włączyć poprzez ich konfigurację w niezwykle skomplikowanym, xmlowym pliku konfiguracyjnym. W Java EE nie zauważyłem tego skomplikowania, co może być tylko moim postrzeganiem, co jest skomplikowane, a co nie. Temat zestawienia usług w świecie serwerów aplikacji Java EE przejmują właśnie ich dostawcy, którzy pozostawiają nam, twórcom aplikacji korporacyjnych, jedynie ich konfigurację. Postrzegając temat przez pryzmat osób nowych w temacie tworzenia aplikacji korporacyjnych, ich wybór zazwyczaj podyktowany jest zwykle bezkrytycznemu postrzeganiu otaczającego ich świata. Obserwując ruch w moim Notatniku zauważam wyjątkowo wysoką aktywność wokół tematów Hibernate, JBoss Seam czy właśnie Spring. Nie potrafię jeszcze tego wytłumaczyć, ale Hibernate bije większość innych tematów na głowę. Zapewne popularność rozwiązań springowych przesłania możliwości serwerów aplikacji Java EE, które powinny być komplementarnym rozwiązaniem, a nie stawiane jako konkurencja. Tak właśnie postrzegam podział, który wytworzył się po ukazaniu książki Roda Johnsona (autora Springa) , Expert One-on-One J2EE Design and Development (Programmer to Programmer) oraz Expert One-on-One J2EE Development without EJB, która zapoczątkowała erę Springa, w której serwery aplikacyjne zostały umiejscawiane w kategorii niepotrzebnego balastu architektonicznego (za wyjątkiem kontenera webowego). Uważam, że wszechobecność Springa wynika z kopiowania (anty?)wzorców. Spring Framework jako kontener IoC (ang. inversion of control) dostarcza ogrom możliwości, ale co mnie niepokoi, to właśnie to kopiowanie i bezkrytyczne naśladowanie. W ten sposób rodzą się właśnie antywzorce, które przez długi czas są rekomendowane jako wzorce, a dopiero po krytycznym im się przyjrzeniu pokazują swoje pazury i "przepoczwarzają" w antywzorce. Niepokojący jest fakt, że Spring jako de facto standard w zakresie kontenerów IoC przyćmił swoim blaskiem inne, potencjalnie bardziej bogatsze projekty. Dobrym przykładem jest kontener IoC wykorzystywany w Apache Maven - Plexus - niewielki, dobrze sprawujący się i dostarczający wyłącznie funkcjonalności wstrzeliwania zależności kontener DI (ang. dependency injection). Ostatnie dyskusje dotyczące Mavena i mechanizmów DI na grupie dyskusyjnej programistów Mavena (trunk & shading czy XBean and DI?) zwróciły moją uwagę na problem wszechobecnego i bezkrytycznie przyjmowanego Springa. Jego stanowsze NIE dla wprowadzenia Springa czy OSGi pod strzechy Mavena daje do myślenia. Pojawienie się Google Guice jest również sygnałem, że w temacie coś jest na rzeczy i wielu oczekuje czegoś alternatywnego. Pewnie, że do możliwości Springa Guice musi jeszcze dorosnąć, ale niektórym monopol Springa na rozwiązania DI najwyraźniej doskwiera.

Wracając do linii podziału między kontenerem EJB, czy pełnego serwera aplikacji vs Spring Framework niepokojący jest fakt, że wykorzystanie serwera Java EE nie pociąga za sobą wykorzystania Spring Framework (przynajmniej w jego części IoC) i odwrotnie (przynajmniej, w sytuacji, gdzie korzystamy również z kontenera servletów). Wciąż zadaję sobie pytanie Dlaczego?. Jednym z potencjalnych wyjaśnień może być (mam nadzieję) przemijająca nieprzyjazność Java EE w jej wersji 1.4, a szczególnie jeśli chodzi o EJB 2.1. Tak, to można napisać nie narażając się komukolwiek - EJB 2.1 to była wpadka, która kosztowała wiele wielu. Pomysł wspaniały, ale realizacja nie ta. Nieprzespane noce ślęcząc nad generowaniem niepotrzebnego kodu, nauka XDoclet, aby ulżyć cierpieniu, aż tu światełko w tunelu w postaci Springa, książka Roda i zaczęła się masowa migracja do jedynej, właściwej platformy Spring Framework. To faktycznie mogło wielu zniechęcić do Java EE. Teraz wierzę i doświadczam na codzień, że sprawy mają się inaczej - Java EE 5 to wciąż te same usługi, ale bardziej rozbudowane i co ważne prostsze w użyciu oraz gotowe do użycia. Przez gotowość do użycia rozumiem fakt, że wystarczy szczątkowa ilość adnotacji czy xmla, wręcz w wielu przypadkach żadna, i już mamy dostęp do bazy danych, aktywne transakcje, bezpieczeństwo, itp. Nie jest to wystarczające? Dodajmy do tego Springa. Dlaczego nie?! Ów "model springowy", o którym pisał Waldi na pewno miał w tym swoją zasługę na ostateczny wygląd specyfikacji Korporacyjnej Javy 5, a w przypadku Java EE 6 będzie miał jeszcze większy. Kiedy ostatnio konfigurowałem Springa uderzyło mnie kopiowanie kroków, jakie musiałbym wykonać konfigurując serwer aplikacji (zestawienie połączenia do bazy danych, konfiguracja transakcji). Napisałem, że serwer aplikacyjny Java EE to aplikacja oparta o Spring Framework ze wszystkimi jego usługami już zestawionymi do poprawnej realizacji wymagań stawianych przez specyfikację Java EE, co podyktowane było spojrzeniem na Springa z perspektywy wyłącznie jego możliwości IoC/DI, który do pełnej gamy usług dostarczanych przez serwer Java EE wymaga dodatkowo konfiguracji, zewnętrznych do Springa, usług. Takie podejście oczywiście pozwala wręcz na konstrukcję serwera aplikacji, czego dowodem jest chociażby wykorzystanie Springa do konstrukcji kontenera EJB 3 w BEA WebLogic Server. Taki ruch jedynie podkreśla możliwości Springa, ale usługi należy w jakiś sposób dostarczyć. Usługi ustandaryzowane przez specyfikację Java EE jak transakcyjność, bezpieczeństwo, utrwalanie danych, wielowątkowość nie są dostępne w Spring Framework za darmo. Pod tym względem liczba zadań przy zestawieniu aplikacji wyłącznie na Springu jest bardziej pracochłonna i może być zabójcza dla wielu, niekoniecznie początkujących programistów. W serwerze aplikacji Java EE mamy je za darmo, co w Springu wiąże się z utworzeniem pliku XML, czy wykorzystaniem innych alternatywnych środków jak adnotacje (co tak czy owak wymaga poświęcenia naszego czasu na stworzenie tego środowiska, które w przypadku serwera Java EE 5 jest gotowe). Dla mnie, owe środowisko serwera aplikacji zgodnego ze specyfikacją Korporacyjnej Javy 5 będzie tym, co ja nazywam Springiem z dodatkowymi usługami związanymi plikiem XML. Można wyobrazić sobie sytuację, w której Spring IoC po dodaniu wymaganych usług przeistoczy się w Spring Application Server (Spring Java EE). Spring jest dobrym kontenerem IoC, dostarcza wiele ciekawych i użytecznych rozwiązań idąc w górę stosu aplikacyjnego, ale nie zgodzę się, że powinien być wyłącznym sensownym rozwiązaniem, gdzie inne dodatki są jedynie dodatkami i to jeszcze traktowanymi jak niepotrzebnie komplikujące rozwiązanie. Mam takie wrażenie, że postrzeganie serwerów aplikacyjnych Java EE 5 przez użytkowników-praktyków Springa jest nieadekwatne do tychże serwerów możliwości upraszczających tworzenie aplikacji korporacyjnych. Mam wrażenie, że wielu postrzega linie podziału między Springiem vs serwer Java EE 5 jako "albo Springa albo serwer", a niewielu sprowadza temat do dyskusji "jak Spring i aplikacje korporacyjne, to i serwer Java EE", bądź "jak Java EE 5, to i Spring". Sądzę, że najprościej możnaby stwierdzić, że wynika to z naszego okrajania możliwości jednego czy drugiego rozwiązania ze względu na ich niedoceniane możliwości, które wymagają czasu na ewaluację i dogłębne poznanie. Czyż nie prościej i łatwiej wziąść coś z półki "gotowe i polecane" niż "bogatsze funkcjonalnie acz wymagające poznania"? Czyż właśnie nie chodzi o tą ilość czasu, jaką mamy na poznawanie niepoznanego?

Na koniec Waldi dodał:

To w sumie też już było kilka razy poruszane, ale moim skromnym zdaniem w fajny sposób pokazałeś, że CZASAMI te zniesławione ostatnimi czasy deployment deskryptory (nawet XMLowe) mogą być lepszym podejściem (biorąc pod uwagę ZAŁOŻENIA) od będących-cool adnotacji. Wybór "adnotacje vs. zewnętrzna konfiguracja" jest kwestią indywidualną danego programisty. Czasem lepiej pasuje jedno, czasem drugie. Akurat mapowanie OR, czy konfiguracja transakcji należą moim zdaniem do tych, gdzie - zwłaszcza w dłuższej perspektywie - zewnętrzna konfiguracja ma przewagę nad adnotacjami. Marzy mi się takie rozszerzenie do IDE, w którym będzie refaktoring zamieniający jednym kliknięciem adnotacje na konfigurację i odwrotnie...

W tym przypadku podzielam zdanie Waldiego, więc komentarz bardzo krótki ;-) Wydaje się, że programiści znużeni są przytłaczającym xmlem jako medium konfiguracyjne, co najczęściej dotyka mnie osobiście właśnie przy Springu i Apache Maven 2. Nazywam to programowaniem w XMLu. W Maven 1 mieliśmy Apache Jelly i początkowo wszyscy byli nim zachwyceni, ale szczęśliwie nie trwało to długo, aby Maven 2 zarzucił ten pomysł na mechanizm wtyczek pisanych w Javie. To wydaje mi się droga ku krainie szczęśliwości - konfiguracja programowalna w języku programowania, np. Javie, albo czymś znacznie mniej restrykcyjnym, skrojonym na miarę wymagań, np. Groovy, albo JRuby. I tutaj możnaby kontynuować temat wskazując na Apache Buildr, gdzie mamy próbę połączenia dwu światów - możliwości Apache Maven 2 (głównie zarządzanie zależnościami) oraz bogactwem języka programowania JRuby zastępując XMLa skryptami. Nota bene, JRuby sam w sobie jest połączeniem dwu rozwiązań - możliwości programowania z wykorzystaniem Ruby na bazie wirtualnej maszyny Javy (JVM) z jednoczesnym korzystaniem z bogactwa bibliotek javowych. Nie mogę doczekać się dnia, kiedy tego typu synergię ujrzę i w Springu, gdzie poza adnotacjami i programowaniem w XMLu będę miał konfigurację programowalną w wybranym języku skryptowym. A może już to mam, a jeszcze tego nie zauważyłem?