Po 3 letech dělám větší refaktoring na našem direct mailingovém modulu a jako první jsem se rozhodl povýšit verze knihoven a zrefaktorovat JUnit testy, které jsou tam ještě psané ve stylu JDK 1.4.
V souvislosti s tím jsem samozřejmě přepracoval formu testů z dědičné hierarchie na anotace, které byly představeny poprvé ve Spring 3.X (pokud se nepletu). A tu jsem zjistil, že mám drobný problém - v původní verzi mého kódu jsem využíval dynamické kompozice Springového kontextu k tomu, abych stejné integrační testy pustil proti různým implementacím úložišť dat (paměť, MySQL databáze, Oracle databáze .
Škálování databází je velké téma a já rozhodně nejsem takový odborník, abych tady rozebíral kdovíjaké detaily. Zcela jistě znáte termíny jako je sharding, o kterém psal Dagi už před 5 lety, popřípadě znáte termín partitioning, který nám nabízejí některé DB stroje "zadarmo" a jiné "za peníze". Alternativním způsobem horizontálního škálování je škálování pomocí sady replik pro čtení, o kterém lze uvažovat v případě, že máte aplikaci, které řádově méně zapisuje do databáze než z ní čte.
Na tento poklad narazil kolega Jakub Liška, když si sám chtěl napsat něco podobného. Pokud používáte pro automatické testy podporu Springu a na vytváření mocků Mockito, máte řadu možností jak vytvářet mock objekty. Jednu z nich, která se mi zdála poměrně jednoduchá jsem popisoval v dřívějším článku Jak se zbavit nepříjemných závislostí v testech, nicméně tento přístup dotáhl Jakub Janczak o kus dál (jo na světě jsou milóny lidí chytřejších jak já :) ).
Spring security is really powerful library in its current version and I like it much. You can secure your application on method level several years now (this feature was introduced by Spring Security 2 in 4/2008) but we've upgraded from old Acegi Security only recently. When using method access control in larger scale I started to think about security rules encapsulation into standalone annotation definitions. It's something you can live without but in my opinion it could help readibility and maintainability of the code.
Dnešní příspěvek bude velmi krátký. Je dost pravděpodobné, že podobné řešení už dávno máte ve svých tetovacích utilitkách, ale mě tato kombinace napadla relativně nedávno a jsem nadšený z toho, o jak elegantní řešení se pro testy jedná.
V některých testech potřebuji vytvořit část Spring aplikačního kontextu, jehož některé beany mají závislost na nějaké další beaně, kterou je pro mne obtížné do testu zahrnout. Buď z důvodu, že její samotné vytvoření s vyžaduje další komplexní infrastrukturu okolo ní nebo třeba proto, že její zařazení do testovacího kontextu způsobuje při běhu testu vedlejší efekty (např.
Testing transactional aspect of your application is not easy as we usually use Springs' transaction rollback on tear down testing approach. Though there are solutions to test aspect oriented logic it's not without a price. More than that - we very much got used relying on easy-to-use Spring @Transaction annotation so that we don't usually take an effort to do it. There is a few standard Spring rules for rollbacking transaction in relation to method resolution:
Tušil jsem, že to je jednoduché, ale že to je AŽ tak jednoduché, to jsem nevěděl. Dokončujeme projekt pro jednu velkou českou banku a potřebovali jsme mít podrobným logováním pokrytou co největší část aplikace pro případ, že by se vyskytly problémy na prostředí, do kterého, z bezpečnostních důvodů, nemáme a nikdy nebudeme mít přístup.
Jako principiální odpůrce manuální práce jsem ihned zavrhnul myšlenku na manuální procházení kódu a rutinní vkládání debug logování pro strýčka příhodu (krom složitějších metod, kde je to nezbytně nutné).
Dnes se mi podařilo vychytat velmi dobré přednášky, takže jsem si po včerejším dm Serveru rozhodně spravil chuť. První dnešní přednášky se týkala Groovy a především novinek ve verzi 1.6. Zprvu se zdálo, že Guillame pojede pouze po povrchu Groovy, ale brzy se přednáška rozjela, takže si z ní člověk nakonec odnesl opravdu hodně. Přednáška stavěla na publikovaném článku o Grovy 1.6 na InfoQ. Groovy by ve verzi 1.6 mělo být výrazně rychlejší (různé micro benchmarky ukazují zlepšení výkonnosti od 150% do 430%), díky hotspotu dle Guillama dokonce předběhnou některé jiné dynamické jazyky mimo JVM platformu (konkrétně zmiňoval Ruby).
Dnešní den přenesl (alespoň v mém případě) řadu roztrpčení. K tomu se ale dostanu až o pár odstavců později. Dnešní keynote se nesla v duchu Lean software development - a to především ve smyslu, jak se co nejrychleji dostat z fáze vývoje do fáze produkčního běhu. Přednáška byla poměrně zajímavá - Adrian Colyer ukazoval prostřednictvím STS živý deployment Spring / Grails aplikací (byť) triviálních přímo na Google App Engine nebo na Amazon EC2.
Dnes začala v Amsterodamu konference Spring One zaměřená na technologie okolo Spring Frameworku (Spring samotný, Spring MVC, Spring WebFlow, Grails, Spring Batch, Spring Security, Spring tc a dm Server atd.). Konference se koná v hotelu Krasnopolski v úplném centru Amsterodamu. My jsme přijeli o den dříve, abychom si město stihli v klidu prohlédnout a projít si zajímavá místa (Red light district apod. :-) ). Nějaké fotografie si můžete prohlédnout zde. Kromě všudy přítomných coffee shopů mě zarazilo především to, že holanďané si vůbec nepotrpí na soukromí a ve velkých oknech řada domů nemá ani záclony, takže je jim běžně vidět téměř až do postele.
Dynamic proxies can be very nasty if you don't know what happening under the cover. Last week I was searching for the memory leak that caused our application to crash. Even though Tomcat had assigned 1GB memory for heap and 0,5GB for PermGenSpace it stood alive for only approximately twelve hours. It's pretty nasty situation having known that application is only in betatesting with relatively low traffic.
When analyzing generated heap dump I have found, that memory leak was caused by web application classloader, that managed thousands of CgLib dynamically generated classes.
Tento článek mám ve WordPressu rozepsaný snad už rok. Jeho původní název zněl "ResourceBundle - stačí Javě beze změny?". Plno věcí, které jsme původně jako Java vývojáři dělali my, postupně uzpůsobujeme tak, aby je mohli dělat web designeři. Na prezentační vrstvu zcela jistě patří lokalizované texty a zprávy, pro které standardně používáme ResourceBundly Javy, které se načítají z property souborů. Ideální model pro web developery je iterace: navrhnu stránku, vložím text do property bundlu, uložím, reloadnu stránku a kouknu jak to vypadá.
Nice thing about Aspect Oriented Programming is that you can easily add piece of logic to several (possibly other way not connected) parts of your application. You'll only write an Advice (piece of code that should be weaved into original code and executed at exactly specified point of time) and define Pointcut (an expression defining which classes and methods shall be advised). Please, keep in mind, that above description is somewhat simplyfying and that AOP could be much broader than this.
Je tomu už drahně let, co jsem používal k populaci JavaBean Commons-BeanUtils z rodiny Apache Jakarta. Od chvíle, kdy stavím svoje aplikace nad Springem, pozbývá používání této knihovny smysl - naopak bylo by bláhové se této knihovny držet, když Spring nabízí již ve svém základu mnohem víc. Prostým logickým úsudkem lze odvodit, že Spring coby IoC kontejner bude obsahovat promyšlenou logiku pro injektování dat do Java Bean. Nicméně v dokumentaci o tom najdete jen poměrně krátkou kapitolu Validation.
Tento týden jsem řešil problém s nedostatkem paměti při spouštění testů jednoho projektu. Pro běh testů nestačilo výchozích 64MB paměti Javy na heapu, což mi připadlo v porovnání s velikostí projektu podezřelé. Začal jsem profilovat a jelikož mne výsledky poněkud překvapily, chci se s Vámi o ně v tomto článku podělit.
Hned na úvod řeknu, že jádrem problému byla třída AspectJExpressionPointcut. Tato třída je ve Spring dokumentaci zmiňována hned několikrát, velmi jednoduše se používá a ze všech dostupných materiálů jsem dospěl k názoru, že se jedná o doporučovaný a běžně používaný standard.
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í.