29. prosince 2008

JSF: zkušenosti s NetAdvantage

O NetAdvantage komponentách jsem již několikrát psal (1, 2, 3) a rád bych napsal ještě jednou a tím to uzavřel. Již jsem se dříve snažil o nějaké zhodnocení a na to bych rád dnes navázal. Pokud se od té doby něco změnilo nebo jsou určité věci jinak než dříve, tak to nyní uvedu, jinak platí to co jsem již napsal.

S NetAdvantage komponentami jsme dělali přibližně půl roku, z toho tři měsíce celkem intenzivně. Projekt jsme zdárně stihli, takže (snad) všechny problémy, které jsme s komponentami měli, jsme dokázali nějak vyřešit. O použitých technologiích jsem psal v tomto příspěvku.

Ještě uvedu, že se budu vyjadřovat k verzi 8.2.20082.1003 - od té doby byly vydány dva nové hotfixy, takže něco může být lehce jinak.

Výhody

Seznam výhod nebudu rozšiřovat, stále platí co jsem již napsal. U podpory prohlížečů jsme narazili pouze na jeden problém a to v nastavení modality okénka (ig:dialogWindow) v IE 6 - v této verzi IE se nám prostě modální okénka nepodařilo rozchodit.

Obecně bych jako největší výhody NetAdvantage označil vzhled a AJAX. Komponenty vypadají hned "v základu" moc hezky, vše je možné skinovat. AJAX funguje bez problémů, člověk ho může používat, aniž by o něm něco věděl.

Nevýhody

Seznam nevýhod resp. nedostatků musím celkem rozšířit. Nejdříve bych ale doplnil informace uvedené v předchozím shrnutí:
  • dokumentace - úroveň uvedené dokumentace (JavaDoc a příručka programátora) jsou pořád na stejné úrovni, jen navíc přibyly nové stránky s ukázkami a příklady. Tyto stránky jsou moc pěkně udělány a navíc obsahují hodně vychytávek, které nikde jinde v dokumentaci uvedeny vůbec nejsou.

  • AJAX a MyFaces Orchestra spolu moc nefungují (neplatí) - toto již neplatí, chyba na straně Apache Orchestra (pozn. ona to úplně nebyla chyba, protože nikde není přesně popsáno jak má fungovat JSF a AJAX dohromady) byla opravena.

  • podpora pouze JSF 1.1 (neplatí) - jak jsem již psal, tak je možné již používat JSF 1.2.


Nyní bych rozšířil seznam nedostatků, na které jsme narazili v průběhu vývoje:
  • JSF chybové zprávy - v konfiguraci JSF jsme nastavili odkaz na vlastní properties soubor s chybovými hláškami. Správně se používají u standardních JSF komponent, ovšem s NetAdvantage komponentami (konkrétně např. ig:dateChoose) se pořád používají chybové hlášky z myfaces.jar.

  • nemožnost používat čisté HTML - i když samotné facelets umožňují libovolné používání "čistého" HTML včetně EL bez nějakých tagů (kdekoliv na stránce mohu použít #{data}), tak bohužel toto neplatí pro NetAdvantage komponenty. Uvnitř těchto komponent (my jsme to raději používali všude) je nutné EL volat pomocí h:outputText a čisté HTML tagy (konkrétné DIV) nahrazovat tagy z Tomahawku (t:div).

  • komponenta ig:dropDownList nefunguje s konvertery - o této chybě jsem již psal, zde uvádím znovu jen kvůli úplnosti

  • ig:link nemá onClick() - NetAdvantage náhrada za h:commandLink má navíc hlavně vestavěnou podporu pro AJAX, ale bohužel nemá metodu onClick. To je například problém, když máte tabulku s možností smazání libovolného řádku s tím, že vlastní smazání musí být ještě potvrzeno. Pokud chci AJAX, tak nemám možnost toto udělat, museli jsme použít normální h:commandLink a oželet v tomto případě AJAX.

  • ig:dateChooser ignoruje locale

  • problémy s ig:dialogWindow - ig:dialogWindow vytváří modální/nemodální okénko (ne pop-up okénko). Zde máme občas problémy s tím, že modalita není dodržena (při více aktivních okénkách na stránce) nebo si uživatel občas může všimnout problikávání při načítání stránky. Ale toto jsou pouze "kosmetické" věci, které bohužel uživatel připomínkuje nejčastěji.

  • předávání parametrů do komponent - vytvářeli jsme si Facelets komponenty pro různé tabulky (ig:gridView), protože jednou se tabulka použije v detailu, podruhé v editaci atd. Naše komponenty měly vždy alespoň jeden parametr a to dataSource pro načtení dat do tabulky. Bohužel předávání proměnné datového zdroje jako parametr naší Facelets komponenty nefungoval.

  • rekurzivní vytváření stromu - komponenta ig:tree umožňuje vytvářet stromy. Jednou z možností načtení dat do stromu je rekurzivní přístup, který nám bohužel nefungoval.

  • předávání objektu řádky tabulky pomocí f:setPropertyActionListener - NetAdvantage komponenta pro tabulku ig:gridView nabízí objekt #{DATA_ROW}, který představuje aktuální objekt pro určitou řádku tabulky. Bohužel není možné tento objekt nasetovat pomocí f:setPropertyActionListener.

  • ...


Závěr

Nakonec jsem vypsal jen ty nejdůležitější nedostatky, protože jich je mnohem více. Většina z nich je reportována výrobci jako chyba a většina z reportovaných chyb je označena statusem "In Development", tak snad budou někdy opravené.

Pokud nás během vývoje něco brzdilo, tak to byly NetAdvantage komponenty, protože vždy nějakou dobu trvalo, než jsme našli tu správnou cestičku. Musím hned ale dodat, že absolutní většinu všech nedostatků se nám podařilo vyřešit, obejít. Také je otázka, zda by to bylo výrazně jiné s jinými JSF komponentami? Pro nás to byl první větší projekt s JSF, takže jsme se učili spoustu věcí za běhu. Během vývoje jsme se několikrát ptali sami sebe, zda nezkusit jiné komponenty, ale dobře jsme udělali, že jsme vydrželi.

Závěrečná otázka asi bude "Použít či nepoužít"? Vzhledem k tomu, že již znám "cestičku", kudy jít při vývoji s NetAdvantage komponentami, tak bych se nebál je použít i na dalším projektu. Zvláště pokud by byla možnost do projektu zasahovat již v době návrhu, tak aby se již v této fázi eliminovaly "neprůjezdné cestičky". U nového projektu nevím. Pokud by to mělo být jen pro jeden projekt a nic dále, tak bych do toho nešel, ale pokud je to s vidinou toho, že to budete využívat i na dalších projektech, tak se pak ten čas navíc (u našeho projektu cca 20% času vývoje) celkem vrátí.

23. prosince 2008

Druhý rok Javičky

K napsání tohoto příspěvku mě inspiroval Otec Fura :). Sice (bohužel) nemám takové výsledky jako on, ale i přesto si myslím, že špatné to úplně není. Jedna věc jsou statistiky a druhá věc je vlastní naplnění, tedy že to vůbec dává nějaký smysl psát blog. Na úplném začátku psaní tohoto blogu jsem měl určité představy a musím říct, že se my všechny tyto představy naplnily. Proto asi pořád ještě píšu :).

Používám také Google Analytics, ale začal jsem ho používat až v polovině května, takže mé statistiky nejsou za celý rok. Sice od začátku používám službu Navrcholu, ale ta pro neplatícího uživatele mnoho nenabízí.

Mě se dosud v tomto roce podařilo napsat 35 článků. Aspoň pro mě je to celkem velké číslo, protože roční holčička bere čím dál více času a práce je také celkem dost. Podle rozvržení jednotlivých článků v průběhu roku je hezky vidět, kdy jsem měl napilno (to jsem moc nepsal, protože člověk je rád, že u toho počítače nemusí pořád sedět) a kdy jsem něco navrhoval nebo zkoušel (to jsem psal nejvíce, protože člověk má nejvíce nových podnětů a rád se s nimi podělí).

Souhrnné statistiky za rok 2008

  • Počet příspěvků: 35
  • Počet unikátních návštěvníků: 8,419 (max. 1,517 září 2008)
  • Počet unikátních návštěv: 15,166 (max. 2,344 září 2008)
  • Počet zobrazení: 22,275 (max. 3,447 září 2008)

Nejčtenější příspěvky (počet přístupů)

  1. Máte čas na unit testy? (1,135, 5.10%)
  2. Srozumitelnost zdrojového kódu (1,020, 4.58%)
  3. JSF - sestava sedmi statečných (957, 4.30%)
  4. Hibernate - práce s kolekcemi, ManyToMany vazba (912, 4.09%)
  5. Jakou databázi používáte? - výsledky (810, 3.64%)
  6. OSGi: Použít nebo nepoužít? (763, 3.43%)
  7. Nástroje SoapUI a JMeter (753, 3.38%)
  8. JSF zase nejsou tak špatný ... (751, 3.37%)
  9. Jaký webový framework používáte - výsledky (716, 3.21%)
  10. JSF s NetAdvantage (713, 3.20%)
  11. Komentovat? Určitě ano. (668, 3.00%)
  12. Open-source ESBs (667, 2.99%)
  13. Verzování entit - JBoss Envers (662, 2.97%)
  14. Přechod z Acegi na Spring security (614, 2.76%)
  15. JSF - FacesTrace a MyFaces Orchestra (596, 2.68%)
  16. NTLM a Spring security (486, 2.18%)
  17. Výhody a nevýhody EJB (398, 1.79%)
  18. JSF a Spring - postup o krok dále (353, 1.58%)
  19. Proč nemám rád Seam (347, 1.56%)
  20. Ukázka konfigurace Acegi security (347, 1.56%)

Zdroje přístupu (počet přístupů)

  1. java.cz (7,057, 46.51%)
  2. google (3,491, 23.01%)
  3. přímý přístup (1,768, 11.65%)
  4. root.cz (649, 4.28%)
  5. seznam.cz (613, 4.04%)

Lokace návštěvníků (počet návštěvníků)

  1. Česká Republika (12,211)
  2. Slovensko (1,628)
  3. Německo (350)
  4. Finsko (206)
  5. Velká Británie (180)

Rozvržení prohlížečů (počet návštěvníků)

  1. Firefox (10,470, 69.04%)
  2. Opera (1,912, 12.61%)
  3. Internet Explorer (1,874, 12.36%)

Rozvržení operačních systémů (počet návštěvníků)

  1. MS Windows (12,004, 79.15%)
  2. Linux (2,774, 18.29%)
  3. MacOS (318, 2.10%)

BIRT reports vs. Jasper Reports

Je to dost častý problém - aplikace sbírá data a tyto data je potřeba nějak prezentovat formou reportů. Standardní výstupní formáty jsou HTML (na prohlížení) a PDF (na tisk).

Asi nejznámější řešení na vytváření reportů je Jasper Reports (pěkný článek o Jasper Reports vyšel na Java.cz).

My jsme pro náš projekt zvolili jiné řešení - Eclipse BIRT reports.

Rád bych nyní uvedl takové malé srovnání Jasper Reports a BIRT reports (s laskavým souhlasem mého kolegy Ondřeje Světlíka, který měl reporty na starosti).

Společné vlastnosti

  • umí lokalizaci textů
  • umí přistupovat k datům přímo přes JDBC, ale i jinými způsoby
  • umí grafy
  • umí všechny možné výstupní formáty - pdf, html, doc/rtf, xls a další

Jasper Reports

  • + výrazně menší runtime - cca 5M
  • + editor podporuje přímo práci se Spring beany
  • - nutnost kompilovat .jrxml na .jasper
  • - horší editor
  • - neumí tabulky, skládají se pouze buňky, takže něco jako změna šířky celého sloupce najednou (hlavička, obsah, patička) je nemyslitelné

BIRT reports

  • + lepší editor
  • + editor součástí Eclipse i standalone
  • + umí tabulky
  • + stylování pomocí CSS
  • + umožňuje skriptování v JavaScriptu
  • - obrovský runtime - cca 42M
  • - pokud má být datovým zdrojem Spring bean, musí se použít skriptovaný datový zdroj
  • - větší nároky na PermGen space, je nutné spouštět tomcat s -XX:MaxPermSize=256m (odzkoušená hodnota, zřejmě bude fungovat i menší, ale default 64m nestačí)


Já bych ještě doplnil mé osobní pocity. Velikost BIRT enginu (engine musí být součástí aplikace, generuje samotné reporty) je opravdu značná, v konečném důsledku asi 50MB. To už je celkem nárůst velikosti aplikace, i když se jedná o server.

Moc se mi líbil editor a obecně možnosti BIRTu samotného. Spoustě lidí může vadit přítomnost Javascriptu, ale já s ním problém nemám.

Trochu jsme měli problém s češtinou v PDF reportech, ale to jsme vyřešili nastavením kódování cp1250 v souboru fontsConfig_pdf.xml.

Propojení BIRT enginu a samotné aplikace je realizováno přes servlet - servlet zjistí potřebné informace o reportu (většinou z URL adresy) a předá je BIRT enginu. Ten pak už jen vygeneruje výstup, který se odešle klientovi.

Všechny definice reportů jsou v XML, takže z pohledu verzování nebyl žádný problém.

Jediný problém, který jsme zatím nevyřešili, je horizontální stránkování při výstupu do PDF. Toto BIRT ještě neumí.

S Jasper Reports jsem nikdy moc nedělal, ale asi už ani dělat nebudu. BIRT mě celkem zaujal...

Další odkazy

1. prosince 2008

Jakou databázi používáte? - výsledky

Druhá minianketka je u konce s těmito výsledky:

  1. MySQL (51%)
  2. Oracle (47%)
  3. PostgreSQL (36%)
  4. MSSQL (12%)
  5. Apache Derby (Java DB) (10%)
  6. Jiná embedded (9%)
  7. DB2 (5%)
  8. Jiná standalone (5%)
  9. InterSystems Caché (0%)
Hlasovalo celkem 121 lidí.

Co k tomu říci? Umístění volně dostupných databází MySQL a PostgreSQL není asi žádným překvapením. MySQL je velice rychlá databáze (sice trochu na úkor funkcionality, ale ta není vždy potřeba) s množstvím administračních nástrojů. Já osobně dávám spíše přednost PostgreSQL, protože jednak toho umí opravdu hodně a v případě potřeby je možné bez větších problémů přejít na databázi Oracle.

Odhaduji, že spousta z vás dělá na velkých projektech, protože jinak by nemohla databáze Oracle být na druhém místě :).

Já jsem svůj největší projekt dělal nad MSSQL databází a byl jsem s ní hodně spokojený. Databáze byla určena již zákazníkem před realizací projektu a já jsem se k tomu stavěl trochu skepticky, ale nebylo třeba. Asi hlavní důvod byl ten, že já jsem přeci jen "klikací" uživatel, a proto se mi moc líbila administrace v této databázi - vše velice intuitivní.

Zajímalo by mě vaše využití embedded databází? Já jsem je používal pouze ve spojení s desktopovými aplikacemi, kdy jsem potřeboval ukládat data mezi jednotlivými spouštěními aplikace.

Co mě možná trochu překvapilo je to, že se nenašel nikdo, kdo by používal objektovou databázi Cache. Je to možná tak dva roky, co byla celkem masivní kampaň na používání a výhody Cache a asi se nikdo nechytil. Já osobně nemám žádnou zkušenost, takže nemohu soudit, ale relační databáze tu již jsou hodně dlouho a je to mnohdy jediná věc v IT oddělení firem, která se po léta nemění.

17. listopadu 2008

JSF - sestava sedmi statečných

V předchozím článku jsem zmínil naší sestavu sedmi frameworků resp. knihoven, které používáme pro vývoj s JSF. Některé knihovny byly dané již od začátku, některé se ukázaly jako nezbytné až v průběhu samotného vývoje.

  • Apache MyFaces - úplně na začátku jsme začali se SUNovskou implementací JSF, ale asi po měsíci jsme přešli k MyFaces. Jednak jsme měli pár problémů s NetAdvantage komponentama, které se přechodem vyřešily a jednak jsme dostali pocit, že MyFaces implementace "více" žije, že je lepší bug-fixing apod. Ale toto může být subjektivní. Používáme JSF verze 1.2.

  • NetAdvantage komponenty - o těchto komponentách jsem již něco napsal (1, 2). Snad jen dodám, že někdy v září vyšla nová verze podporující JSF 1.2, která zejména ve spojení s Facelets obsahuje celkem dost chyb. Hodně jsme přemýšleli, zda pokračovat nebo zkusit nějaké jiné komponenty a rozhodli jsme se pokračovat - reportovali jsme hodně chyb a teď víceméně čekáme na nový hotfix. Verze 1.1 a bez Facelets (platí pro obě verze) je mnohem více odladěná.

  • Tomahawk komponenty - primárně využíváme NetAdvantage komponenty, ale sem tam potřebujeme něco jiného nebo něco více. Například tagy t:htmlTag a t:div používáme celkem dost, protože NetAdvantage nedovolují používat čisté HTML ve svých tagách (i když používáme Facelets). Zkoušeli jsme také Trinidad, hlavně kvůli komponentě na výběr barvy, ale od toho jsme nakonec ustoupili - jednak je tato knihovna celkem invazivní (vyžaduje použití vlastního ViewHandleru) a jednak už jsme začali cítit, že těch knihoven máme v projektu nějak moc.

  • Spring framework - bez Springu si už nedovedu představit snad žádnou aplikaci, takže zde nebylo co řešit. Velkou výhodu to přineslo díky MyFaces Orchestra, která implementuje nové konverzační rozsahy pro Spring beany. Používáme Spring EL resolver, takže nemusíme skoro nic definovat přímo v JSF. O bezpečnost aplikace se nám stará Spring security.

  • MyFaces Orchestra - s pomocí Springu implementuje nové konverzační rozsahy, více v tomto článku.

  • Facelets - když už JSF, tak jedině s Facelets. Díky Facelets je JSF mnohem více stravitelnější, je to výborný šablonový systém. Při použití JSF s JSP resp. JSTL si je potřeba dát pozor na spoustu možných problémů (popsáno v tomto článku), které s Facelets odpadají.

  • URL rewriter - díky URL rewriteru jsme byli schopni vyřešit asi největší nedostatky JSF - nemožnost bookmarkovat stránky, nemožnost efektivního zabezpečení stránek pomocí Spring security a problém s "opožděnými" URL (uživatel vidí v prohlížeči URL, které odpovídá předchozí stránce). Také jsme tím mohli zcela vynechat konfiguraci navigace v JSF a nadefinovat jí (dle mého názoru efektivněji) pomocí URL rewriteru.

14. listopadu 2008

JSF zase nejsou tak špatný ...

Sice se zpožděním, ale rád bych reagoval na nedávno vydané články o JSF (1, 2). Možná bych spíše měl napsat doplnil místo reagoval, protože se vším co bylo napsáno souhlasím - na komponentovou technologii JSF jsem přešel teprve letos na jaře a přechod to byl celkem bolestivý. U mě to bylo ještě umocněný tím, že jsme si vybraly NetAdvantage komponenty, které mají celkem dost chyb, takže nebylo výjimkou, že jsem hodiny zkoumal proč něco jednoduchého nefunguje. Teď už si naše JSF sestava (MyFaces, NetAdvantage a Tomahawk komponenty, Spring framework, MyFaces Orchestra, Facelets, URL rewriter) sedla a už to celkem jde.

Chtěl bych uvést pár pozitiv, které jsem u JSF spatřil (nutno dodat, že výhody jsou zejména oproti request-driven řešením, než oproti jiným komponentovým technologiím).

  • JSF je J2EE standard - to má svoje velké nevýhody, ale i svoje výhody - technologie má zaručenou určitou životnost (velice důležité z pohledu investic), lépe se budou hledat programátoři na projekty, existuje určitá konkurence mezi dodavateli JSF komponent.

  • vzhled prodává - ať si každý říká co chce, ale vzhled je velice důležitá věc u většiny aplikací. I když NetAdvantage mají velké množství chyb a nedostatků, tak jedno se jim nedá upřít - jejich komponenty jsou pěkné. Komponenty jsou standardně nabízeny v asi deseti různých odstínech, stačí si jen vybrat nebo si upravit podle svého přání již existující.

  • rychlost vývoje - počátky vývoje aplikace byly hodně pomalé, ale od té doby, co jsme "prokopli" základní struktury stránek (detail, editace, výběr s modálním oknem apod.), tak jde vývoj velice rychle. Již v době návrhu obrazovek a výsledné podoby aplikace jsme věděli, že budeme používat NetAdvantage komponenty a podle toho jsme se to již snažili navrhovat. Teď navíc víme co funguje, co ne, takže jsme schopni navrhnout celkem rychle jakoukoliv stránku s tím, že ji také celkem rychle poskládáme a uděláme.

Nejsem určitě ten, kdo má rád JSF technologii, ale je prostě pár věcí, které s nimi celkem fungují.

3. listopadu 2008

Stromová data v relační databázi

Řešil jsem nyní na projektu uložení a práci se stromovou strukturou dat.



Každého asi napadne řešení, kdy objekt si bude držet referenci na svého předka. Toto řešení je funkční, ale má jednu velkou nevýhodu a tou je pomalost načítání stromu. To je dáno rekurzivním algoritmem a tedy velkým množstvím dotazů do databáze. Na druhou stranu je velice jednoduché přidávat nové objekty nebo je přesouvat. Tento model se označuje jako The Adjacency List Model.

Já jsem ale potřeboval "opačné řešení" - co nejrychlejší načítání stromu i za cenu toho, že při správě stromu si uživatel chvíli počká. Pro tento případ je ideální tzv. Modified Preorder Tree Traversal algoritmus. Ten si kromě odkazu na svého předchůdce eviduje další dvě pomocné hodnoty, tak aby sestavení stromu bylo co nejrychlejší. Naopak změny v hierarchii stromu mohou vést k nutnosti přepočítat pomocné hodnoty u všech objektů.


Více informací k uvedené problematice lze nalézt zde:

19. října 2008

Jaký webový framework používáte - výsledky

První minianketka je u konce s těmito výsledky:

  1. Spring MVC (36%)
  2. JSF (34%)
  3. Struts (16%)
  4. Něco jiného (14%)
  5. Samotné JSP a JSTL (8%)
  6. JBoss Seam (8%)
  7. Apache Wicket (6%)
  8. Spring Web Flow (6%)
  9. Tapestry (4%)

Hlasovalo celkem 61 lidí, takže se zrovna o velký vzorek lidí nejedná :(. Nechci z toho vyvozovat nějaké velké závěry, ale pár myšlenek si dovolím.

Pro mě osobně je Spring MVC a JSF volbou číslo jedna v současné době. Pokud potřebuji mít vše pod kontrolou, potřebuji mít rychlý web s velkou návštěvností, tak budu volit Spring MVC. Pokud si mohu dovolit JSF, tak volím JSF - tedy zejména pro intranetové aplikace, složité stránky a formuláře. Jedna volba nevylučuje druhou - JSF použiji třeba pro administrátorskou část aplikace, Spring MVC pro část prezentující data.

Struts mají silnou pozici z minulosti, takže na tom poběží pořád hodně projektů. Moc ale nepředpokládám, že by se toto řešení v nějaké větší míře používalo ještě dnes u nových projektů. Když už, tak aspoň Struts 2.

Tapestry jsou celkem staré (dnes je již beta verze páté verze) a ve své době měly několik revolučních věcí (např. provázání HTML a komponent přes speciální atribut, komponentový přístup), které ovšem v současné době jiné frameworky, které se nechaly inspirovat, řeší lépe (např. JSF Facelets, Apache Wicket). Musím se přiznat, že mě osobně nikdy moc Tapestry nezaujali.

Hodně by mě zajímalo, co se schovává pod "Něco jiného" u lidí, kteří tuto volbu zaškrtli. Možná Shale, WebWork, něco proprietárního, nevím...

26. září 2008

JSF s NetAdvantage - pokračování

Nedávno jsem psal o zkušenostech s komponentami NetAdvantage. Od té doby vyšla nová verze s celkem zásadními změnami, tak bych je rád uvedl.

Hlavní změna je ta, že jsou již podporovány JSF verze 1.2. Vzhledem k tomu, že vývoj naší aplikace je pořád spíše na začátku, tak jsme hned stáhli novou verzi a přešli na JSF 1.2. Přechod byl na 99% úspěšný, snad jen dvě chybky jsme jim tam našli.

Také jsme se rozhodli opustit klasické JSF a přejít na facelets. Zde těch problémů ze strany NetAdvantage komponent je více, některé celkem zásadní, např. nemožnost použití WebChart komponent. Více na stránkách známých omezení (1, 2, 3).

Problém s konvertery, o kterém jsem psal minule ("komponenta ig:dropDownList nefunguje s konvertery"), se nakonec ukázal jako ještě větší a obecnější, který zasahuje přes více komponent, např. dateChooser.



Z mojí mini ankety "Jaký webový framework používáte?" zatím vyplývá, že se JSF používají celkem dost. Mě by hodně zajímalo, zda využíváte pouze open-source knihovny nebo zda máte nějakou zkušenost s jinými komerčními JSF knihovnami?

25. září 2008

Proč JPA, když mi stačí Hibernate?

Většinu projektů jsem v minulosti realizovat pomocí "čistého" Hibernatu (Hibernate Core). Na posledním projektu jsem byl nucen přejít na Hibernate Entity Manager resp. JPA z důvodu použití nástroje JBoss Envers na verzování. Sice to byl pádný důvod proč přejít na JPA, ale pokud bych tento důvod neměl, tak jina žádný důvod pro přechod k JPA nemám, spíše naopak.

Než si začnu stěžovat, tak ještě musím uvést, že píši v kontextu lightweight aplikací. Při použití EJB resp. aplikačních serverů je to zcela jiné, tam vidím velký význam a přínos ve standardizaci rozhraní datové vrstvy.

Zde jsou některé mé stížnosti:

  • JPA toho zdaleka neumí tolik co samotný Hibernate (viz list of all Hibernate extension annotations nebo Hibernate Annotation Extensions).

  • Na předchozí bod je možné namítnout, že mi nic nebrání, abych tyto rozšíření používal. To je pravda, ale proč pak nepoužít přímo Hibernate? Jedna z uváděných vlastností JPA je ta, že je možné vyměnit ORM engine pokud se budu držet JPA specifikace. Má to vůbec smysl? Občas potřebuji vyměnit databázi, ale nevím, kdy bych potřeboval vyměnit ORM engine.

  • Nedávno jsem řešil problém s ukládáním souborů (BLOB objektů) do databáze. Spring nabízí jako vždy pomoc - třída AbstractLobType a její implementace (hezký popis je na tomto blogu). Zde je ovšem podmínkou konfigurovat Hibernate pomocí LocalSessionFactoryBean, tedy používat "čistý" Hibernate Core.

  • Konfigurace Hibernatu přes JPA je trochu přes ruku. Většina věcí se musí konfigurovat přes properties v persistence.xml. Je ale pravda, že nyní (všimnul jsem si toho až v poslední verzi 3.4 Entity Manageru) je možné používat JPA a konfigurovat Hibernate přes standardní hibernate.cfg.xml soubor, viz hibernate.ejb.cfgfile property.

  • Stejnou výtku jako v předešlém bodě mohu mít ke psaní JPQL dotazů. Samotný JPQL sice vychází z HQL, ale takové možnosti nemá. Mohu zase používat HQL, mohu využívat Session, nativní JDBC dotazy, ale vše je to přímočařejší s Hibernate bez JPA.

12. září 2008

Srozumitelnost zdrojového kódu

K dnešnímu psaní mě inspirovat článek s názvem "Four harmful Java idioms, and how to fix them" na serveru JavaWorld. Nedalo mi to, abych k tomu nenapsat něco svého.

Pro ty, kdo to nechtějí číst celé mám zde krátké resumé. Autor článku navrhuje čtyři následující řešení (lépe řečeno reaguje na čtyři celkem rozšířené idiomy) pro lepší čitelnost zdrojového kódu resp. pro jeho lepší použitelnost, pochopení, údržbu:

  1. Konvence pro rozlišení lokálních proměnných, argumentů metod a proměnných tříd. Autor navrhuje použít a jako prefix pro argumenty metod, f pro proměnné třídy a lokální proměnné nechat bez prefixu.

  2. Sdružovat třídy do balíků podle funkcionality a ne podle vrstev. Hlavní myšlenkou je co nejvíce využít zapouzdřenosti jednotlivých balíků (packages) tak, aby balíky sdružovali všechny třídy (entitu, DAO, kontroller, atd.) pro jednu funkcionalitu. Oproti tomu staví běžný přístup, kdy balíky jsou členěny dle vrstev, tj. balík pro všechny entity, pro všechny DAO objekty atd.

  3. Využívat neměnitelné (immutable) objekty jak je to jen možné. Autor uvádí rozpor v tom, že dnes je všechno JavaBean, což je pravý opak.

  4. Proměnné a metody třídy řadit od nejvíce obecných k nejvíce detailním. Na místo klasického začátku s definicí proměnných začít uvedením veřejných metod, poté soukromé metody a až na konec uvést proměnné.


Tak to máme za sebou krátké resumé a teď konečně má reakce k jednotlivým bodům:
  1. Toto se mi zdá celkem přínosné, i když mě trochu odrazuje moje zkušenost s "Maďarskou konvencí" z časů, kdy jsem ještě programoval v C++. Hodně lidí bude argumentovat tím, že v IDE to každý hned pozná, ale ne vždy mohu IDE používat.

  2. K tomuto bodu mám asi největší výhrady. Sice čitelnost super (mám vše na jednom místě, nemusím skákat mezi balíkama), ale to je tak asi všechno. Další velký argument zapouzdřenost má určitě něco do sebe, ale nevidím v tom takový problém. Já se spíše snažím o zapouzdřenost na úrovni modulů, tj. několika balíků, uvnitř modulů mi to tolik nevadí. A nakonec v přístupu "package-by-feature" vidím nevýhodu při používání AOP - když mám strukturu "package-by-layer" tak mohu pěkně využívat AOP přes různé vrstvy, protože mi tomu odpovídá struktura balíků. Také se mi bude určitě lépe "řezat" aplikace, když budu potřebovat škálovat.

  3. K tomuto není co dodat, výhody jsou zřejmé. Spíše je obecný problém v tom, že JavaBeany jsou natolik rozšířené, až je to problém. Každý "nepřemýšlející" programátor sází jeden JavaBean za druhým. Polehčující okolností může být to, že často používané knihovny, např. JSF, ORM knihovny, Spring MVC ho k tomu víceméně tlačí.

  4. Autor argumentuje tím, jak člověk efektivně řeší problémy - nejdříve ho zajímají vysokoúrovňové věci a postupně jde do detailů. Zajímavé, nikdy jsem o tom takto nepřemýšlel. Zde mě ale hlavně zarazilo to, že je to vlastně v rozporu s Java konvencí od Sunu. K tomu prý Joshua Bloch říká: "I wouldn't take that document [Sun's Coding Conventions] too seriously. It is not actively maintained or used at Sun.". Co dodat :).


A jaký styl programování máte vy? Používáte třeba některý z těchto přístupů?

7. září 2008

JSF s NetAdvantage

Pro poslední projekt jsme se rozhodli použít JSF. Jedná se o intranetovou aplikaci s velkým důrazem na vzhled a funkčnost grafického rozhraní, takže jsme si řekli, že by to nemuselo být špatné to udělat pomocí JSF. Moc zkušeností s JSF jsme v týmu neměli, takže jsme se rozhodli použít nějakou komerční JSF distribuci, zejména kvůli podpoře. Nakonec jsme vybrali NetAdvantage for JSF (máme verzi 2008 Volume 1) od firmy Infragistics.

S NetAdvantage pracujeme celkem intenzivně dva měsíce, což už je doba na nějaké to shrnutí. Jako každé řešení, tak i toto má svoje výhody a nevýhody.

Výhody

  • podpora AJAXu - programátor nemusí nic vědět o AJAXu a může bez problémů dělat AJAXové aplikace. AJAXové chování lze ovlivnit jednak pomocí atributů jednotlivých komponent resp. tagů a nebo pomocí Java API z managed beanů. Už žádný Javascript, vše funguje úplně parádně samo.

  • kvalitní podpora - komponenty NetAdvantage se kupují na dobu jednoho roku a je možné si vybrat různé úrovně podpory. My máme tu základní úroveň, což znamená, že můžeme psát na fórum a nebo přímo jim s případnými problémy. Odezvy na naše dotazy jsou hodně dobré, řekněme v průměru do jednoho dne. Většinou odpovídají ještě v rámci dne (řekl bych, že někteří členové týmu jsou z východní Evropy, takže mají stejnou pracovní dobu jako my).

  • web grid (tabulka) - tabulku používáme velice často, a proto když jsme vybírali mezi různými distribucemi, tak jsme právě na tabulky dávali velký důraz. Tabulka od NetAdvantage toho umí opravdu hodně, to se nám již potvrdilo.

  • grafy - ty jsme zatím nepoužily, ale stačí se podívat do ukázek a člověk uvidí opravdu hodně velké množství všech různých typů grafů. Stačí si jen vybrat...

  • podpora Apache MyFaces a Sun RI JSF - NetAdvantage fungují nad oběma základníma implementacemi JSF. My jsme nejdříve používali Sunovskou verzi a pak jsme přešli na MyFaces verzi. Důvod? Zatím spíše subjektivní - MyFaces více žije, rychleji se opravují případné problémy a hlavně bychom rádi postupně začali využívat další komponenty (Tomahawk, Tobago, ...) od MyFaces.

  • podpora prohlížečů - vzhled a chování komponent je odladěné pro všechny nejpoužívanější prohlížeče.

  • velké množství skinů - NetAdvantage nabízí velké množství (cca 15) barevných skinů, takže není až tak velký problém s návrhem grafického rozhraní aplikace dle svých požadavků.

  • hotfixy - každý software má své chyby a nejinak je tomu u NetAdvantage. V průměru každý měsíc až dva měsíce vychází nový hotfix, který opravuje reportované chyby. Toto bych řekl, že celkem funguje.


Nevýhody

  • dokumentace - celkově mi dokumentace nepřijde moc kvalitní. JavaDoc sice existuje, ale skoro bez popisu. Zbylá dokumentace obsahuje pouze základní informace a některé věci tam ani nejsou, např. komponenta ig:link. Součástí instalace jsou i ukázky včetně zdrojových kódů, takže pro první seznámení to stačí. Horší kvalita dokumentace je vyvážena podporou ze strany výrobce komponent. Abych byl spravedlivý, tak zde musím uvést, že když jsem začínal s NetAdvantage, tak jsem začínal i s JSF, takže jsem dost často neřešil ani tak problémy s NetAdvantage jako spíše s JSF.

  • AJAX a MyFaces Orchestra spolu moc nefungují - používám MyFaces Orchestra kvůli konverzacím (viz minulý článek) a jak se ukázalo, tak neexistuje žádný standard pro implementaci AJAXu v JSF komponentách. Zatím to tedy dohromady moc nefunguje (některá AJAXová volání nesprávně ukončují konverzaci), snad se to nějak vyřeší (1, 2, 3)

  • podpora pouze JSF 1.1 - v současné verzi komponent NetAdvantage je podporována pouze JSF verze 1.1. JSF 1.2 budou podporovány od další verze.

  • komponenta ig:dropDownList nefunguje s konvertery - komponenta ig:dropDownList je náhradou za standardní JSF komponentu h:selectOneMenu, ovšem s podporou AJAXu. Bohužel ig:dropDownList nefunguje správně s konvertery, takže se s tím úplně dobře nepracuje.


Ještě toho budeme hodně zkoušet, takže pravděpodobně tento článek bude mít své pokračování. Zatím jsme třeba ještě nezapojili jiné komponenty třetích stran než od NetAdvantage, takže jsem zvědavý na vzájemnou kompatibilitu.

Další zajímavé zdroje:

25. srpna 2008

JSF - FacesTrace a MyFaces Orchestra

Teprve nedávno jsem začal používat JSF a musím se přiznat, že se v tom pořád tak nějak plácám. Jsem zvyklý, že při programování mám vždy vše pod kontrolou, ale tady z toho takový pocit nemám. Ale toto téma si nechám až na nějaký další článek.

V tomto článku bych chtěl zmínit dvě knihovny, které mi celkem zpříjemnily mojí práci s JSF.

FacesTrace

Pokud nastane nějaký problém s JSF, tak někdy je dost těžké vůbec zjistit příčinu problému - skoro žádné logování, skoro žádné ladící informace. Tato knihovna v tomto ohledu aspoň trochu pomůže.

Použití je velice jednoduché - přidá se knihovna k aplikaci a na stránce určené k ladění se použije tag <ft:trace />. Někdy je ještě nutné přidat mapování do web.xml.
Ukázku poskytnutých informací lze vidět zde.

MyFaces Orchestra

Při práci s JSF dost často nestačí ukládat proměnné jen do rozsahu requestu (pokud tedy chceme zachovat "rozumnou eleganci" vývoje s JSF). Potom musíme sáhnout po session, což není ideální, minimálně z pohledu nároků na paměť a škálovatelnosti (další důvody jsou uvedeny zde).
MyFaces Orchestra nabízí něco mezi - konverzaci. MyFaces Orchestra vyžaduje přítomnost Springu, protože využívá možnosti Springu si definovat vlastní rozsah (scope) pro uložení beanů resp. JSF managed beanů. Je možné využívát dva typy konverzací:
  • automatická - konverzace se automaticky vytvoří při přechodu na bean, který je definován pro rozsah konverzace. Při přechodu na bean s jiným rozsahem (request, session) se konverzace automaticky ukončuje.

  • manuální - řízení začátku a konce konverzace je plně na programátorovi pomocí dostupného API.

Kromě toho knihovna ještě nabízí "persistence in conversation". Tedy něco jako "session in view", ale zde pouze v rozsahu konverzací.

Knihovna je nezávislá na implementaci JSF API, tedy funguje nejen nad Apache MyFaces, tak i nad Sun RI. Knihovny jsem zkoušel s JSF 1.1.


Pokud máte nějaké další tipy na knihovny, které pomohou s vývojem v JSF, tak sem s nimi prosím :).

Hibernate - práce s kolekcemi, ManyToMany vazba

S Hibernatem dělám již celkem dlouho, ale i tak pořád narážím na nové a nové věci (to bude asi tím, že jsem manuál k Hibernate celý ještě nečetl a vždy se učím až za pochodu). Teď naposledy jsem řešil celkem intenzivně kolekce a asociace.

Není List jako List

Hibernate z pohledu kolekcí rozlišuje tři základní implementace:
Přesnou definici jednotlivých typů lze najít zde.

Když máme třídu, která obsahuje nějaký seznam (java.util.List), tak to ještě vůbec neznamená, že i Hibernate s tím bude pracovat jako s indexovanou kolekcí. Pro Hibernate se to stává indexovanou kolekcí teprve tehdy, když je definován i index pro jednotlivé položky (@IndexColumn), jinak List Hibernate interně zpracovává jako bags, což může mít nějaké nevýhody, viz další kapitola.

Kromě samotné podoby kolekce je ještě potřeba brát v potaz použitou asociaci mezi třídou s kolekcí a elementy kolekce. Ne všechny případy asociací mohou být z principu indexované (např. obousměrná (bidirectional) ManyToMany vazba). Obecně nelze mít indexované kolekce označené jako inverzní (nastavení inverse="true" v XML konfiguraci nebo použití mappedBy při vytváření asociace pomocí anotací). Přehled typů kolekcí vs. asociací je možné nalézt zde.

One shot delete

Máme kolekci elementů a přidáme nový jeden element. Pokud kolekce není interně interpretována jako indexovaná kolekce, tak pak se změna provádí takto - smažou se všechny elementy a poté se znovu přidají jeden po druhém včetně toho nového. Toto může mít některé negativní dopady, např. pokud potřebujete vést historii všech změn nebo když např. používáme triggery nad vazební tabulkou. Z pohledu kolekcí je nejlepší mít indexované kolekce (viz předchozí kapitola) - pak má Hibernate vše pod kontrolou a když je potřeba přidat jednu položku, tak přidá do databáze pouze jednu položku.

Na druhou stranu je ale někdy žádoucí, aby se smazaly všechny položky a poté znovu přidaly (one shot delete), např. z pohledu výkonnosti, když deset položek chci odebrat a jednu smazat. Toho lze docílit znovu inicializací originální kolekce. Jinak řečeno vytvořím novou kolekci na základě staré.
Nevýhoda indexovaných kolekcí je ta, že při odmazání elementu uprostřed seznamu je nutné upravit indexy všech elementů, které následují.
Více lze opět najít v dokumentaci k Hibernate v kapitole One shot delete.

Práce s obousměrnou ManyToMany vazbou

Mezi objekty ClassA a ClassB je oboustranný vztah ManyToMany, tj. ClassA obsahuje množinu objektů ClassB a naopak. Pokud chceme přidat objekt ClassA do množiny objektů ClassB, pak musíme přidat i objekt ClassB do množiny objektů ClassA.
Z pohledu ukládání obou objektů a jejich kolekcí je potřeba si uvědomit, že nestačí provést uložení pouze nad jedním objektem. Pouze ta strana resp. ten objekt, který je vlastníkem vazby, může uložit změny do databáze.
Podrobné info je v této kapitole.

Otázkou je, zda se lépe nepracuje pouze s jednosměrnou ManyToMany vazbou. Relaci mezi objekty mi drží pouze jeden objekt, takže z pohledu spravování to mám jednodušší. A pokud chci získat i opačný pohled, tak mohu použít tento dotaz (vysvětlení: AssetGroup obsahuje kolekci objektů Asset, vazba mezi oběma objekty je ManyToMany):

SELECT ag
FROM com..AssetGroup ag,
com..Asset a
WHERE a IN ELEMENTS(ag.assets) AND a = :asset

Pořadí práce nad objekty

V nějakém příspěvku jsem našel následující pořadí, v kterém Hibernate vykonává operace nad "svými" objekty:
  1. all entity insertions, in the same order the corresponding objects were saved using Session.save()
  2. all entity updates
  3. all collection deletions
  4. all collection element deletions, updates and insertions
  5. all collection insertions
  6. all entity deletions, in the same order the corresponding objects were deleted using Session.delete()


Tento článek jsem napsal hlavně kvůli sobě, protože zapomínám. Vzvláště s Hibernatem je to znát, protože ten intenzivně používám pouze na začátcích projektů a to zase není tak často.

10. července 2008

Verzování entit - JBoss Envers

Sledování historie změn není nijak výjimečný požadavek, a proto mě i celkem překvapuje, že na tomto poli nejsou (nebo jsem nenašel) skoro žádné open-source projekty, které by toto řešily. Jeden jsem však našel a jmenuje se JBoss Envers.

Nemá cenu opisovat, to co je uvedeno na webu projektu, jen bych zase uvedl pár poznámek.

Envers potřebuje pro svoji práci Hibernate a Hibernate Entity Manager.

Nyní se projekt nachází ve verzi 1.0.0.Beta2 - kromě verzování atributů entit zvládá základní vazby typu @OneToOne, @OneToMany a @ManyToOne. Zatím neumí (mělo by být ve verzi 1.1.0) takové vazby, kde je automaticky vytvořena vazební tabulka (join table), tedy např. @ManyToMany, ale mohou to být třeba i vazby @OneToMany. Do jisté míry to lze obejít tak, že si vytvořím vlastní vazební entitu a tím pak budu mít pouze vazby @OneToMany nebo @ManyToOne.

Velice příjemné je, že lze vytvořit ANT task, který umí generovat datové schéma včetně tabulek pro verzování a pro evidenci revizí.


Další zdroje:

7. července 2008

Spam: nabídka spolupráce

Dneska budu trochu spamovat a využiji svůj blog pro nabídku pracovní spolupráce. Od srpna začínám působit na volné noze a rád bych vám touto cestou nabídl spolupráci při vývoji softwaru.

Základní informace o mé osobě naleznete na LinkedIn a v případě zájmu mě můžete kontaktovat přímo na adrese pjuza zavináč seznam.cz.

Možná se hned ptáte proč? Těch důvodů je více a od každého něco: touha si to zkusit, nezávislost, možnost vyzkoušení více projektů a prostředí a samozřejmě také snaha o větší peníze. Sám jsem zvědavý, jaké budu mít pocity třeba za rok, ale každopádně jsem nyní rád, že jsem se už rozhodl.

6. července 2008

NTLM a Spring security

Ještě před pár dny jsem skoro nevěděl, co to je NTLM a dnes tento autentifikační protokol používám v mé aplikaci.
Našel jsem na jednom blogu parádní článek, kde je víceméně vše podstatné k implementaci pomocí Spring security řečeno. Nemá cenu se tedy opakovat, spíše bych přidal některé moje poznámky a doplnění:

  • autor článku místo ukázky zřetězení filtrů (Virtual filter chain resp. FilterChainProxy) znovu vložil již dříve uvedený kus kódu. Zde bych to tedy napravil. Pořadí filtrů není libovolné, je nutné si dát pozor na to, že filtr NtlmProcessingFilter musí být za filtrem ExceptionTranslationFilter. Já osobně jsem použil toto zřetězení:
    /ntlm/**=httpSessionContextIntegrationFilter,logoutFilter,ntlmExceptionTranslationFilter,ntlmFilter,filterInvocationInterceptor

  • druhá věc, na kterou je potřeba si dát pozor je ta, že filtr NtlmProcessingFilter slouží pouze pro autentifikaci, nikoliv pro autorizaci uživatelů. Je zde potřeba myslet na to, že při načítání UserDetails pomocí UserDetailsService musí být hodnota uživatelského hesla prázdná. Pro testovací účely si načítám informace o uživatelích z properties souboru (InMemoryDaoImpl), kde mám tento řádek (pozice pro heslo není vyplněna):
    pjuza=,ROLE_ANALYST, ROLE_READER

  • V článku jsem nepochopil autorovu implementaci UserDetailsAuthenticationProvider. Já jsem nic podobného dělat nemusel. Jediné co jsem musel nakonfigurovat pro NTLM byly filtry NtlmProcessingFilter, ExceptionTranslationFilter a musel jsem tyto filtry přidat do FilterChainProxy.

  • NTLM je oficiálně až ve Spring security. Nicméně i v Acegi security lze využít NTLM, viz článek Acegi Security and NTLM.


Další zdroje k implementaci NTLM:

27. června 2008

Přechod z Acegi na Spring security

Na minulých projektech jsme používali Acegi security se spoustou vlastních doplňků a vychytávek. Teď začínáme psát nový projekt a tak jsme si řekli, že je už čas se posunout dát a začít použít Spring security (jeden z důvodů byla podpora NTLM ve Spring security, ale o tom budu psát v dalších příspěvku).

V tomto článku bych rád uvedl moje zkušenosti s touto migrace. Základní naše konfigurace vypadala asi jako ta uvedená v článku Ukázka konfigurace Acegi security plus jsme si vytvořili tzv. bezpečností modul, který obsahuje různá rozšíření, které standardně v Acegi implementovány nejsou (např. zablokování účtu po třech špatných přihlášeních, kontrola na existenci rolí při přihlašování apod.).

Vzal jsem tedy konfiguraci a pár stránek ze starého projektu a nasadil do nového. Musel jsem provést následující úpravy:

  • přejmenovat balíky org.acegisecurity na org.springframework.security. Takže když jsem měl v konfiguraci org.acegisecurity.ui.ExceptionTranslationFilter, tak jsem to musel změnit na org.springframework.security.ui.ExceptionTranslationFilter.

  • přejmenovat některé statické proměnné, např. AbstractProcessingFilter.ACEGI_SECURITY_LAST_EXCEPTION_KEY na AbstractProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY nebo AuthenticationProcessingFilter.ACEGI_SECURITY_LAST_USERNAME_KEY na AuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY. Tyto proměnné nepoužívám přímo v konfiguraci, ale již v rámci našeho kódu.

  • přejmenovat URL pro odhlášení z j_acegi_logout na j_spring_security_logout.

  • přejmenovat URL pro zpracování přihlašovacího formuláře z j_acegi_security_check na j_spring_security_check.


A to je všechno, vše bez problémů. Zatím jsem migroval vše kromě naší knihovny, ale tam již žádné problémy neočekávám. Pouze bude nutné všechny použité třídy z Acegi přejmenovat na Spring security.
Jediné co mě překvapilo je, že jsem nikde na stránkách Springu, ani v dokumentaci Spring security nenašel návod k migraci.

Zdroje informací:

20. června 2008

OSGi: Použít nebo nepoužít?

Hned na začátku článku musím říci, že jsem velký fanda modulárních systémů a OSGi především. Ale to hned nemusí znamenat, že OSGi budu používat vždy a za všech okolností - pro mě je důležité za použitím jakékoliv technologie vidět určitý přínos a tedy důvod, proč danou technologii použít. Samozřejmě to také musí být vyvážené rozumnou pracností.

O OSGi je v poslední době hodně slyšet. Málokdo asi ví, že tato věc vznikla už někdy v roce 1999, takže se nejedná o žádnou novinku. Určitě znáte resp. používáte Eclipse nebo IBM WebSphere - to jsou asi dva hlavní představitelé produktů, které jsou postaveny nad OSGi. Přijde mi, že to správné buzzword z toho udělal až Spring, protože Spring si OSGi vybral jako nosné řešení pro své všechny projekty, pro svoji vlastní aplikační serverovou platformu SpringSource Application Platform. Základem je projekt Spring Dynamic modules, který zase funguje jako nástavba na "čistým" API OSGi a nabízí spoustu ulehčení - prostě standardní Spring :). Možná ještě více publicitě OSGi pomohl sám Sun, který přišel s něčím podobným přímo do JVM - Java Module System. Do teď není zcela jasné, které řešení nakonec zvítězí, ale řekl bych, že OSGi má v současné době navrch.

Cílem článku není vysvětlovat možnosti OSGi, na to jsou jiné weby. Tento článek shrnuje mé osobní poznatky z průzkumu OSGi, jakožto možné platformy pro vývoj naší nové aplikace. Připravujeme vývoj nové webové aplikace (možná by se dalo říci i produktu), která technologicky nevybočuje nijak z průměru (Spring, Hibernate, JSF). Nejedná se také o aplikaci nijak zásadně kritickou, spíše o podpůrný nástroj pro menší skupinku lidí ve firmě. Aplikace to nebude (aspoň na začátku) nijak rozsáhlá.

A teď jsme před rozhodnutím, zda použít nebo nepoužít OSGi. Ještě jsme se finálně nerozhodli, ale spíše to vidím tak, že OSGi pro tento projekt zatím nepoužijeme. Mám k tomu následující důvody:

  • Sice jsem psal, že OSGi bude mít příští rok 10 let, ale v oblasti serverové Javy tak dlouho nepůsobí. Nejdříve tato technologie byla vyvíjena pro mobilní aplikace (to je záruka, že OSGi je opravdu lightweigth řešení), poté se adaptovala v oblasti standalone aplikací (např. Eclipse, kontejner Equinox) a teď v poslední době je snaha o adaptaci v oblasti serverových aplikací. To je trochu složitější, protože jsou potřeba minimálně dva kontejnery - pro Javu resp. servlety a pro OSGi. Jsou plně podporovány kontejnery Tomcat, Jetty a prý další nejsou problém, ale nikde jsem k tomu moc informací nenašel. OSGi kontejner může být vložen do webového kontejneru a naopak, více zde. Jak je možné integrovat do OSGi+webového kontejneru stávající MVC řešení? Co když budu chtít použít další kontejner pro EJB? Tak v tomto vůbec jasno nemám.

  • Abych mohl aplikaci modularizovat pomocí OSGi, tak pak musím mít vše rozdělené do tzv. bundlů - moje i všechny knihovny třetích stran musí být bundly. Vznikají tedy různá repository (např. 1, 2), kde je možné si stáhnout bundly známých knihoven, např. pro Hibernate, Jakarta Commons apod. Nicméně určitě všechny knihovny tam v podobě bundlů nenajdete. Pak jsou dvě možnosti - buď si počkáte až bundle bude a nebo si bundle z jar souborů vytvoříte sami. Buď ručně nebo s pomocí nástroje Bnd.

  • Pokud tedy budu mít OSGi aplikaci, tak mohu za běhu aplikace instalovat, nahrávat, rušit jednotlivé moduly resp. bundly, mohu efektivně řešit verzování apod. Na to se dá říci jen SUPER. Ale potřebuji to tak zrovna pro mojí aplikaci? Nikdy jsem to zrovna nepotřeboval a pro tuto aplikaci to asi také nepotřebuji. Aplikace není kritická, takže ji v pohodě mohu celou otočit. Ani velká moc nebude, takže upgrade bude otázka chvilky. Na druhou stranu mě hned napadá, že se bude jednat o aplikaci s instalacemi a úpravami u více zákazníků, což by se hezky dalo řešit pomocí modulů. Také hromadný upgrade všech instalací z jednoho místa by nemusel být k zahození.

  • Nikdy neříkej nikdy - možná přijde doba, kdy z malé počáteční aplikace bude velký systém, který bude potřebovat modularizovat. Nemám s tím žádnou zkušenost, ale řekl bych, že nebude tak velký problém z již existující aplikace vytvořit OSGi aplikaci. Příkladem mohou být např. Spring projekty, které jsou nyní plně OSGi - jednotlivé jar soubory jsou zároveň bundly exportující a importující potřebné služby resp. balíky.

Nějaké zdroje k OSGi:

13. června 2008

Nástroje SoapUI a JMeter

Uvedené nástroje používám již několik let a myslel jsem si, že jsou natolik známé a rozšířené mezi programátory, že ani nemá cenu se psát, jestli je někdo zná. Překvapivě jsem se mýlil.

JMeter je nástroj pro měření výkonnosti a pro vytváření umělé zátěže na webových projektech. Je to spíše nástroj "pro začátek" - tím myslím to, že kdo opravdu řeší problematiku výkonnosti, robustnosti a škálovatelnosti aplikací, tak asi bude používat jiné, komerční nástroje. Já si většinou pouze chci ověřit, že mnou napsaná aplikace běhá dle očekávání, že tam není vyloženě nějaký problém třeba v konkurenčním přístupu více uživatelů apod. V tomto ohledu naprosto dostačující nástroj.

Bez nástroje SoapUI si vývoj webových služeb vůbec nedovedu představit. Vždy když se vytvoří nová webová služba nebo se nějaká již existující integruje, tak je potřeba si ověřit komunikaci pomocí nějakého klienta. SoupUI není pouze klientem webové služby, ale celkem sofistikovaný nástroj pro jejich vytváření a testování.

Oba dva nástroje jsou samozřejmě open-source, tedy zdarma.

9. června 2008

Znáte Daisy?

Mě tento CMS nástroj doporučil kolega, já ho úspěšně použil pro jednoho zákazníka a tak pozitivní zkušenost šířím dál.

Je to již nějaký čas, co jsem Daisy používal, ale zrovna minulý týden se na mě kamarád obrátil pro radu, tak jsem si na Daisy znovu vzpomněl.

Na Daisy jsem oceňoval hlavně tyto věci:

  • aplikace je napsaná v Javě, takže pro mě není problém aplikaci kustomizovat

  • přišla mi velice intuitivní, takže jsem se s tím velice rychle naučil

  • udělal jsem tam vše, co jsem potřeboval - zákazníkovi jsme pomocí Daisy vytvářeli skladiště dokumentace k projektům. Bylo tedy potřeba vytvořit nějakou základní strukturu úložiště pro uložení dat včetně nastavení přístupových práv. Vložené dokumenty (zejména MS Word) se automaticky indexují a lze přes ně fulltextově vyhledávat. Daisy je natolik uživatelsky přívětivé, že zákazník po zaškolení používá aplikaci sám.

Ve svých poznámkách jsem našel jedinou nevýhodu, se kterou jsem se potkal - měl jsem občas problém s češtinou při fulltextovém vyhledávání (používal jsem verzi 2.1). Neměl jsem čas a ani prostor to moc řešit, takže ani nevím, jak to dopadlo.

2. června 2008

Open-source ESBs

Integrace, SOA, ESB - to jsou buzzwords poslední doby. Není to jen módní vlna, která hlavně vychází z marketingových snah velkých firem, ale také realita současnosti - existuje spousta starých či nových systémů, které je potřeba propojovat. Pokud je těch systémů více (více jak 5), tak už nemá cenu to propojovat přímo mezi sebou, ale využít nějaké ESB řešení.

Pro náročná řešení a náročné zákazníky máme v portfóliu naší firmy produkty od IBM - WebSphere Process Server, WebSphere Integration Developer a WebSphere Enterprise Service Bus.

Kromě toho ale potřebujeme i dostupná řešení pro širokou škálu zákazníků, takže jsem se začal dívat po nějakých open-source ESB řešeních. Dal jsem dohromady krátký seznam řešení, na která jsem narazil spolu s body, které mě zaujaly. Hned říkám, že žádné praktické zkušenosti s uvedenými systémy nemám a za jakékoliv informace tohoto typu budu velice rád.

MuleESB

  • URL: http://www.mulesource.com, http://www.muleforge.org
  • konfigurace pomoci Springu, systém postaven nad Springem
  • velice úspěšný a rozšířený open-source projekt (7 firem z fortune 50)
  • kromě ESB mají další produkty zaměřené na SOA. Některé z nich jsou dostupné v rámci podpory.
  • OSGi ready
  • MuleForge - web pro hostování projektu pro Mule rozšíření, např. různé konektory k systémům třetích stran

JBoss ESB

  • URL: http://www.jboss.org/jbossesb/, http://www.jboss.com/products/platforms/soa
  • podpora od české firmy - lokální partner firma Servodata
  • možnost školení v češtině
  • postaveno na základech Rosetta ESB, které JBoss získal v roce 2006. Rosetta ESB je prověřené řešení vyvinuté a používané ve velké Kanadské pojišťovací společnosti.
  • součástí podpory jsou i nastroje pro monitorování a další věci, které normálně volně dostupné nejsou
  • actions mohou byt instalovány/odinstalovány za běhu
  • JBoss nabízí celkem velké portfolio technologií a platforem, se kterými se dá vystavět aplikace od A do Z včetně integrace

WSO2 ESB

  • URL: http://wso2.com/products/esb/, http://synapse.apache.org/
  • řešení je postaveno nad Apache Synapse, pouze je rozšířeno o administrátorské rozhraní. Autoři WSO2 ESB jsou i autory Apache Synapse.
  • jednoduché, malé řešení určené zejména pro mediace a transformace zpráv, není k dispozici orchestrace.

OpenESB

  • URL: https://open-esb.dev.java.net/
  • Uvádím jen pro úplnost, ale s ohledem na předchozí řešení mi toto již nepřipadá tolik zajímavé, a proto jsem ho dal pryč z užšího výběru.


Závěr

Ještě jsme nic nevybrali. Není to ovšem vždy jen o technologické úrovni, ale hodně také o politice - jaké naše firma má partnery, koho můžeme podporovat a koho ne atd.
Mě je zatím nejsympatičtější ESB od Mule. Proč? To nedokážu přesně popsat, zatím jen pocit :). Finální výběr vidím mezi MuleESB a JBoss ESB. Apache Synapse se mi moc libí hlavně z toho důvodu, že je to malé, lehké řešení a to že nemá orchestrace zase tak vadit nemusí, na to jsou větší řešení (říká se, že dává smysl něco orchestrovat pro více než 5 služeb což odpovídá spíše středním firmám). Proti mluví to, že nemá cenu se učit tolik systému (něco pro velké zákazníky, něco pro střední a něco jen pro lehké věci), proto asi Synapsi také vyřazuji z výběru.

18. května 2008

Komentovat? Určitě ano.

Opět jsem se setkal s názorem, že komentovat zdrojové kódy není potřeba, že kód sám o sobě je dokumentace. K tomu můžu říci jen jedno - to je naprostá blbost.

Stačí nepracovat s vlastním kódem několik týdnů a už člověk ztrácí přehled o jemných detailech algoritmů, které sám psal. Nemluvě pak o tom, když je potřeba opravit chybu v rok staré aplikaci a nebo pracovat v kódu svých kolegů.

Také jsem slyšel "Jsem orientovaný na výkon a psaní komentářů mě brzdí". To je hodně krátkozraké, protože možná je člověk o pár minut rychlejší, když implementuje algoritmus, ale z dlouhodobějšího pohledu je to samozřejmě krátkozraké - čas strávený nad zjišťováním, jak jsem to já nebo můj kolega vlastně tehdy mysleli, je mnohem větší než kolik se dá ušetřit na jednom algoritmu bez komentářů. Ale já bych se vůbec do těchto polemik nepouštěl, protože dle mého názoru zdrojový kód se automaticky rovná kód plus komentáře.

Při psaní komentářů je potřeba nezapomínat, že zdrojové kódy nejsou Java soubory, ale také třeba konfigurační soubory, soubory prezentační vrstvy atd. To jsou také zdrojáky a ty je potřeba také komentovat.

Opačný extrém je takový, že na jeden řádek kódu připadají dva řádky komentáře. Není potřeba komentovat to, co je zřejmé z vlastního kódu. Zdrojový kód je jako dobrodružná knížka, kde jazyk Java popisuje vlastní děj příběhu. Komentáře jsou pak dějová vysvětlení, aby se čtenář v jednotlivých zápletkách neztratil. Pokud je toho vysvětlování příliš na úkor vlastního děje, tak pak to asi moc záživná knížka nebude.

14. května 2008

Máte čas na unit testy?

Pokud bych si měl hned sám odpovědět, tak dle mého názoru moc času není. Není z jednoho hlavního důvodu a to jsou peníze resp. náklady plynoucí z času, který bude věnován psaní unit testů. Hned na začátku také musím dodat, že celý článek je o "normálních" jednorázových projektech, které nejsou nějak mission-critical. U vývoje produktu (tj. aplikace, kterou zabalím a pošlu zákazníkům nebo aplikace, kterou opakovaně dodávám) předpokládám, že bude prostor pro psaní testů mnohem větší.

Ještě jsem nedělal ve firmě, kde by se počítalo s tím, že N dní budu vyvíjet produkční kód a dalších N dní budu mít vyhrazeno na testování (pozn. píši to sice v pořadí produkční kód, testy, ale klidně je možné si představit přístup opačný - TDD). Takto to často prezentují agilní přístupy k vývoji softwaru, ale v praxi je dle mého názoru toto neuskutečnitelné, aspoň tedy v rámci projektového vývoje, protože poměr nákladů na psaní unit testů vs. přínosy z toho plynoucí nejsou zrovna moc pozitivní.

V žádném případě nejsem odpůrce psaní testů, ale realita mě nějak naučila se na tu problematiku dívat i z jiného pohledu než jen vývojářského. Vidím spoustu výhod ze psaní testů, zejména následující dva:

  • zajištění požadované kvality produkčního kódu
  • kvalitou se nemyslí jen kód bez chyb, ale i takové věci, jako kvalitní architektura aplikace, dobrá dekompozice problému apod. Pokud chci psát efektivně testy, tak pak potřebuji mít i dostatečně kvalitní produkční kód.

Samozřejmě bez testů to nejde, nedovedu si představit, že bych takto odevzdal aplikaci zákazníkovi. Ale na jaké testy se zaměřit, aby přínosy a náklady byly v rozumné rovnováze? Dle mých zkušeností jsem asi nejlepší poměr přínosy vs. náklady zaznamenal v těchto případech:
  • znovupoužitelný kus kódu (knihovna, modul)
  • stěžejní aplikační logika, např. jádro aplikace
  • doménové objekty - equals. Na to jsou již testy napsané, takže je jen použít. Přínos možná malý, ale ušetří spoustu času při hledání chyb s kolekcemi.
  • při použití ORM nástroje testovat základní CRUD operace nad objekty. Pro tyto účely jsem si napsal sérii testů, protože je to stejné pořád dokola a je dobré vědět, že práce s DB na té základní úrovni funguje jak má. Spíše je to testování ORM mapování jako celku, než jen samotného procesu ukládání dat do DB.

Naopak mám negativní zkušenost z Mock (jMock, EasyMock) testů servisních a jiných interních rozhraní v aplikaci. Přínosem určitě bylo to, že mi testy drží strukturu aplikace pohromadě, ale velkou nevýhodou byla ztráta flexibility - kdykoliv jsem provedl nějaký refaktoring, tak jsem musel měnit i tyto testy. Testy se musí měnit vždy s ohledem na změny produkčního kódu, ale v oblasti rozhraní se mění a přidává celkem hodně a dle mého názoru výhody nepřevažují nevýhody.

Speciální kapitolou je testování GUI. Již jsem se na toto téma jednou rozepsal, kde jsem porovnával nástroje pro unit testy GUI. Bohužel je dost často rychlejší tedy levnější nechat GUI testy provést manuálně, než testy vytvořit a testovat automaticky. Většina si hned asi v duchu řekne, že je to možná levnější během vývoje, ale z pohledu nasazení, údržby a podpory aplikace to už neplatí. Toto je asi pravda, ale těžko se to prosazuje v průběhu vývoje. Úplně nejlepší je zapojit do testování zákazníka. Snažíme se vyvíjet iteračním způsobem a vždy na konci každé iterace dáme hotovou část aplikace zákazníkovi, který to následně připomínkuje.

Mě by hodně zajímalo, zda můj pohled na věc odráží realitu současného vývoje aplikací nebo zda jsem mimo. Znám spoustu firem resp. kolegů, kteří ještě nenapsali ani čárku testovacího kódu, ale na druhé straně znám i firmy, kde se na testování klade velký důraz. Já bych sám rád testoval určitě více než doposud, ale ekonomické tlaky od obchodníků, projekt managerů a vedoucích mi to moc nedovolují.

17. dubna 2008

Porovnání webových frameworků

Včera jsem zkouknul zajímavou prezentaci, kde se autor snaží na základě svých zkušeností a z pohledu různých kritérií porovnat Java webové frameworky (JSF, Spring MVC, Stripes, Struts 2, Tapestry, Wicket).
Pokud si chce člověk udělat takový první názor a nechce si všechny ty frameworky zkoušet, tak mi ta prezentace přijde super.

15. dubna 2008

Výhody a nevýhody EJB

Dost často kolem sebe slyším při rozhovorech o vhodných technologiích pro určitý projekt, že použijeme EJB, tím se nedá nic zkazit. Je to prověřená technologie, je to dostatečně enterprise, je to standard, takže vlastně nejsou žádné důvody, proč to nepoužít.
Já si myslím, že těch nevýhod může být celkem hodně. V tomto článku bych rád některé nevýhody prezentoval:

  • Testovatelnost aplikace - pokud chci testovat EJB, tak potřebuji EJB kontejner. Sice existuje pěkná knihovna Jakarta Cactus, ale přeci jen to není tak přímočaré, jako když mám POJO. Nebo mohu použít Embedded EJB kontejner, popis zde.

  • Přenositelnost - myslím, že každý ocení, když někde vyvine aplikaci, kterou pak může nasadit na libovolný server tak jak je, bez nějaké další potřeby konfigurace aplikačního serveru. Obecně se dá říci, že kolečko develop-test-deploy je rychlejší u lightweight řešení než u řešení s EJB.

  • Rychlost spouštění - jakýkoliv server, který obsahuje něco více než čistý webový Java kontejner se mi bude spouštět pomaleji. A během vývoje takový server pouštím opravdu často. Ano, nepoužívané služby si mohu vypnout, ale pak je otázka, proč potřebuji plný J2EE server. Proto se mi moc líbí myšlenka profilů ve specifikaci J2EE 6.

  • Náklady na EJB server - samotný EJB server se sehnat nedá (nebo dá?) a pokud je tedy EJB (přesněji řečeno EJB kontejner) potřeba, člověk musí sáhnout po J2EE serveru. Jedna věc jsou náklady na pořízení serveru, druhá věc jsou náklady spojené s instalací a školením pro práci s J2EE serverem. Přeci jen vše je složitější než Tomcat :).


Některé nevýhody jsou více či méně významné, nutné je také brát velký posun od EJB 2.1 k EJB 3.0 (nevýhod EJB 2.1 je o dost více, ale ty zde neuvádím). Nechci, aby tento článek vyzněl, že nemám rád EJB, to není vůbec pravda. Já se jen snažím říci, že EJB ano, ale jen pro ten typ aplikací, kde je to opravdu potřeba, protože EJB je "heavyweight" technologie, což sebou přináší určité nevýhody. Typický příklad - pro webovou CRUD aplikaci nad jednou databází bych EJB nepoužíval.

Kromě nevýhod má řešení s EJB i spoustu výhod:
  • EJB je řešení pro distribuované aplikace, tj. aplikační logika nebo aplikační komponenty jsou umístěny na více serverech (nemyslím cluster) nebo aplikace má několik typů klientů včetně tlustého klienta.

  • EJB zjednodušuje psaní vícevláknových aplikací

  • EJB nabízí transakční kontejner, který umožňuje efektivní řešení transakcí přes více datových zdrojů

  • pokud je distribuovaná EJB aplikace dobře napsaná, tak lze docílit větší robustnosti a škálovatelnosti aplikace než když aplikace bude bez EJB umístěná na jednom serveru.


Výhod je tedy hodně, ale potřebuji nebo ocením toto vše pro mojí aplikaci? Pokud ne, tak EJB nepotřebuji a mohu využít výhod lightweight aplikací.

14. dubna 2008

Konkurenční přístup k datům - zamykací mechanismy, díl čtvrtý

Dnes bych rád popsal pesimistické offline zamykání. Tento poslední díl mého mini-seriálu o zamykacích mechanismech navazuje na předchozí tři díly (1, 2, 3).

Důvody, proč někdy nestačí online zamykací mechanismy jsem popsal v minulém díle, nyní se budu tedy hned věnovat samotnému pesimistickému zamykání.

Pesimistické offline zamykání

Tento typ zamykání se nám hodí zejména v takových případech užití, kde pravděpodobnost "střetu" je velká nebo následky velké. Jen pro úplnost dodávám, že se jedná o offline zamykání, protože jinak bychom mohli použít Pesimistické online zamykání.

Tento typ zamykání je řešen na aplikační úrovni aplikace a před jeho realizací je nutné si zodpovědět následující otázky:
  • Co je potřeba zamykat? Objekt, mapu objektů nebo bude stačit jen určitý atribut objektu? Může se hodit např. tento přístup od Martina Fowlera.

  • Kdy se data budou zamykat a odemykat?

  • Jaký typ zámku použiji? Použiji zámek pouze na zápis dat nebo i pro jejich čtení?

  • Jak budu identifikovat vlastníka zámku? Bude to HTTP Session ID nebo uživatelské ID nebo něco jiného?

  • Jak budu udržovat zámky? Bude mi stačit interní paměť nebo budu potřebovat databázi.

  • Jak budu uvolňovat zámky? Mám na mysli standardní případy, kdy někdo bude mít zamknutá data a odejde na oběd. Má se zámek po určité době automaticky uvolnit, dovolíme jiným uživatelům tento zámek získat?


Těch otázek není málo a od jejich odpovědí se odvyjí implementace. Znám dvě:
  • Centrální zamykací systém (lock manager). Tento způsob používám, protože se mi líbí, že je to neinvazivní způsob (nemusím měnit objekty, pouze kde potřebuji přidám LockManager), je to centralizované řešení a dle potřeby mohu zvolit implementace uložení zámků - paměť vs. databáze.

  • Ukládání zámků přímo v objektech. Ty objekty, které potřebuji zamykat vybavím speciálními atributy, abych poznal, že daný objekt je nebo není zamknutý.



Pozn.: Většinu informací, které jsem v této sérii článků prezentoval, jsem našel v knížce POJO in Facade.

6. dubna 2008

Konkurenční přístup k datům - zamykací mechanismy, díl třetí

Jak jsem již zmiňoval v předchozím díle, dnes bych se věnoval tzv. offline zamykacím mechanismům. Offline zamykací mechanismy přicházejí v úvahu, když nemůžeme využít online (předchozí) mechanismy, tj. hlavně když

  • jedna transakce by běžela příliš dlouho
  • realizace případu užití se skládá z více transakcí

Optimistické offline zamykání

Pokud bych to měl stručně vyjádřit, tak myšlenka a implementace je velice podobná jako u optimistického zamykání z prvního dílu, jen s tím rozdílem, že zde se nepohybujeme pouze v rámci jedné transakce.

Příklad:
  • Transakce A1 načte objednávku a uloží číslo verze (nebo jinou informaci, podle které je možné rozlišit různé verze objektu) do session.
  • Transakce B1 načte a zruší objednávku, což způsobí změnu verze
  • Transakce A2 se pokusí změnit objednávku. Protože se změnil stav objednávky resp. se změnila verze, tak změna neprojde.

Implementace: jak již bylo naznačeno, optimistické zamykání funguje na principu porovnání stavu objektu po načtení a před úpravou. Toho lze docílit buď evidencí verze, časového razítka nebo přímo porovnáním hodnot. Offline porovnání má ještě to specifikum, že je potřeba informaci o verzi uchovat přes více transakcí. Vhodné úložiště je uživatelská session.

Pro optimistické offline zamykání se nabízí ještě jedna možnost implementace - přes detašované objekty. Načtu objekt z databáze a uložím detašovanou verzi objektu někde bokem, např. v uživatelské session. Uživatel provede operaci, hodnoty detašovaného objektu se nám změní. Aplikace se pokusí převést tento objekt znovu do persistentního stavu a zde nám ORM nástroj dá sám vědět, zda pracujeme pořád nad stejnou verzí objektu nebo ne.
Výhodou tohoto řešení je, že aplikace sama nemusí řešit porovnávání různých verzí objektů, to za nás udělá ORM knihovna. Také se zde neomezujeme pouze na jeden objekt, ale můžeme takto porovnat celý graf objektů.

Použití: vhodné pro takové případy užití, kde se pracuje s daty přes více transakcí, kde je malá pravděpodobnost konkurenčního přístupu nebo tolik nevadí návrat zpět po neúspěšném pokusu změny dat. Také se tento typ zamykání hodí pro ty případy, kde máme problémy se zajištěním vymazání zámku (viz dále pesimistické offline zamykání).

Popis s diagramem tohoto patternu lze nalézt na stránkách Martina Fowlera.

Myslel jsem, že ten můj miniseriál již dnes ukončím, ale bude ještě jeden díl - Pesimistické offline zamykání.

1. dubna 2008

JSF a Spring - postup o krok dále

Velice mě zaujala prezentace o možnostech integrace JSF a Springu, hlavně tzv. Spring-centric JSF Integration Approach.

Uvedu jen základní informace (vše ostatní je v prezentaci):
JSF plugs into Spring as a View implementation
• Integrates with Spring MVC and Web Flow
• FacesServlet is not used

Spring is used
• As the managed bean provider
• As the request dispatcher
• As the navigation handler
• As the state manager
• As a lightweight JSF component library

Mimo jiné mě také zaujalo toto - "The ability to inject the result of an EL expression evaluation into a managed bean" - to by mělo být dostupné ve Springu 3.0.

Pro mě jako Springaře je to dobrá zpráva, protože na mě kolegové pořád tlačí s JSF a Seamem a takhle budu mít zase o něco lepší alternativu k jejich návrhům.

31. března 2008

Vytvářet nejdříve WSDL nebo Java rozhraní?

Mé zkušenosti s vytvářením webových služeb resp. WSDL (viz např. minulý článek) mě dovedly ke zjištění, že vždy raději nejdříve navrhnout WSDL a poté si nechat vygenerovat Java kód (WSDL First Development) než opačně - napsat Java rozhraní, přidat anotace a vygenerovat WSDL (Java First Development).

Píši vždy, ale myslím tím vždy, když budu mít možnost si službu sám navrhnout (zejména pro nové projekty) a příjemcem služby bude jiný systém než můj. Již více nebudu navrhovat WSDL pomocí Java rozhraní a anotací, protože s tím mám špatné zkušenosti:

  • Zatím se mi nikdy nepodařilo vytvořit pomocí anotací takové WSDL, které bych si představoval. Vždy jsem musel vzít nějaké kompromisní řešení. Většinu lze ovlivnit pomocí JAX-WS anotací, ale pokud potřebuji jít dále (například vyladit mapování jednotlivých objektů), tak už to není zcela jednoduché a přijde mi to spíše komplikované. Dosud mám zkušenost s XFire a Apache CXF.

  • Webové služby většinou používám při integraci s jinými systémy převážně systémy od jiných dodavatelů. Svým způsobem je pěkná podoba WSDL mojí vizitkou. Nemluvě pak o tom, že mohou být problémy při vytváření klientů v jiných jazycích než je Java. Ano, ono to vždy půjde, ale jak moc sližitě?

  • Když se mi generuje WSDL z kódu, tak se mi lehce může stát, že něco změním a hned se mi změní WSDL (a ani si to nemusím uvědomit). Pokud budu mít nejdříve WSDL, tak toto se mi stát nemůže.

Samozřejmě vytváření WSDL z Javy se pořád hodí - já osobně vidím hlavní oblast použití pro případ komunikace mezi dvěma systémy (nebo v rámci jednoho systému), kde mám pod kontrolou klienta i server. Zde je mi tak nějak jedno, jak to WSDL vlastně vypadá. Ideální jsou v tomto ohledu možnosti Springu - Remoting and web services using Spring.
Pokud budu mít klienta i server pod kontrolou na stejné platformě, tak pak je ale otázka, proč používat webové služby a nepoužít něco rychlejšího, např. RMI, Hessian, Burlab... Přeci jen webové služby moc výkonné nejsou.

Může se také stát, že již budu mít nějaký historický systém a bude potřeba zpřístupnit určitou funkcionalitu přes webové služby - zde asi také bude vhodné jen přidat anotace, přidat konfiguraci a bude hotovo.

Apache CXF vs. Codehaus XFire

Minulý rok jsem na jednom malém projektíku použil XFire pro zpřístupnění určité funkcionality přes webové služby.

Minulý týden jsem opět potřeboval dát dohromady pro účely demo aplikace nějakou webovou službu a chtěl jsem tedy znovu použít XFire, protože jsem nechtěl nic vymýšlet. Ale hned při zobrazení úvodní stránky projektu XFire se mi zobrazila tato hláška:

XFire is now CXF - User's looking to use XFire on a new project, should use CXF instead. CXF is a continuation of the XFire project and is considered XFire 2.0. ...

Nedalo mi to, abych tedy nevyzkoušel Apache CXF, protože se to někdy v budoucnu může hodit.

Bohužel mě to moc (zatím) nenadchlo, určitě také kvůli tomu, že vše ještě není úplně dotažené jak má být:
  • Kdy píšou, že je to vlastně XFire 2.0, tak bych očekával nějakou návaznost, možnost migrace na vyšší verze. Potřeboval jsem převést popis webové služby (JAX-WS APIs, specifický binding objektů pomocí Aegis), konfiguraci webové služby (nastavení serveru) a testy.
    Migrace JAX-WS byla bez problémů, což je určitě tím, že se jedná o JSR 224 specifikaci a Apache CXF nabízí v současné době plnou implementaci. Aegis je i v Apache CXF, takže zde také nebyl problém.
    Konfigurace je nyní úplně jiná, takže tato část se musí přepsat. Ale je k dispozici celkem rozumná migrační dokumentace, takže s tímto jsem problém neměl.
    Bohužel testy se mi nepodařilo zmigrovat vůbec a o co hůře, ani se mi žádné testy nepodařilo napsat! Určitě je to také tím, že jsem k tomu našel minimum dokumentace. Pomocí XFire se psaly testy parádně.

  • S dokumentací budu pokračovat - jsem asi "rozmazlený" Springem, kde vždy najdu to co potřebuji. Tady prostě ne - základní dokumentace je dle mého názoru nedostatečná a JavaDoc mi přijde hodně slabý. Zkoušel jsem si i nějaké kusy kódu uvedené na webu a i když jsem je překopíroval, tak mi to hlásilo chyby, musel jsem něco dopisovat... Tohle je prostě slabina.

  • Každý, kdo dělá s Javou je zvyklý, že když nastane výjimka, tak se vypíše celý průběh volání. Tady to vše Apache CXF "nějak" chytá a ve výsledku to jen vypíše chybovou hlášku bez nějakých dalších informací.

  • Ani nevím, zda Apache CXF vznikl až po XFire nebo oba projekty spolu běží souběžně, každopádně bych si troufl odhadnout, že hlavní důvod přechodu na Apache CXF bude architektura aplikace. Apache CXF je zcela postaven nad Springem, má naprosto modulární architekturu, takže není žádný problém "cokoliv" změnit, upravit. Ale když k tomu není pořádná dokumentace, tak pak architektura může být sebelepší...

Hrál jsem si s Apache CXF jeden den, takže moc toho vyzkoumat zase nešlo a na něco jsem určitě nepřišel. Budu rád za vaše postřehy.

24. března 2008

Konkurenční přístup k datům - zamykací mechanismy, díl druhý

V předchozím díle jsem popisoval optimistické zamykání na datové úrovni, v tomto díle popíšu pesimistické zamykání a také zmíním další možný způsob řešení konkurenčního přístupu k datům - plně izolované transakce.

Pesimistické zamykání

Tento způsob zamykání již předem počítá s tím, že bude docházet ke konkurenčním přístupům k datům, a proto si každá transakce zamkne svá data a nepustí je dokud data nebudou úspěšně změněna nebo pokud se neprovede roll-back transakce. Tím je zaručeno, že data během transakce nikdo jiný nezmění, a že se aktualizace vždy povede. Také je zaručena konzistence čtených dat v rámci jedné transakce.

Pesimistické zamykání na úrovni dat je řešeno přímo databázovými stroji, např. Oracle používá SELECT FOR UPDATE.

Výhody: není potřeba měnit datový model, zaručuje konzistentní data pro čtení, zaručuje, že jiná transakce nezmění zamknutá data, lepší než izolované transakce - menší nároky na zajištění konzistence dat, menší pravděpodobnost dead-locku.

Nevýhody: všechny potencionálně konfliktní transakce musejí používat stejný přístup nad danou datovou jednotkou, výrazně snížena výkonnost, při častém použití se zvyšuje pravděpodobnost deadlocku (jedna transakce čeká na druhou až uvolní svá data), použití SELECT FOR UPDATE má svá určitá omezení, ne všechny perzistentní Java ORM nástroje tento přístup umožňují, omezená použitelnost cache.

Použití: vhodné pro aplikace, kde je potřeba mít zaručenou konzistentnost čtených dat, kde nemáme možnost použít jiný typ zamykání.


Plně izolované transakce

Pokud budeme používat transakce, které jsou od sebe vzájemně izolovány pak databázový stroj zaručí, že výsledek spuštění více transakcí v jeden moment bude stejný, jako kdyby se jednotlivé transakce spustily postupně za sebou. Bohužel tímto přístupem velice trpí výkonnost a škálovatelnost databázového stroje.
Pro řadu případů je možné použít slabší úrovně izolace - REPEATABLE READ nebo READ COMMITTED.

Výhody a nevýhody jsou zřejmé - jednoduché na použití, zabraňuje většině problémů s konkurenčním přístupem k datům, ale za cenu big overhead.

Použití bude tam, kde ztráta výkonnosti je akceptovatelná nebo tam, kde je naprosto podstatná konzistence čtených dat.


Já osobně preferují mezi ORM nástroji Hibernate, proto ještě uvádím odkaz na možnosti vymezení transakcí resp. řešení konkurenčního přístupu v tomto nástroji.

V příštím a posledním díle se budu věnovat offline zamykacím mechanismům.