27. října 2008

jOpenSpace 2008 - Spring - otevřenost novinkám

Už jsem se bál, že zbytek záznamů z nultého ročníku jOpenSpace neexistují a hned jsem dostal odpověď v podobě dalších pěti záznamů. Šestým v pořadí je záznam od Dagiho Spring adoption in large enterprise project. Spring používáme a převážně jako IoC container, tak mě toto téma zajímalo. Bohužel kvalita zvuku je hodně špatná, takže jsem spíš neslyšel než slyšel.

Přesto jsem zaslechl jednu poznámku, která mě vybudila zamyslet se na téma: Kde se v lidech bere touha poznávat a používat nové vs. držet se v zajetých kolejích? Řadil bych se spíš k těm zvídavým, které nové věci zajímají a přemýšlejí o jejich aplikaci.

Je to dáno tím, že mě programování zajímá? Že to je i můj koníček. Nebo je to tím, že chci něčeho ve své profesi dosáhnout a proto se snažím? Nebo je to prostě tím, že věci většinou dělám pořádně a nesnažím se něco odfláknout, jenom proto abych už to měl za sebou? Asi je nutná kombinace všech zmíněných důvodů, aby programátor měl chuť se sebevzdělávat a tím byl otevřený novým věcem.

Vždyť všechny lidské činnosti podléhají zubu času, stále se hledají lepší a dokonalejší řešení čehokoliv, jenom v oblasti IT je to všechno trochu markantnější a rychlejší. Ovšem pozor, i s prosazováním nových věcí to není tak jednoduché. Je nutné se na ně vždy podívat i skepticky, protože hrozí 2 věci. První je over-engineering projektu, kdy na řešení problému používáme příliš složité technologie. A druhým problémem je vklouznutí do slepé uličky, protože ne vše co se v době svého vzniku jeví jako dobré se dobrým ukáže i po čase používání.

Ve svém důsledku se obávám, že i ty skeptiky, kteří neradi posouvají své znalosti někam dál, potřebujeme. Není přeci nic podnětnějšího než přesvědčování takového člověka, protože je nutné vymýšlet argumenty a při této činnosti se kolikrát ukáže, že jsme měli na očích růžové brýle.

Takže závěrem: doufám, že budeme mít vždy šťastnou ruku ve volbě novinek a že se budu potkávat spíš s těmi nadšenci pro nové věci, které budeme moci probírat a řešit, zda jsou užitečné.

21. října 2008

jOpenSpace 2008 - Metodiky vývoje - jak děláme review kódu

Dneska vám předkládám poslední reakci na první dávku audií z jOpenSpace, po ORM a dokumentaci mě oslovila diskuse na téma metodiky vývoje. Poslední 2 zaznamenaná témata mě k nějakým poznámkám nevyburcovala.

Co se metodiky vývoje v podstatě mě velmi mile překvapilo, že se již naplno prosazují iterativní a agilní způsoby vývoje, které začínají odsouvat nevhodný vodopád. To je velmi potěšující. Je až nepochopitelně překvapující, že se vodopád udržel tak dlouho (mimo jiné podle knihy Craiga Larmana Agile and Iterative Development: A Manager's Guide je zjištění jeho nefunkčnosti hodně staré).

Poslední věc z diskuse je taky všude stejná. Zapojit zákazníka do vývoje je velmi težké, ale pokud se to podaří, je to super věc. My se především staráme o jednu už né-malou aplikaci, kterou poskytujeme jako službu. Je-li zákazník interní (vymyslíme si nějakou funkcionalitu, či vyvíjíme něco dovnitř) pak je to super, je-li zákazník externí, pak je odezva většinou pomalá.

Co ovšem vzbudilo mou chuť napsat tento příspěvek, je poměrně složitý způsob reviewováví kódu, které bylo nastíněno. Protože s naším systémem jsem poměrně hodně spokojen a mám pocit, že je na úrovni, rád se s ním s vámi podělím. Review jsem od začátku zamýšlel tak, aby každý kód, který vytvoříme byl reviewován. Z počátku jsme kontrolovali příchozí změny z CVSka. Pak nás začlo být v teamu víc než 2 a tento postup přestal fungovat.

Zhruba v tu dobu jsme nasadili systém JIRA pro evidenci požadavků. Tím se nám nabídla možnost evidovat jakoukoliv práci na projektu jako požadavek, který definuje, kdo jej bude implementovat a zároveň kdo jej bude reviewovat. Požadavek nemůže být zavřen, pokud nebylo provedeno review. Jednoznačnou výhodou je přehled toho, co se na projektu děje. Dále review provádíme průběžně a nikoliv až na konci iterace (přecijenom dělání review není moc populární a zajímavé), navíc je review skutečně provedeno na každý změněný řádek a to považuji za podstatné (víc očí víc vidí a rozumí-li kódu dva mozky, pak jim pravděpodobně bude rozumět i třetí).

Jako vývojový nástroj používáme Eclipse a proto jsem hledal podporu review kódu integrovatelnou do Eclipse. Jediné co jsem našel byl Jupiter (koukám, že se na něm usilovně pracuje, tak třeba se zlepší). Dlouho jsme jej používali a zjistili jsme, že má řadu nevýhod a proto jsem hledal náhradu. Koukal jsem na Crucible, ale nelíbilo se mi, že by evidence review byla mimo již existující infrastrukturu (podobně jako v případě Jupiteru).

Jako zatím top volba se ukazuje integrovat systém JIRA s naším subversion serverem (pomocí subversion pluginu) tak, aby u každého požadavku zobrazoval change sety, které se jej týkají (k tomu stačí, aby komentář commitu do subversion obsahoval kód požadavku). Následně jsme potřebovali nástroj na zobrazení obsahu subversion a volba padla na Fisheye, protože je sofistikovanější než ViewVC.

A jak samotné review probíhá? Je-li požadavek vyřešen, pak je nutno provést review. Podívám se na požadavek a vidím jaké soubory, byly v souvislosti s jeho řešením commitovány. Přímo ze systému JIRA je možno se prokliknout do Fisheye, kde potřebuji další klik na zobrazení změn souboru s požadavkem souvisejících. Je-li vše v pořádku, pak stačí požadavek označit jako reviewovaný a pak už jej může vedoucí projektu zavřít.

Není-li vše v pořádku, pak přijde na řadu diskuse. Tu nijak nedokomuntujeme a je věcí programátorů, jak ji zrealizují. Pokud se ukáže, že je nutné provést změnu kódu (překvapivě se to děje docela často), pak je v systému JIRA vytvořen další požadavek na změnu (nepřehledný kód, nějaká chyba v kódu, chybějící test atd.). Tento požadavek je normálně řešen a je i reviewován jako každý jiný. Commit do subversion obsahuje kódy obou požadavků, aby byl v systému JIRA spojen s oběma (jak s původním, tak s review).

A jaký má systém výhody a nevýhody? Řadu už jsem jich zmínil, ovšem další výhoda tkví v přesné evidenci toho co se děje, v jakém stavu je který požadavek a co se v souvislosti s jeho plněním měnilo a jak. To je neocenitelné. A nevýhody? Pokud je požadavek hodně rozsáhlý, pak je složitější se v souborech vyznat. Je-li to umocněno více change sety (tj. více commity), je to skutečně náročné.

A uplným závěrem motivační větu: Review kódu skutečně zvyšuje jeho kvalitu a napomáhá dřívějšímu odhalení chyb. Navíc se programátoři učí číst kód druhých, orientovat se v něm, komunikovat o něm a lépe poznávají systém, který programují.

14. října 2008

Spring bean z Java enumu

Dneska jsem potřeboval vytvořit ve Spring IoC Java enum, ale jak na to. Než jsem začal vytvářet nějakou factory, řekl jsem si, že to už musí být vyřešené. Google pomohl a našel jsem blog post Creating a Spring Bean from a Java 5 Enum.

Ve stručnosti se věc dá shrnout do dvou ukázek, první jest pro Spring 1.2.2 a menší:

<bean id="latte" class="cz.xxx.PersonType" factory-method="valueOf">
<constructor-arg>
<value>ADULT</value>
</constructor-arg>
</bean>
Kde ADULT je jméno konkrétního enumu. Domnívám se (nezkoušel jsem), že tuto variantu je nutné použít i ve Springu 1.2.2 a vyšším, pokud se odkazujete na enum v okamžiku, kdy není jasné, že výsledkem má být enum (např. položky listu, mapy).

Používáte-li Spring 1.2.2 a starší, pak na místě kde má být enum stačí použít:
<bean id="person" class="cz.xxx.Person">
<property name="type" value="STUDENT"/>
</bean>
Jednoduché, ale moc šikovné. Tak to mám rád.

13. října 2008

jOpenSpace 2008 - Dokumentace - nezatracujme FOP

A máme tu pokračování inspirované poslechem audio záznamů z jOpenSpace konference. Již jsem psal o ORM a nyní mé poznámky k tématu Dokumentace. Toto téma mě opravdu hodně zajímalo, protože jsem měl dojem, že na našem projektu dokumentace moc nevzniká a hrozně mě zajímalo, jak to dělají druzí.

V podstatě vývojářskou dokumentaci neděláme žádnou, takže pro nováčka může být dost obtížné se v kódu zorientovat. Proč to tak je? No v podstatě se snažíme psát přehledný a jasný kód, což je pohlídané především systémem review, který používáme (o něm více v příštím příspěvku). Navíc je to vše umocněno skutečností, že mé schopnosti orientovat se v kódu jsou nadstandardní a protože podle sebe soudím tebe, myslím si, že to dovedou všichni. Ve výsledku se ukazuje, že to chvilku trvá, ale ve výsledku je struktura aplikace poměrně dobře pochopitelná. Hlavním problémem stejně zůstává skutečnost co aplikace dělá a proč, a o tom bych dokumentaci psal hodně nerad, protože by to bylo na hrozně dlouho.

Byl jsem potěšen, jak i v tomto ohledu je tvorba naší dokumentace v souladu s okolím. Především pro uživatelskou dokumentaci používáme DocBook, který v poslední době editujeme pomocí XMLMindu. A nyní se začínáme malinko odlišovat. Obecně se hovoří o různých způsobech převodu DocBooku do výstupního formátu. Zde jsme šli standardní cestou a tou je XSLT transformace, kterou získáváme jak manuál v HTML tak v PDF (přes FOP). Protože jsme si vybrali jenom podmnožinu DocBooku, kterou podporujeme, máme vlastní šablony, které nejsou komplikované a vše funguje ke 100% spokojenosti. Konfigurace fontů, která byla zmiňovaná jako komplikovaná, zas tak složitá není (v porovnání např. s iTextem je srovnatelně složitá).

Samozřejmě FOP má své mouchy a nedostatky, ale současné verze se od 0.20.5 liší a dosahují uspokojivých výsledků. Navíc se FOP docela vyvíjí a každá nová verze je lepší než ta předchozí.

Jako podpora nanáviděných formátu od nejmenované firmy, bylo zmíněno, že uživatelé stejně vyžadují Wordový dokument, který umějí zpracovat a proto nejde DocBook použít. To není pravda, protože převod DocBooku do RTF není problém a pak pomocí revizí zanést změny zpět do DocBooku také není složité.

Z diskuse je zřejmé, že s dokumentací se bojuje všude a najít vyvážení mezi dost a né příliš záleží projekt od projektu. Ale obecně platí, čím více dokumentace jsme schopní vygenerovat na základě jednoho zdroje (ať už je jím DocBook, kód, UML model atd.) tím lépe pro všechny zúčastněné. Jakmile začneme přepisovat myšlenky z UML, či z kódu do dokumentace je to cesta do pekel, dřív nebo později se dokumentace rozejde s originálem (a když se nerozejde, bude nás to stát velmi vysoké úsilí).

5. října 2008

jOpenSpace 2008 - ORM - Hibernate a klientská aplikace

Konečně jsem se dostal k tomu, abych si poslechl audia z akce jOpenSpace. Pro zájemce bych odkázal především na blog otce Fura.

Konference musela být jisto jistě velmi zajímavá a prospěšná. Moc mě mrzí, že jsem se nezúčastnil, ale mohu si za to především sám, protože jsem zasklil call-for-papers v konference java.cz. Dám si závazek, že napřezrok se to již nebude opakovat.

První záznam je z diskuse o ORM. Nosným tématem je použití Hibernate v klientských aplikacích. Problematické v tomto případě je, že Hibernate session object není thread-safe a Hibernate si hodně zakládá na lazy nahrávání čehokoliv (tj. k nahraným objektům je připojena session a atributy, asociace se dohrávají až v okamžiku, kdy je potřeba).

Klientské aplikace napsané v AWT, Swingu nebo SWT mají jedno velké specifikum oproti aplikacím webovým. Tím specifikem je jednovláknovost těchto knihoven. Tj. kód, který přistupuje k UI tak musí činit z UI vlákna (ve webové aplikaci má každý request své vlákno - skoro vždy). Z tohoto vlákna tedy není vhodné provádět náročné akce, protože dojde k zamrznutí UI. A jak v tomto prostředí řešit přístup k datům (pomocí Hibernate a jeho nesynchronizovaného objektu session)?

Varianty jsou v podstatě tři:

  1. používat session pouze z UI vlákna
  2. používat session pouze z jiného vlákna
  3. používat session jak z UI tak z jiného vlákna
První varianta je špatně, protože provádět dlouho trvající dotazy z UI vlákna zhorší odezvu UI. Druhá varianta je ideální, ale má jedno úskalí. Jak zařídit nahrání všech vlastností a vazeb objektu, které budou v UI potřeba tak, aby již nebylo nutné dotahovat žádná data (tj. jak obejít Hibernate laziness). Třetí varianta spočívá v nahrání dat v jiném vlákně a následném nahrání lazy atributů a vazeb z UI vlákna (dotahují se, až když k nim UI přistoupí a to tak učiní z UI vlákna).

Ještě je nutno zmínit jak to bude se správou session objektů. V prvním případě nám stačí jedna session, protože ji používáme pouze z jednoho vlákna. Pro druhý případ může session potřebovat víc, ale ve své podstatě to záleží na počtu výkonných vláken pro provádění komunikace s DB přes Hibernate. Ve třetím případě určitě potřebujeme pro každou událost (řekněme, že se jedná o obdobu requestu v klientské aplikaci) vlastní session, protože ji použijeme pro nahrání objektů a případné další lazy nahrávání z UI vlákna. Tyto 3 strategie je možné komplikovat dodáním synchronizace a využitím menšího počtu session objektů.

Mě osobně se nejvíce zamlouvá druhá varianta, protože veškerá režie s nahráním dat je mimo UI vlákno. Ale jak nahrát vše co je potřeba? Velmi jednoduše. Stačí, aby model každého UI prvku implementoval speciální rozhraní, které bude vracet ty atributy a vazby, které bude pro své vykreslení potřebovat. Díky tomuto kroku a stromové struktuře UI elementů stačí získat tento seznam pro model root elementu (ten se rekurzivně poptá u svých potomků). Inicializaci lazy atributů a vazeb je možné provést pouhým přistoupením k nim pomocí get metod (nebo pomocí metody initialize).

Bohužel klientskou aplikaci jsem již hodně dlouho nedělal, takže tento návrh je pouze z mé hlavy a né z praktické zkušenosti.

26. září 2008

Jak mě vypekla DB2

Začnu zeširoka. Možnost ukládat XML do databáze v DB2 se mi moc líbí. XQuery je plně integrováno s SQL, je možno tedy dělat dotazy i na XML data z SQL. Navíc jsou plně podporovány indexy, takže vyhledávání může být i rychlé.

Navíc v aplikaci, kterou vyvíjíme je velký tlak na uložení různorodých dat. Vytvářet velké množství tabulek nechci. Ukládat je rozložením do universální tabulky, kde bude více řádků pro jednu entitu (jeden sloupec nese název atributu a druhý jeho hodnotu), taky nechci. Takže jsem si vysnil ukládat je do XML.

10 dní jsem realizoval framework, který mi toto umožní a bude fungovat ruku v ruce s Hibernate. Vše jsem otestoval, vyzkoušel a funguje to super. No a dnes jsem se pustil do realizace v našem produktu. A ejhle, hned jsem narazil na problémy, které mě zastavily.

Není možné mít sloupec typu XML v tabulce, která používá MDC (MultiDimesional Clustering). Velmi špatná zpráva, protože MDC používáme pro zvýšení výkonu přistupu k datům v našich obřích tabulkách. Asi budu muste udělat druhou tabulku, kde budu ukládat pouze XML ... půjde to, ale výkon nebude nic moc ...

A druhá rána, sloupec typu XML nemůže být ve view, které používá INSTEAD OF triggery. Tak to zase používáme pro zápis dat do logovacích tabulek, abychom dokázali trackovat jak se měnila data. To asi budu muset obejít buď logováním přímo z aplikace (pomocí Hibernate a jeho Interceptoru), což se mi nelíbí. Přišel bych o tuto funkcionalitu při přímém přístupu přes SQL. A nebo budu muset udělat trigger přímo na tabulku, což není jednoduché, protože jsem do view často dotahoval data i z jiných tabulek.

Každopádně ... jsou to problémy řešitelné. Ale opět jsem se přesvědčil, že vývoj aplikací není předvídatelná činnost a nedá se naplánovat. Kolikrát si myslíme, že jsme na konci cesty a musíme se zase pěkný kus vracet.

Termín nám straší za dveřmi ... vysvětlete to obchodníkům ...

22. září 2008

Tapestry - jak dělat webové aplikace konfortně

Už je to zase příšerně dlouho co jsem si našel chvíli a navíc jsem měl chuť něco sepsat a protože se mi nahromadilo pár zajímavých čtení o Tapestry, pak je logické, že můj první příspěvek po takové době patří právě Tapetry. Navíc je to pár hodin, co vyšlo Tapestry 5.0.15, které mělo být prvním release candidatem. Bohužel se tak nestalo, kvůli chybičkám objeveným v pozdní stádiu releasu (blíže).

První článek, který vám chci naservírovat, je zajímavý, protože se mu podařilo velmi přehlednou formou shrnout proč je Tapestry zajímavé. Why you should consider Tapestry 5. Bohužel je už malinko starší. Ze stejného blogu pochází i porovnání s Wicket: A glimpse of Wicket 1.4 and Tapestry 5.

Tapestry se vždy hlásilo k následujícím pravidlům: rychlost a škálovatelnost vytvořených aplikací, pohodlný vývoj aplikace bez potřeby speciální podpory v IDE a vysoká produktivita vývojáře. A o produktivitě je Boost Your Productivity Using Apache Tapestry.

Specialitou Tapestry již od verze 4 je vlastní IoC framework. Ve verzi 4 se jednalo o HiveMind, ve verzi 5 jde prostě o Tapestry IoC. Proč má Tapestry vlastní IoC framework, co umí je možné se dočíst ve dvou článcích napsaných přímou autorem Howardem L. Shipem: Tapestry 5 IoC: Binding and Building Services a Tapestry 5 IoC: Introducing Service Configurations.

V neposlední řadě: pozitivní krok je i vznik AppFuse pro Tapestry 5.