Category Archives: EJB

EJB 3 – injektujeme SFSB

(aneb vstřikujeme zrnka sezení plná stavu)

Konečně jsem našel odpověď na otázku, která už mi dlouho ležela v hlavě. Přivedl mě na ni kolega, který na jednom firemním setkání Javistů někdy před rokem nadnesl otázku „Co se stane, když injektnu stateful session bean do servletu?“

Zajímavé co? Stejná otázka se samozřejmě nabízí i u stateless beanů. Co se stane, když něco co drží stav injektnu (vnesu??) do objektu, který je bezstavový.



@Statefull
public class Cart {
 ...
}

@Stateless
public class Shop
{
  @EJB private Cart cart;
  ...
}

Tak co, víte co se stane? Já už ano. Odpověď mi poskytla docela pěkná kniha EJB 3 in Action. Na straně 136 se dočteme:

Mějte na paměti, že nesmíte injektovat stateful session bean do bezstavového objektu, jako je stateless session bean nebo servlet, který může být sdílen více souběžně přistupujícími klienty (v takovýchto případech používejte JNDI)

Hurá, otázka zodpovězena. Jak tento problém řeší Spring? Ten sice nemá žádný ekvivalent SFSB, ale od verze 2 má tzv. scopy (rozsahy) beanů. Je tedy možné, injektnout bean, který se váže na HTTP session uživatele, do beanu, který je sdílen mezi všemi uživateli? Co se stane v tomto případě? Nenastane stejný problém jako u EJB? To je to ale napínavé co?

Nenastane! Springu totiž můžete říci, aby neinjektoval původní bean, ale proxy. Ta ohlídá aby každý uživatel (session) dostal svoji verzi i v kódu, který o scopu a stavech vůbec nic netuší. Tato proxy se také stará o vytvoření beanu, pokud je to potřeba. Více podrobností naleznete v dokumentaci Springu.

Jak jsem potkal EJB

Rozhodl jsem se, že se už konečně pořádně naučím EJB. Ano, opravdu, já zavilý odpůrce této technologie, jsem se rozhodl, že poznám nepřítele a to pěkně podrobně.

Začal jsem knihou Head First EJB vřele doporučuji všem, kteří chtějí pochopit EJB. Stejně jako ostatní knihy Head First série nás do tématu uvede hravou a zábavnou formou. Ač je to neuvěřitelné, pokrývá skoro všechny oblasti EJB a to tak, že je pochopíte a zapamatujete si je i při prvním čtení. Nevýhodou této knihy je to, že popisuje EJB 2.0, takže už se zdá trochu pasé. Ale je to zajímavé čtení, které všem doporučuji. Mimo jiné i proto, že stejné jádro je i v EJB 3 i když je notně přikrášleno anotacemi.

Hodně poučné pro mě bylo studium chyb v návrhu a problémů, které tyto chyby působí. Jedna z nejmarkatnějších je recyklace rozhraní. Autoři specifikace se rozhodli, že všechny typy beanů budou sdílet společná rozhraní. Je úplně jedno, že mají úplně jiný životní cyklus a účel, všechny se musejí tvářit jako že jsou v podstatě zaměnitelné. Dostáváme se potom do nepěkné situace, kdy uživatel SLSB vidí na rozharní EJBObjektu nesmyslnou metodu getPrimaryKey. Autor SLSB musí naimplementovat metody ejbActivate a ejbPassivate, které stejně nikdy nebudou zavolány. Stejně tak si může v EJBContextu zavolat metodu setRollbackOnly jenom pokud zrovna používá CMT, když je v BMT, tuto metodu vidí, ale zavolat ji nesmí. Toto nepíši protože bych chtěl kritizovat, nepochybuji o tom, že autoři specifikace měli jenom ty nejlepší úmysly. Je podle mě dobré si ale takovéto chyby uvědomit, abychom je neopakovali.

V tomto případě je zdroj problému zřejmý. V EJB 2 se řeší konfigurací něco by se mělo řešit kódem. Jestli je session bean stateless nebo statefull se určuje v XML souboru. To by naznačovalo, že je to jenom otázka konfigurace a až při deploymentu se rozhodneme jakého typu daný bean bude. To je samozřejmě nesmysl. SLSB a SFSB jsou objekty s naprosto jiným životním cyklem i použitím a jejich kód rozhodně zaměnitelný není. Celá mašinérie EJB by byla mnohem snazší na pochopení, kdyby měl každý typ beanu svá vlastní rozhraní. Nemá smysl psát do konfiguračního souboru něco, co stejně konfigurovat nejde. Co si z toho beru za ponaučení?

Nebudu recyklovat rozhraní.

Nebojte, neustrnul jsem jen u EJB 2. Vrhl jsem se i na verzi 3, ale o tom snad někdy příště.

Už tam budem?

Právě jsem dokoukal záznam z přednášky Roda Johnsona s názvem „Už tam budem?“ (Are we there yet?) Vřele ji doporučuji, člověk se v ní doslechne mnoho zajímavých myšlenek.

Jak už název napovídá, celá přednáška měla být o tom, jestli už se Java vyvinula natolik, aby v ní bylo bezproblémové vyvíjet enterprise aplikace. Začíná zajímavým ohlédnutím do roku 2003, kdy jedinými masově rozšířenými open source projekty v Javě byly Struts a Log4j. Upozorňuje také na zajímavý posun v myšlení vývojářů. V roce 2003 panovalo přesvědčení, že na to, aby mohla být technologie úspěšná, musí být i komplexní. Dnes už tomuto věří málokdo.

Dle svého zvyku se přednášející obouvá do EJB. Hlavně do jejich snahy skrýt některé věci před vývojáři (pooling, starání se o vlákna atp.) Zaujaly mě následující hlášky

Když se k vývojářům budeme chovat jako k opicím, jediné co dostaneme bude tlupa naštvaných opic.

Je zásadní chybou definovat infrastrukturu a architekturu s tím, že architekti a vývojáři jsou hloupí.

Tento problém nemají jen EJB, setkáme se s tím i u všelijakých vlastnoručně psaných frameworků. Podle Roda Johnsona se omezením kreativity vývojařů o hodně připravíme. Toto téma vede k zamyšlení nad standardy a specifikacemi. Dovolím se opět ocitovat

Specifikace dobře pochopených problémů jsou úspěšné.

Je snadné standardizovat něco, co se za dvacet let nezměnilo.

Evidentními příklady jsou JMS, JTA a JNDI. Jsou to věci, které v době jejich specifikace byly dobře prozkoumány a jejich standardy jsou tím pádem úspěšné. Naproti tomu standardizování věcí, které ještě nejsou dobře prozkoumány vede k problémům (např. entity beany)

Zásadní myšlenka zazněla přibližně uprostřed prezentace.

Většina Java aplikací není objektově orientována.

Nejprve mě to překvapilo, ale pak jsem si uvědomil, že má pravdu. Uvědomme si, že objekt je cosi co seskupuje data a chování do jedné entity. Podíváme-li se na klasickou třívrstvou Java aplikaci, zjistíme, že tříd, které by měly obojí je tam minimum. Máme servisní vrstvu, která je obvykle bezstavová a kromě konfigurace v sobě moc dat nemá. V podstatě obsahuje jenom chování. Na druhé straně pak máme doménový model, který obvykle jenom drží data a neobsahuje žádné chování. To je zajímavé. Všichni tvrdíme, že OOP je dobrý nápad, ale přesto programujeme více méně procedurálně. Připravujeme se tím o spoustu výhod, které nám OOP nabízí.

Obchodní logika v servisní vrstvě není znovupoužitelná.

Co s tím? Řešením je přesunout logiku do doménových objektů. Tzn. místo toho abychom měli službu, která zaregistruje mazlíčka u veterináře, mít příslušnou metodu přímo u třídy reprezentující veterináře. Narazíme zde ale na jeden problém. Jak nainjektovat podpůrné služby do doménového objektu? Přes Spring to nejde, doménové objekty jsou obvykle instanciovány OR nástroji. Řešením je AspektJ. Napíšeme si malou anotaci (nebo XML konfiguraci) a můžeme injektovat přímo do doménového modelu. Pan Johnson tvrdí, že se tím výrazně zvýší znovupoužitelnost kódu.

V poslední části prezentace uvidíme zajímavou studii interceptorů v EJB 3. Zde se autoři specifikace nepoučili ze zkušeností AOP aliance a rozhodli se, že si problém AOP vyřeší po svém.

Ve skutečnosti nezáleží na tom jak je člověk chytrý, když mu chybí zkušenost.

U EJB 3 máme AOP bez pointcutů. Tzn. jediný způsob jak určit, kdy se interceptor zavolá, je přidat ke třídě nebo metodě příslušnou anotaci (nebo se vrhnou do ekvivalentní XML konfigurace). Není možné říci například, že chci mít interceptor kolem všech metod v tomto balíku. To je přinejmenším nepohodlné. Není možné říci, že chci volat interceptor jen u metod, které mají parametr daného typu. To už je i náchylné na chybu.

EJB interceptory jsou experimentální.

Ano, ještě nikdo nikdy nezkoušel dělat AOP bez pointcutů. Dá se očekávat, že se přitom narazí na problémy.

A jak zní odpověď na otázku v názvu prezentace? Dovolím si zde použít citát z Murphyho zákonů

Končí-li novinový titulek otazníkem, zní odpověď “ne”.

Zbývá ještě dost problémů, které je třeba v Javě vyřešit, než budeme moci říci, že vývoj enterprise aplikací je v ní bezproblémový.

Upozornění: V tomto příspěvku se mísí citáty Roda Johnsona s mojí interpretací. Netvrdím, že všechno co zde píši řekl, je to spíš o tom co jsem si z toho vzal já. Pokud chcete informace nezkreslené, vřele doporučuji originál.