Aplikační události jsou jedním ze základních stavebních kamenů Springu a proto by bylo škoda se ochudit o tuto skvělou vlastnost na rozhraní modulů. Je zřejmé, že nebudeme chtít otevřít všechny aplikační události svému okolí, nicméně u řady událostí bychom chtěli umožnit ostatním modulům reagovat. Jako příklad uvedu interakci mezi modulem pro správu uživatelů a notifikačním modulem - notifikační modul se stará o rozesílání emailových notifikací v reakci na konkrétní aplikační události (samozřejmě obecně - konfigurovatelně).
V prvním díle jsme si ukázali, jak jednotlivé moduly separovat a propojit ve stromu. V předchozím pak způsob, jak strom udržet konzistentní a refreshovatelný za běhu aplikace. Dnešní díl bude o tom, jak jednotlivé moduly mezi sebou propojit - respektive, jak zajistit interakci mezi jednotlivými moduly. Vystavení "interface" bean modulů Pokud se vydáte cestou tvorby stromu z aplikačních kontextů, pravděpodobně narazíte na problém rozhraní jednotlivých modulů. Vraťme se k našemu příkladu reportovacího modulu, modulu uživatelů a web aplikace.
V této části seriálu si rozebereme problematiku refreshe stromu aplikačních kontextů. Toto je skvělá vlastnost Springu, která je často nedoceněná a málo používaná. Díky ní je možné jednoduše zahodit všechny současné instance bean definované v aplikačním kontextu a provést kompletní reinicalizaci kontextu s aktuální konfigurací (tak můžeme elegantně změnit chování aplikace bez nutnosti restartu serveru). S refreshem aplikačního kontextu se dá vyřešit poměrně dost věcí i v produkčním prostředí - navíc netrpí problémem PermGenSpace jako při reloadu kontextu celé aplikace na serveru.
V tomto díle si povíme něco o aplikačních kontextech, jejich vlastnostech a možnosti jejich řetězení do stromové struktury. Tato část je základem principem celého modulární skladby, jejíž detaily vám budu v následujících dílech popisovat. Jak jsem již uváděl v předmluvě, nejedná se o nic světoborného, jen o základní principy Springu.
Aplikační kontexty Celý Spring je postaven na aplikačních kontextech. Aplikační kontext se dá nejlépe přiblížit ke class loaderům v Javě, má i řadu podobných vlastností.
Ve chvíli, kdy začnete používat při vývoji masivněji Spring Framework a začnete vytvářet znovupoužitelné knihovny postavené nad tímto frameworkem, začnete řešit jak z těchto knihoven co nejlépe složit výslednou aplikaci. První myšlenky povedou pravděpodobně těmito cestami:
konfigurační soubory jednotlivých knihoven sloučit v jednom velkém aplikačním kontextu držet jednotlivé knihovny odděleně - nechat jim jejich vlastní aplikační kontexty a k těmto kontextům se dostávat programovým způsobem Obě cesty však mají svá úskalí.
Pokud mi někdo řekne, že moje aplikace má běžet v aplikačním serveru OC4J naskočí mi husí kůže. Tento reflex se mi už dostal do podvědomí kvůli řadě bezesných nocí řešením řady chyb ukrytých v kódu, ke kterým člověk nemá zdrojové kódy. Nedá se ovšem nic dělat, náš zákazník, náš pán. Opět jsem se tedy musel ponořit do zakalených vod bažiny OC4J.
Pozn.: Tento příspěvek byl psán ve velké depresi. Kdo nemáte rádi pesimistické články před víkendem, radši ani nepokračujte ;-) .
Tento post je tak trochu věnován Petru Ferschmannovi ze SoftEU, který bude mít 19. září 2007 přednášku na téma praktické nasazení Mavenu na CZJUGu. Jelikož vím, že občas na můj blog zamíří (doufám že pravidelně :-) ), věřím, že na článek zareaguje a kdo ví - třeba na moje otázky v září odpoví.
Problémy s maven-release-plugin Vycházím z praktické zkušenosti (cca 3/4 roku staré tedy), kdy jsem se snažil použít maven-release-plugin pro vydávání verzi v multiprojektu.
Integrace build systému do IDE je věc pro mne nepostradatelná. Není ovšem integrace jako integrace. Pokud používáte Maven 2 a IntelliJ Idea jako my zjistíte, že pluginů je řada, ale velmi rozdílné kvality a velmi rozdílné aktuálnosti.
Navíc osobně si velmi cením možnosti buildovat projekt přímo z IDE - toto buildování je totiž řádově rychlejší než kterýkoli ant / maven build, jelikož IDE ví přesně, které třídy se změnily a zda je třeba překompilovat závislé třídy a když, tak jaké.
Integrační testy spočívají v testování konkrétní kódu spolu s okolními částmi, se kterými spolupracuje. Cílem je snaha otestovat kód ve stavu, který se blíží reálnému nasazení. Obvykle takto testujeme datovou vrstvu aplikace (jelikož tam klasické jednotkové testy ztrácejí smysl - chceme přeci otestovat správné dotazování databáze, tudíž databázi k testu potřebujeme) a v řadě případů se nám nevyplatí mockovat ani na úrovni business vrstvy. Dokonce i Rod Johnson ve své prezentaci (kterou byl inspirován tento článek) zdůrazňuje důležitost integračních testů.
Jsou chyby malé, velké, závažné i triviální, úsměvné, spletité i velmi hloupé. Z celého pokolení chyb je tahle velmi, velmi stará a také dost hloupá. A vypadá to, že z úcty k jejímu věku, ji nechá M$ už pokojně dožít spolu s chatrčí zvanou Internet Explorer.
Na chybu narazíte tehdy, když coby Java programátor napíšete servlet, který vrací binární data přes protokol HTTPS (např. vygenerovaný MS Excel jako já, nebo třeba PDF atd.
Nedávno na jednom připomínkovacím sezení mě zákazník překvapil přáním, že bych chtěl chránit své emailové adresy uvedené v kontaktech jako <a href="mailto:blabla@blabla.cz"/> proti zneužití spamboty. Jedná se o poměrně jednoduché přání, se kterým jsem se ale ve své praxi setkal poprvé. Obvykle, většina z nás akceptuje toto riziko výměnou za to, že naši zákazníci jednoduše kliknou na odkaz a otevře se jim rovnou jejich mailový klient s předvyplněnou adresou. Ihned nás napadlo vyměnit mailto linky za emaily vepsané např.
Spring framework má "od přírody" k dispozici implementaci Observer patternu. To není nic jiného než mechanismus "listenerů" tak, jak jej známe například ze Swingu. Základní a defaultní implementace je velmi jednoduchá, kdekoliv v managovaných beanách můžete přes tzv. Publisher (což je typicky aplikační kontext, kterým je daná beana vytvořena) vyslat informaci o události. Tuto událost pak může zpracovat jakákoliv třída implementující ApplicationListener rozhraní, a která je správně zaregistrovaná do fronty listenerů.
This presentation was prepared formerly for internal purposes of Norkom Technologies in Ireland by my old friend Pavel Jetenský. We appreciate that authorities of this company allowed us to make the presentation public so you can benefit from it as well. I also thank Pavel for preparing this presentation and for providing support to me with finalizing material to be published.
The training shows how to jUnit test J2EE application based on Spring and Hibernate.
Na serveru The Server Side vyšel zajímavý článek o Artifactory. Pro ty kdož chtějí Artifactory nasadit pro vnitrofiremní použití se jistě jedná o velmi užitečný článek. Faktem je, že Artifactory se dá velmi jednoduše nasadit i bez větších znalostí - jedná se o velmi user friendly aplikaci.
Jediný problém, na který jsem narazil (a který je tedy relativně dost nepříjemný) byl ve verzi 1.2.1-rc0, kdy při deployi do repository se náhodně vracel HTTP 500 - Internal Server Error, díky problematické práci se zámky v JackRabbitu.
Je možné zajistit bezpečné sdílení HTTP session mezi oběma protokoly? Z dostupné dokumentace se dozvídáme, že nikoliv. Tento článek se zabývá možným řešením, které za jistých podmínek umožňuje bezpečně sdílet společnou session. Důvod proč se tímto problémem zabývat je jednoduchý - SSL šifrování je výpočetně nákladná věc (viz. např. Performance analysis of Secure HTTP Protocol). Proto je možná vhodné používat HTTPS pouze tam, kde je k tomu důvod (tedy např. uživatel pracuje s některými důvěrnými daty).
Jistě jste také už mnohokrát, stejně jako já, řešili problém, jak spolehlivě automaticky otestovat, že vaše aplikace správně odeslala email s konkrétním obsahem na konkrétní emailovou adresu. Problém je to zapeklitý a dosud jsem ho dokázal řešit jen těmito způsoby:
udáním testovací schránky a automatickým výběrem této schránky (např. přes protokol POP3) vytvořením mock objektu, který mi zastoupil třídu starající se o odeslání emailu (tzn. k žádnému emailu fyzicky v testu nedošlo) Oba dva přístupy mají svá úskalí.
V projektu, na kterém v současné době pracuji, bylo navrženo poměrně extenzivní použití AJAXových funkcí. Proto jsem se, coby AJAXem dosud netknutý vývojář, vrhnul do studia knihoven, které by mi realizaci usnadnily. Výsledkem mi bylo zjištění, které uvádím v titulku příspěvku - není AJAX jako AJAX. Každá z knihoven tento problém řeší velmi odlišně - a přestože mé první kroky vedly k GWT, brzy jsem tento záměr opustil.
Jelikož pracuji ve společnosti, která své krédo staví na velmi propracovaných webech - co se týká použitelnosti, přístupnosti, validity a grafickém vzhledu (o tuhle stránku věci se naštěstí nestarám já ;)) - bylo nutné zajistit, aby stejná funkcionalita byla přístupná s AJAXem i bez něj.
Nedá mi to, abych nenapsal něco o frameworku iBatis. Někteří jej možná znáte, někteří jste možná o něm už slyšeli, ale dle trafficu na java.cz konferenci bych řekl, že jej většina z vás přehlíží. Zůstal nepovšimnut i v našem krají protřelém CZ podcastu číslo 8. Myslím, že je to škoda a proto jsem se rozhodl o malou osvětovou, nebo-li, jak by řekl Roumen, evangelizační práci.
Ještě v úvodu bych rád podotknul, že někomu se může zdát že to není ten pravý "
Na http://theserverside.com vyšla upoutávka na elektronickou knihu o Mavenu. Trošku jsem do ní nakouknul a opravdu poměrně podrobně a přehledně pokrývá problematiku okolo tohoto skvělého projektového systému. Vřele doporučuji, už jsem si ji zařadil do fronty - díky přehlednosti v ní jistě bude možné nalézt i řešení na ad hoc problémy.
HTML verzi naleznete zde
PDF verzi ke stažení zde
V poslední době jsem zjistil, že některé věci, které já považuji za samozřejmé, pokud se rozhlédnu kolem sebe, tak úplně samozřejmé nejsou. Jednou z nich je debugování Javovského kódu. I v dnešní době, kdy je podpora ze strany technologií na perfektní úrovni je mnoho vývojářů, kteří pro rutinní vývoj (nemluvím o řešení problémů po nasazení aplikace) a odlaďování kódu debuggování nepoužívají a spoléhají se na záznamy z logu. Je pravda, že tento přístup má své výhody – obvykle se tímto způsobem obohatí kód dostatečným množstvím logů, že i v produkci je obvykle dost informací k řešení problémů, pokud nastanou.