Zobrazují se příspěvky se štítkemOstatní. Zobrazit všechny příspěvky
Zobrazují se příspěvky se štítkemOstatní. Zobrazit všechny příspěvky

1. března 2013

Programátorské firmy v Plzni

Tento článek vznikl díky diskuzi, kde si jeden z přítomných povzdychl, že v Plzni žádné velké příležitosti pro programátora nejsou, a proto že musí pracovat v Praze.

Je pravda, že Brno, ani Praha to není, ale i tak těch programátorských příležitostí v Plzni není málo. Proto jsem vytvořil následující seznam firem, které jsou přímo Plzeňské nebo mají sídlo jinde, ale v Plzni mají pobočku. Hlavním kritériem je, že to musí být firma (tj. one-man show se nepočítá), a že firma se musí (i třeba jen částečně) věnovat vývoji software. Bohužel nemám natolik detailní informace pro všechny firmy, abych mohl tvrdit, že firmy, které mají v Plzni pobočku, zde skutečně vyvíjejí, zda to třeba není jen obchodní zastoupení. 
Seznam vznikl na základě mých znalostí, informací z internetu a od kamarádů. Budu rád, pokud se v komentářích objeví další firmy, protože již během psaní jsem si jistý, že nějaké další firmy v Plzni máme, jen o nich bohužel nevím.

Seznam je řazen abecedně:

Mimo hlavní seznam bych ještě uvedl BIC Plzeň, což je takový podnikatelský technologický inkubátor, kde určitě sídlí zajímavé firmy, ale bohužel jsem nikde nenašel jejich seznam.
  

9. ledna 2011

Generování PCL do souboru

Tento článek dnes píši z trochu jiných důvodů než jindy - rád bych si shrnul mé dosavadní znalosti v této oblasti a také bych vás rád požádal o radu, protože s touto problematikou nemám moc zkušeností.

PCL je formát používaný při tisku tiskárnami. Většinou se s tímto formátem člověk přímo nepotká, protože když někdo chce něco vytisknout, tak použije nějaký vhodný ovladač ke konkrétní tiskárně, ten PCL vygeneruje a pošle rovnou na tiskárnu k tisku.

Já mám k řešení trochu jiný problém. Moje aplikace tvoří část tiskového řešení, které je postavené na tom, že firma má po celém světě různé sklady a kanceláře, kde má síťové tiskárny. A podle určitých pravidel přijde nějaký dokument, ze kterého je potřeba vygenerovat PCL a poslat dle konfigurace na cílovou tiskárnu. Tiskárny jsou to většinou HP (řekl bych tak z 90%), sem tam se objeví i jiná značka, např. Xerox. Přenos souboru na tiskárnu je přes FTP.

Nemohu tedy využít konkrétní ovladače pro konkrétní tiskárny, musím vygenerovat nějaký obecný PCL soubor a ten tam poslat. Pokud se jedná čistě o textový soubor, tak ten se vytiskne bez potřeby generování PCL, ale ne všechny dokumenty jsou jen čistý text, někde jsou i obrázky.

PCL formát má řadu podformátů - 5e, 5c, 6. Ideální je (asi) verze PCL6, protože již dnes většina tiskáren podporuje tuto verzi a do budoucna bude rozšíření ještě větší. Navíc jednotlivé verze nejsou zpětně kompatibilní (někde se píše, že jsou zpětně kompatibilní a někde, že zase ne, ale spíše věřím tomu, že nejsou).

Další obecné požadavky na aplikaci - cílové OS je Linux (Redhat Enterprise) a velký důraz je kladen na rychlost, robustnost a škálovatelnost aplikace. Výsledný soubor k tisku musí být co nejmenší, řádově desítky kB.

Java Print Service

Java má celkem flexibilní API pro tisk - Java Print Service. Použití je přímočaré (ukázka generování z GIFu do PS) a v dokumentaci mezi podporovanými formáty PCL je, jenže při bližším zkoumání zjistíte, že PCL je podporováno jen na rozhraní a ne implementačně - "The StreamPrintService from JDK 6 does only support PS...".

Nenašel jsem žádnou knihovnu třetí strany, která by toto implementovala.

Apache FOP

Když se člověk poprvé při řešení tohoto problému porozhlédne po internetu, tak jako první většinou najde Apache FOP, který umí převádět data do PCL.

Bohužel podpora PCL v Apache FOP není dokonalá a má spoustu nevýhod:
  • celkem složité na implementaci, navíc těžko říci, zda to bude také rychlé. Je potřeba různě generovat XML, pak je transformovat atd. Určitě nic extra rychlého.
  • umí jen PCL5 a podpora PCL6 asi ani nebude.
  • neumí UTF-8 (Multibyte characters are not supported)
  • přehled dalších omezení

FO procesorů je více (zde je přehled), ale žádný jiný neumí PCL a nebo nejsou vhodné k použití s Javou.

Command-line a tiskové nástroje

Při hledání možného řešení jsem i prohledal všechny možné tiskové a konverzní nástroje, bohužel bez přímé podpory pro PCL.
I kdybych našel vhodný nástroj pro konverzi do PCL, tak zde vidím spoustu dalších nevýhod: nejsou to úplně levná řešení, pomalé a nevýkonné řešení, problém s integrací do naší aplikace, kód a další vývoj produktu nemám pod kontrolou.

Generování přes drivery

Při nějakém dalším zkoumání mě napadlo využít nějaký obecný driver pro tiskárnu, tj. poslat dokument k tisku na vhodný driver, ale místo na tiskárnu, tak výstup uložit do souboru.

Našel jsem "HP Universal Print Driver", ale ten je pouze pro Windows, já potřebuji Linux.

Pro Linux mě zaujal projekt Gutenprint a obecný driver Generic PCL 6/PCL XL Printer.

Podle mých slabých znalostí v této oblasti mám dvě možnosti - použiji program ghostscript a vygeneruji PCL z PS. Ghostscript by měl být součástí distribuce. Druhou variatnou je vyrobit virtuální tiskárnu, která se tváří jako PS tiskárna a interně použije ghostscript jako filtr na výrobu konkrétního tiskového formátu.

Chybí mi v této oblasti znalosti, jak by se to vůbec dalo na Linuxu zrealizovat, nicméně mám pocit, že tato cesta je celkem reálná, a že by mohla fungovat.

Něco jiného než PCL?

Když se podíváte na podporované formáty u lepších (=síťových) tiskáren, tak často jsou ještě vidět dva další formáty - PDF a Postscript.

PDF musím hned vynechat, protože podpora není nic moc - v mém vzorku cca 20 řad tiskáren (nemyslím konkrétní modely, ale celé řady tiskáren, např. HP LaserJet P4015 Printer series) je podpora u cca 50% a to je málo.

Pak se nabízí Postscript, podpora asi u 85% tiskáren. Generování do PS je přímočaré, protože to umí přímo Java Print Service ve standardní Javě. Jedinou nevýhodou, kromě slabší podpory u tiskáren než má PCL, je výsledná velikost souboru a nároky na systémové prostředky při generování. Z mých testů vyplynulo, že pro naše typové dokumenty je velikost PS 3x větší než PCL. Hned je ale potřeba dodat, že výsledné velikosti PS byly okolo 10kB, takže minimální.
"PS used to come at a price - it use to be the case that you had to pay extra money to get PS but now its fairly standard on many printers and indeed some HP printers will even print PDF directly. PS is generally considered more resource hungry - it requires more memory and is slower than PCL5/PCL6.
PS output files are usually larger than those generated for PCL5/PCL6 because it is plain ASCII, you can actually read it ; BUT communication times (between computer and printer) used to be slower."

Generování do PS již naše aplikace umí a zdá se, že vše běhá celkem rychle. Bohužel business požadavek je od začátku PCL.

Další informace:


Budu moc rád, pokud mi někdo poradíte a posunete mě dál. Já osobně nyní nejvíce věřím řešení přes drivery v OS.

24. května 2010

Kdo nemá twitter, není správný programátor

"Kdo nemá twitter, není správný programátor" - takový pocit jsem získal v poslední době, když pozoruji své kolegy v práci nebo lidi v Java komunitě. Pokud nemáš twitter, tak jsi out :). Je to samozřejmě přehnané, ale když se podívám na českou Java komunitu, tak je opravdu hodně lidí, kteří Twitter používají.

Nepřidávám se snad ani kvůli tomu, že chci být in, ale hlavně z toho důvodu, že to chci zkusit. Chci zkusit zjistit, zda je tato forma komunikace pro mě přínosem, chci tímto způsobem získat nové zajímavé informace, chci tímto způsobem i já sám s trochou přispět a upozornit na zajímavé články nebo myšlenky. Určitě ale nechci psát o mém soukromí, o tom, co právě dělám a o tom jak se mám. Rád bych, aby se vše týkalo vývoje a Javy.

Nevím, zda je to jen můj pohled, ale přijde mi, že v poslední době (cca půl roku zpátky) se nepíší blogy tak jako dříve. Těžko říci, čím to je - již není o čem psát? Jsou už blogeři unavení nebo mají již něco jiného na práci? Nahrazuje twitter klasické blogování? Myslím si, že asi od všeho něco. Já bych každopádně ještě nějaký čas rád psal, protože pořád cítím, že mi to více dává než kolik tomu dávám já.

Pokud mě tedy chcete následovat, pak mám účet pjuza.

11. srpna 2009

VMware získal SpringSource

Dnes ráno jsem v mé RSS čtečce našel celkem (aspoň pro mě) překvapivou zprávu - společnost VMware získala společnost SpringSource.

Více o této akvizici lze dočíst na blogu Roda Johnsona nebo na blogu Steve Herroda (VMware CTO) a nebo si přečíst oficiální PR vyjádření.

Podle informací z těchto článků se SpringSource stane novou divizí Vmwaru, kterou bude i nadále vést Rod Johnson. Rod Johnson ubezpečuje, že se nic měnit nebude, že model fungování firmy, produktová řada, investice do open-source zůstanou beze změny. Je jasné, že hned na začátku nikdo nebude tvrdit, že se to celé změní, ale jak znám společnost VMware, tak mi to dává naději, že opravdu vše zůstane jako dříve a z mého pohledu (z pohledu vývojáře, který rád používá Spring produkty) se nic nezmění.

11. června 2009

Rozcestník knihoven

Na intranet jsem psal takový rozcestník odkazů na různé knihovny a třídy, který by měl posloužit k tomu, aby se programátoři nejdříve podívali, zda to co potřebují řešit, není již náhodou někde (lépe) vyřešeno. Myslím, že tento rozcestník se může hodit i někomu z vás.

Následující rozcestník slouží k rychlé navigaci, pokud potřebujete pracovat s určitými datovými typy nebo provést nějaké obecné operace:

  • řetězce (String) -> StringUtils, StringEscapeUtils, StrTokenizer nebo WordUtils z Commons Lang.
    • kontrola na prázdné řetězce, hledání a náhrada znaků (řetězců) v řetězci, mazání částí řetězce, převod na malá/velká písmena, dělení řetězce na části, mazání mezer a doplňování řetězců, kontrola na čísla, alfa znaky apod., otáčení řetězců, porovnání řetězců,
    • práce s escape znaky pro Java, Java Script, HTML, XML, and SQL
    • dělení řetězce, práce s částmi řetězců
    • práce se slovy v řetězci

  • datumy (Date) -> DateUtils
    • posun datumů, zaokrouhlování, získání určité složky z datumu

  • čísla (Number) -> NumberUtils
    • převod řetězců na čísla, min. a max. hodnoty, porovnání desetinných čísel

  • boolean -> BooleanUtils
    • převod řetězců na boolean, převod čísel na boolean a obráceně

  • pole (Array) -> ArrayUtils
    • přidávání, mazání, hledání prvků v polích, vytváření pod-polí, převod na pole primitiv

  • kolekce (Collection) -> ListUtils, MapUtils nebo SetUtils z Commons - Collections
    • množinové operace s kolekcemi

  • equals() a hash() -> EqualsBuilder a HashCodeBuilder
  • toString() -> ToStringBuilder
  • soubory, adresáře (File) -> FileUtils nebo FilenameUtils z Commons IO
    • vytváření, mazání souborů a adresářů, čtení a zápis dat, kopírování souborů a adresářů, porovnání obsahu souborů
    • práce se jménem souborů a celou cestou k souboru

  • streamy (InputStream, OutputStream) -> IOUtils
    • čtení a zápis dat, kopírování mezi streamy, zavírání streamů, porovnání streamů

  • kódování (Base64, Hex, SHA, MD5, ...) -> Common Codes


Pokud hledáte snad ještě něco jiného, tak doporučuji se podívat na následující projekty:

17. března 2009

Dynamické jazyky nejsou zase tak špatné

Pokud jste v minulosti četli mé názory na dynamické jazyky, tak jste museli cítit, že je zrovna "moc nemusím". Jak to dost často bývá, člověk je omezený díky své neznalosti.

Když jsem se vždy někoho zeptal, k čemu jsou dobré dynamické jazyky, tak jsem vždy dostal hodně podobnou odpověď - DSL, tvorba GUI, customizace. Jenže můj problém byl vždy v tom, že jsem si nedokázal sám sobě říci, kde konkrétně to můžu využít - DSL jazyky obvykle nevytvářím, pro GUI používám JSP nebo JSF (a obecně s tím nemám problém) a customizace je pěkná věc, ale také jsem ji nikdy moc nepotřeboval, protože spíše pracuji na jednorázových projektech než na produktech.

Můj názor se celkem radikálně změnil poté, co jsem si přečetl články o integraci Springu a Groovy a také po vašich komentářích v mém posledním článku o dynamických jazycích.

Díky tomu se mi moc začala líbit ta myšlenka, že pomocí Javy si vytvořím kostru aplikace (pomocí rozhraní) a ty části, které se mění resp. je potřeba upravovat per instalace, tak ty můžu implementovat pomocí Groovy (a hezky měnit za běhu aplikace bez restartu serveru). Toto není nijak obecně převratná myšlenka, ale pro mě je převratná v tom, že jsem ji dokázal aplikovat na konkrétní aplikaci s konkrétními problémy. Holt někomu to trvá trochu déle... :)

29. ledna 2009

Jaké dynamické jazyky využíváte? - výsledky

Opět skončila další minianketka, tentokrát mě zajímalo využití dynamických jazyků. Zde jsou výsledky:

  1. Žádné (41%)
  2. Něco jiného (25%)
  3. Groovy (20%)
  4. Jython (12%)
  5. jRuby (2%)
  6. Scala (2%)
  7. Rhino (1%)
Hlasovalo celkem 62 lidí.

Co k tomu říci? Výsledky mě nepřekvapily, jen by mě zajímalo, jaké dynamické jazyky se skrývají pod položkou "Něco jiného". Když jsem vybíral jazyky do ankety, tak jsem vycházel z tohoto seznamu a snažil jsem se vybrat ty nejpopulárnější, ale asi se mi to moc nepodařilo.

Asi před rokem jsem o dynamických jazycích psal a od té doby se můj váhavý postoj nijak nezměnil. Pořád jsem na tom stejně - pořád nevím, kde bych je mohl sám využít, kde mi přinesou tu tíženou výhodu při vývoji aplikací oproti standardní Javě.

Asi je nebudu využívat přímo, ale přes nějaký aplikační framework jako jsou třeba Grails nebo ZK framework. Jsem hodně zvědavý s čím novým přijde Spring ve spojení s Groovy, když nedávno koupili firmu G2One, které stojí za frameworkem Grails a jazykem Groovy.

S uvedených jazyků jsem používal pouze Groovy a to ve spojení s nástrojem SoapUI. Díky Groovy jsem si mohl napsat vlastní testovací případy a to se mi líbilo.

Také jsem skeptický na větší využití dynamických jazyků s ohledem na většinu (dle mého názoru ano, na většinu) programátorů, kteří se vlastně ani nic nového učit nechtějí - naučí se Javu a pár věcí okolo a myslí si, že jim to bude stačit. Znám to - stačí abych přišel s nějakou myšlenkou využití nové knihovny (natož s použitím nějakého dynamického jazyka) a už vidím tu nutnost přemlouvání, vysvětlování apod.

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%)

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í.

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:

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í.

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.

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

Každý asi ví, že konkurenční přístup k datům je nutné řešit, ať už na datové nebo aplikační úrovni. Mám ovšem tu zkušenost, že většina kolegů tento problém řeší až v době implementace případu užití, což si myslím, že už je trochu pozdě. Přístup k datům resp. zvolený zamykací mechanismus ovlivňuje návrh samotné aplikace (datový model nebo aplikaci samotnou) a proto by způsob přístupu k datům měl být vyjasněn již v době analýzy a zohledněn v návrhu aplikace.
Rád bych tedy v sérii několika článků zmínil základní způsoby řešení konkurenčního přístupu k datům - ať už na úrovni datové nebo aplikační.

Optimistické zamykání

Navzdory svému jménu vlastně o žádné zamykání nejde. Transakce přistupují k datům bez nějakého omezení, pouze při updatu se ověřuje, zda data nebyla v průběhu transakce změněna jinou transakcí od doby, kdy se data načetla. V případě kolize je nutné transakcí vrátit (roll-back).
Kontrola změny dat se může řešit pomocí:
  • evidence verze. Pro tuto variantu je nutné přidat nový speciální sloupec do tabulky pro evidenci verze. Při každé změně hodnoty se zvýší verze a pak je jednoduché zjistit, zda došlo ke změně nebo nikoliv.

  • evidence času poslední změny. Víceméně totožné jako předchozí varianta, ale místo verze se eviduje timestamp poslední změny.

  • porovnání nové a původní hodnoty. Velké výhoda tohoto přístupu je ta, že není nutné přidávat žádný sloupec, tedy vhodné pro systémy, kde nemůžeme provádět úpravy v datovém modelu.

Většina ORM nástrojů minimálně jeden z uvedených způsobů podporuje a je pouze otázkou konfigurace, jaká implementace se použije.

Výhody: snadná implementace, nenáročná kontrola změny dat a roll-back pouze v případě konfliktu

Nevýhody: všechny konkurentní transakce (myšleno nad jednou datovou jednotkou, např. tabulkou) musejí používat optimistické zamykání, není vždy možné provádět změny v datovém modelu a tedy přidávat nové sloupce (není možné vždy použít třetí variantu ověřování, např. problémy s null hodnotami, desetinná čísla), není zaručena konzistence čtených dat.

Použití: vhodné pro aplikace, kde máme datový model pod kontrolou, kde nám moc nevadí nekonzistentnost dat při čtení a hlavně tam, kde nám nevadí, když se aktualizace dat neprovede. Pokud budu v UI mít složitý formulář nebo průvodce přes několik obrazovek, tak pak bych optimistické zamykání určitě nepoužil, protože uživatel by asi nebyl moc šťastný, když by si po několika minutách vkládání dat do formulářů přečetl hlášku, že data nelze uložit.

V příštím díle se zmíním o pesimistickém zamykání a dalších možnostech řešení konkurenčního přístupu k datům.

16. ledna 2008

Bezpečnostní problémy webových aplikací

Již před pár lety naše firma vytvořila aplikaci pro administraci LDAP adresáře jedné nejmenované pojišťovny. Nyní si pojišťovna nechala udělat bezpečnostní audit - nejen na naší aplikaci, ale obecně na celé své řešení spojené s adresářovými službami.
Některé připomínky mě více či méně překvapily, posuďte sami (jen pro přesnost musím uvést, že s většinou uvedených problémů naše aplikace neměla problémy):

  • problém jménem Cross-site scripting (2) (XSS). Tento způsob podvržení není asi dobré podceňovat, protože možnosti útoků jsou skoro nekonečné. Jako vhodné řešení (poměr námaha vs. úspěšnost) se mi jeví převádět všechny podezřelé položky (takže vlastně všechny) na HTML entity. Zde nestačí pouze kontrolovat resp. převádět položky zadané uživatelem, ale ideálně i položky z LDAPu nebo databáze.

  • CRLF injection, SQL injection

  • správa sessions - po každém přihlášení by se měla zrušit stávající session (která byla vytvořena v moment přístupu k aplikaci) a vytvořit nová session. Po odhlášení vždy session zneplatnit.

  • ošetření chybových stavů - chybová hlášení by neměla být natolik detailní, aby z nich bylo možné vyčíst údaje vhodné pro další typy útoků. Např. neuvádět detailní popis služby, která spadla, neuvádět jména a verze komponent, kde nastal problém apod.

  • slabá hesla - auditor zkoušel namátkou odhadnout hesla uživatelů a zjistil, že 364 uživatelů má heslo "12345678", 12 uživatelů pak "87654321"!

25. prosince 2007

Co (mi) přinesl letošní rok?

Je závěr roku a kdekdo se snaží shrnout, co se NEJ stalo v tomto roce. Já budu také jeden z nich, ale můj pohled bude malinkato jiný - rád bych uvedl věci, které mě jako programátora resp. architekta tento rok nejvíce pomohli v mé každodenní práci. Nebude to přehled nějakých významných objevů či událostí, které se v tomto roce ve světě Javy staly, ale spíše věci, které mi pomohly a pomáhají lépe a rychleji vytvářet aplikace, nebo které mě nějakým způsobem v mé práci ovlivnily.

Rozšiřování Spring portfólia

Já mám rád Spring, já ho rád používám a jsem plně ztotožněn s filosofií, která stála u zrodu Springu, a která platí až doposud. Proto tak oceňuji, že Spring resp. Spring portfólio se rozšiřuje o nové projekty, že čím dále více projektů třetích stran nabízí přímou a snadnou Spring-integraci, že Spring používá čím dál více lidí a tím pádem se objevuje více informací na internetu a více příspěvků v diskuzích.

Zvýšení povědomí o Springu

Tento bod velice souvisí s předchozím bodem, ale je o trochu něčem jiném. Je o tom, že Spring již dneska není považován za nějaký dočasný open-source projektík, ale za vyspělé propracované řešení, které se nebojí využívat ani velcí hráči jako jsou banky, pojišťovny, vládní instituce apod. To je v konečném důsledku super hlavně pro nás vývojáře, že můžeme jít s dobou a nemusíme pořád i dnes vyvíjet v prostředí Javy 1.3 nebo Struts.

Vyspělejší prezentační technologie

Myslím si, že Java oproti jiným jazykům (hlavně C#) nejvíce ztrácí v efektivitě vytváření "ksichtu" aplikací. Je sice hezké mít super robustní jádro aplikace, ale pokud uživatel neuvidí pěknou, moderní, uživatelsky přívětivou aplikaci, tak moc spokojený nebude. Proto jsem rád, že vznikl Seam, který ukázal v tomto ohledu zajímavý způsob řešení, že nastal posun v JSF specifikaci, že vzniká čím dál více použitelných AJAXových frameworků.

J2EE 6

Dle článků na internetu se dá tušit, že specifikace J2EE verze 6 se vyvíjí tím správným směrem. Uvidíme, jak to nakonec ale dopadne - jaké dílčí specifikace budou součástí finální J2EE specifikace, jak moc se podaří prosadit lidem okolo Springu jejich představy.

Nedostatek pracovních sil

Sice tento bod přímo nesouvisí s tím, jak každý den řeším programátorské problémy, ale nepřímo to celkem mojí práci ovlivňuje. Na jedné straně tím, že se nemusím bát o svoji práci, že si mohu vybírat a částečně určovat podmínky já sám. Na druhé straně jako nevýhodu vidím v tom, že máme problémy sehnat nové kolegy (schválně jsem vynechal slovíčko kvalitní, protože to je dneska spíše nedostižný ideál) a tedy spoustu věcí třeba ani řešit nemůžeme.

21. prosince 2007

Skriptovací jazyky v Javě - co s nimi?

Tento článek jsem nezačal psát jako jiné články s tím, že bych rád něco sdělil, ale spíše, že bych se rád něco dozvěděl. Před chvílí jsem dočetl článek o skriptovacích jazycích v Javě a pořád si nějak nemohu správně odpovědět na otázku - K čemu mi jsou v Javě ty skriptovací jazyky vlastně dobrý?

Musím se přiznat, že obecně skriptovací jazyky neovládám a spíše jen pasivně sleduji dění okolo, něco hodně málo jsem napsal v Groovy. Když si čtu články o skriptovacích jazycích v Javě, tak se často objevují tyto výhody vzájemného propojení:

  • skriptovací jazyky jsou jednodušší, lehčí, názornější, intuitivnější. To je z velké části dáno tím, že se jedná většinou o jazyky dynamické a slabě typované (obecně řečeno, protože např. Python je typově silný jazyk).

  • Java nabízí celou řadu věcí, které nejsou dostupné v samostatných skriptovacích jazycích, např. transakční management nebo vzdálená volání. Kromě toho lze pomocí Javy využít obrovské množství knihoven třetích stran, které lze ve skriptech využít.

  • výběr skriptovacích jazyků pro Javu je dneska opravdu veliký

  • díky spojení s Javou se neztrácejí hlavní přednosti Javy - možnost vytváření velkých, robustních a škálovatelných aplikací.


Kromě výhod to má samozřejmě i nějaké nevýhody:
  • často se uvádí slabší výkonnost skriptovacího enginu s JVM oproti nativnímu enginu samotnému. Je to dáno tím, že je potřeba provádět řadu kontrol a konverzí mezi oběma světy. Toto např. neplatí úplně pro Groovy, což je jen taková jiná Java.

  • skripty napsané s pomocí JVM samozřejmě pak nelze spouštět v nativním enginu

  • někdy jsou světy Javy a skriptovacího jazyka natolik rozdílné, že to nelze v některých jazycích vůbec implementovat nebo za cenu ne úplně ideálního kódu. Myslím například anotace v Javě.

  • větší nároky spojené s údržbou aplikací. Dříve stačilo umět jen Javu, ale teď k tomu potřebuji znát ještě minimálně další jazyk.

  • podpora přímo na úrovni JVM od verze 6 - JSR 223


Takže k čemu já to jen využiji? I když si dokážu představit, že určité části aplikace napíši rychleji např. pomocí Groovy, tak jsem asi moc konzervativní, ale mě to zase taková výhoda nepřijde. Já mám svoji Javu rád :), takže si všechno napíšu v ní. Když to nebudu brát jen z mého osobního pohledu, tak přeci jen otázka údržby aplikace je hodně významná a s použitím více jazyků a technologií se tento problém stává těžší a komplikovanější (a tedy nákladnější). A když už budu psát část aplikace pomocí skriptovacích jazyků, tak proč už to pak nenapíšu celé jen pomocí skriptovacího jazyka?

Často se uvádí jako vhodné využití prototypování aplikací. Zde si to dovedu celkem představit jako přínosné, ale moje zkušenost mi říká, že spousta takto vytvořených prototypů se použije pro následný vývoj celé aplikace. Raději bych to tedy od začátku psal pořádně v Javě.

Můj osobní stav je nyní takový, že pořád moc nevím, kde a jak bych mohl efektivně využít skriptovací jazyky z pohledu vývoje v Javě. Budu moc rád, když přispějete formou diskuse a vysvětlíte mi, že se v určitých ohledech pletu nebo jsem jen špatně resp. málo informovaný.