GeeCON 2010 - Den druhý

Po včerejší after párty se mi dneska skutečně nechtělo příliš vstávat. Niméně diskuse s Hansem Dockterem (autorem Gradle) skutečně stála za to. Hans je skutečně mimořádný člověk se skvělými názory - přidávám další bodík pro Gradle. Styl, jakým se Gradle vyvíjí a filozofie, která za ním stojí, se mi skutečně zamlouvá. U dikuse byl také Vašek Pech z JetBrains, který má na svém kontě také samostatný OS projekt GPars, takže se diskuse odvíjela i na téma zkušeností s vedením OS projektu, respektive firmy, která je živa z konzultací a školení spojených s daným OS projektem. Tyhle chvilky jsou zkrátka na konferencích asi to nejlepší - dostat se do kontaktu s výjimečnými lidmi a mít možnost s nimi mluvit tváří v tvář. Jsem opravdu rád, že tyhle "výlety" na konference jsou ve Forrestu možné, protože to zdaleka není samozřejmost.

V rámci druhého dne se odehrála celá řada velmi zajímavých přednášek, které bych rád trošku nastínil v dnešním příspěvku.

Easing JPA DAO development with Hades / Oliver Gierke

Tato přednáška byla pro mne asi tím nejzajímavějším z dnešního dne. Oliver Gierke rozebíral projekt Hades, který umožňuje automatické generování DAO interfaců. Přednáška byla tím zajímavější, že podobnou věc (vlastní implementaci postavenou nad JdbcTemplate) u nás už cirka 3/4 roku používáme.

Hades je nadstavba JPA využívající ke svému běhu Spring Framework. Myšlenka pochází ze světa dynamických jazyků (GORM například), kdy programátor pouze volá (v případě plain Javy deklaruje signatury metod) DAO metody, jejichž implementace nikde neexistuje, ale je systémem automaticky generována na základě nějakých pravidel.

Cílem je samozřejmě maximalizovat produktivitu - řada metod na DAO vrstvě je prostě velmi jednoduchá a jejich implementace je repetitivní. Programátor se takto může soustředit jen na ty složitější a repetitivní práci přenechat generátoru. V našem prostředí mohu po 9 měsících směle prohlásit, že tento přístup se už osvědčil a skutečně je zvýšení produktivity jasně cítit.

Na tohle téma bych chtěl letos mluvit na JOpenspace konferenci, a teď mám konečně pro účastníky konference i odkaz na OS projekt, na kterém si životaschopnost tohoto přístupu mohou okamžitě vyzkoušet.

JDK 7 Update / Dalibor Topic

V této přednášce Dalibor topic rozebíral novinky v JDK7. Bohužel se člověk, který si udržuje jen základní přehled o dění v Java světě, v přednášce moc nového nedozvěděl. Bylo to jen taková průřezová rekapitulace toho, co se do JDK7 dostane. Ani datum vydání JDK nebylo zpřesněno - pouze, že má vyjít v letošním roce.

Zajímavé bylo shrnutí toho, co se musí udělat při každé změně specky Javy:

  • aktualizovat vlastní specifikaci jazyka
  • implementovat potřebná rozšíření / úpravy v kompilátoru
  • upravit existující knihovny, tak aby využívaly této novinky
  • implementovat sadu testů, prověřující danou funkcionalitu
  • upravit specifikaci VM
  • aktualizovat VM a nástroje pro práci s class soubory
  • aktualizovat Reflection API
  • implementovat podporu v Serializaci
  • aktualizovat výstup do JavaDocu

To jsou všechno věci, které si vývojář, který Javu pouze používá a nevyvíjí, moc neuvědomuje.

Squeezing Java Performance: When you need a little more / Thomas Enebo

Thomas Enebo je jedním z lidí pracujících na vývoji JRuby. Svoji přednášku uvedl prohlášením, že JRuby je v současné době 2x až 2,5x rychlejší jak originální distribuce psaná v Céčku - to je jistě věc pozoruhodná a stojí za zamyšlení ;-) .

Zajímavá pro mě byla informace o tom, jak HotSpot pracuje - jednak, že optimalizaci provádí iterativně - vždy provede jen jeden optimalizační krok v čase, následně sleduje, jestli daný krok vedl k navýšení výkonu či ne. Pokud ne, vrátí tuto optimalizaci zpět a pokusí se provést něco jiného, pokud optimalizace vedla k navýšení výkonu, HotSpot zkusí na zoptimalizovaném kódu provádět další optimalizace.

Další zajímavá věc je ta, že HotSpot vám nezoptimalizuje rozsáhlé metody. Čím více menších metod, tím lepší práci vám HotSpot provede. Základním optimalizačním mechanismem je tzv. inlining, kdy se konkrétní kód v externí metodě přímo vloží do metody druhé na místo, kde je použito volání. HotSpot má však zabudované omezení, které zamezí inlinování metod, které mají více jak 35 bytecode instrukcí. Taktéž se při inlinování zastaví na hloubce 9 vnořených volání.

Non-thread safe třídy HotSpot optimalizuje lépe - tj. nezamykejte, pokud to skutečně nepotřebujete. ConcurrentHashMap nemá jeden zámek na celou mapu, ale má několik menších zámků pro konkrétní oblasti. Immutabilita může úplně odstranit práci se zámky a tudíž zvýšit výkon. Autoboxing a varargs zpomalují, zkuste zvážit overloadované metody, pokud třeba danou metodu s varargy voláte často s jedním, dvěma parametry apod.

Základní pravidlo, které nám Thomas Enebo kladl na srdce, je pokud možno výkonnostní optimalizaci neprovádět. A pokud přeci musíme, tak ji provádět na základě smysluplných měření. Smysluplné měření by mělo probíhat na kompletní aplikaci (ne na nějakém prototypu - malé aplikace zoptimalizuje HotSpot jinak než velké), na cílovém HW (JVM na různých platformám může běžet řádově jinak), a mělo by se z měření odečítat úvodní sekvence, ve které se program "zahřívá" (tj. při které HotSpot optimalizuje kód za běhu). Taktéž by se měly pokud možno minimalizovat IO operace, pokud se netestují právě ony.

Ideálně neoptimalizujte dřív, než je aplikace hotová, protože:

  • můžete pracně optimalizovat část, která nakonec bude fungovat jinak a nebo se i odstraní
  • optimalizací obvykle kód velmi znepřehledníte a díky tomu s ním bude obtížná práce a bude problém jej udržovat

První věcí na, na kterou byste se měli zaměřit nejsou jednotlivosti v dané aplikaci, ale celková architektura a evidentní nedomyšlenosti (jako příklad uváděl společnost, která si je pozvala na optimalizaci JRuby kódu, protože prý běžel pomalu, aby se po chvíli zjistilo, že při zobrazení každé stránky parsují 250kB XML pro to, aby mohli zobrazit jméno a příjmení přihlášeného uživatele). Jako jednu z prvních věcí se také zkuste podívat na vlastní nastavení Javy - např. přechodem z Javy 1.5 na 1.6 u JRuby dosáhnete cirka 20% zrychlení. Také správné nastavení GC na různých HW konfiguracích může hrát značnou roli.

Přednáška byla zajímavá, i když vlastní přednes byl takový univerzitní - přistihl jsem pár kolegů, kteří si u této přednášky dávali po včerejším kulečníkovém turnaji šlofíka ;-) .

Game Programming with Groovy / James Williams

James Williams ukazoval použití Groovy pro programování jednoduchých 2D her. Na ukázkách dokazoval, že Java je pro tyto účely dostatečně rychlá. Na přednášce provedl rychlý vhled do knihoven JavaMonkeyEngine, Lightweight java Graphics Library (LWJGL), JOGL, JOAL, JInput, Tilemaps, Slick a zmínil DarkStar Project.

Snažil se ukázat podporu bluetooth, na demu s WiiMote ovladačem pomocí knihovny Motej, která by měla podporovat i další zařízení jako např. Nunchuk, Balance Board a klasické ovladače. Což se nakonec bohužel nepodařilo (generálský efekt, který určitě znají všichni, kdo někdy prezentovali).

Pro mě se jednalo o aajímavý náhled do světa her. Čekal jsem něco ve formě existujících DSL jazyků postavené nad Groovy, nicméně přednáška v tomhle byla poměrně skoupá.

Static analysis using JSR308 annotations / Adam Warski

Adam Warski ukazoval jak by se v praxi měla chovat validace pomocí JSR308 anotací. Bylo velmi zajímavé vidět anotace na typech, generikách, polích a dokonce i v přetypování:


@NoNull String s;
Map<String, @NotNull String> map;
class MyClass extends <@NotNull String> {}

a vlastní rozšíření validačních anotací díky specifikaci Bean validation:


Map<@Email String> emails;

Bohužel prozatím tuto podporu nemohl ukázat v IDE, takže celá přednáška probíhala přes spouštění JavaC z příkazové řádky s ruční konfigurací anotačních processorů. Pro většinu přítomných asi zatím těžko zkousnutelná věc, ale s podporou v IDE v tom vidím zajímavou možnost, jak vylepšit statickou analýzu správného použití cizího API.

HTML5 Web Sockets: All-You-Can-Eat Real Time! / Peter Lubbers

WebSockets jsou novinkou ve specifikaci HTML5 a měly by se stát plnohodnotnou náhradou současných ajaxových volání serveru. Zkraje přednášky Peter rozebral všechny základní v současnosti používané principy AJAXového volání a jejich nevýhody:

  • Polling - časté dotazy na server, často s nulovým výsledkem (žádná změna na serveru není) - velmi drahé na režii volání
  • Long polling - odpověď serveru se neuzavře do doby než je k dispozici nějaká nová informace na serveru - neefektivní, pokud na serveru často vznikají nové zprávy / stavy
  • Comet - streaming, odpověď se nikdy neukončí - problematické pokud jsou na cestě nějaké staré proxy servery nebo firewally, které vyžadují ukončení odpovědi serveru

WebSockety fungují na bázi standardního HTTP protokolu (tj. přes porty 80 a 443). Pokud klient i server tuto techniku podporují, dohodnou se na tzv. "upgradu" protokolu a začnou spolu komunikovat přes WebSocket. To je kanál, který se nikdy neuzavře a komunikace po něm probíhá oboustranně. Data, která se po něm přenášejí jsou textového charakteru (ale ten lze upravit i pro přenos binárního obsahu). Na klientovi dokážeme podporu WebSocketů identifikovat pomocí jednoduchého konstruktu:


if (window.WebSocket) {
   ...
}

A v současnosti jej podporuje Chrome 4, Safari (v night buildech), Opera a Firefox na něm pracují a měli by ho podporovat do konce tohoto roku a náš poslední utlačovaný IE jej bude podporovat až někdy ve verzi 10. WebSocket nebude trpět crossdomain problémem - tj. jak jsem pochopil, mělo by být možné z klienta vytvořit několik WebSocketů na servery na jiných doménách.

Vše se neobešlo bez řádné reklamy na Kaazing WebSocket Server, který by měl již implementovat práci s WebSockety s emulací této podpory i pro starší prohlížeče typu IE6. Pravda je, že tento komerční produkt je velmi vymakaný a při reálných ukázkách toho, co se dá přes WebSockety provádět nám trošku klesala čelist. Pro Apache by se měl vyvíjet pywebsocket, který by měl tuto podporu zajistit snad pro širší publikum.

JSR-299 Context and Dependency Injection / Mark Struberg

V poslední přednášce nám Mark Struberg popisoval konkrétní implementační detaily JSR-299 na téma Context and Dependency Injection. V rychlosti řečeno, většina věcí člověka, který používá Spring v kombinaci s anotacemi neměla překvapit. Valnou část této specky podle mého názoru Spring integroval již ve verzi 2.5.X.

Pravda je, že když Mark ukázal kombinace jednotlivých anotací, s možností (nutností) vytvářet další anotace vlastní, začal kód vypadat poměrně hodně magicky. Celá specifikace mě na první pohled připadala velmi komplikovaná (jaký je český výraz pro "overengeneered"?) a v případě, že by některé z různých kombinací anotací přestaly funguvat asi by člověk dost těžko zjišťoval, kde konkrétní vendor implementující specku udělal chybu (respektive pokud je chyba u mě, ta v čem spočívá). Celkové propojení bean na základě anotací prostě vypadalo až příliš magicky.

Co mi ovšem přišlo jako zásadní problém je to, že CDI funguje na základě classpath scanningu. Tj. automaticky při startu aplikace vyhledá všechny JARy obsahující v META-INF soubor beans.xml a v těch se snaži najít libovolné třídy obsahující ty správné anotace. Pro prohledání classpat nahodí jeden velký kontext se všemi beanami podle pravidel definovaných jejich anotacemi. V tomto ohledu se obávám dvou věcí: a) nikdy nebudu vědět, jestli s nějakým přilinkovaným JARem se mi do kontextu nezamíchá něco co nechci b) (a to i v souvislosti s předchozím bodem) jestli mi někde nedojde nějakému name clashingu.

V době kdy je modularita jedním ze žhavých témat, mělo být toto (myslím si) rozhodně vzato v úvahu.

Závěrem

GeeCON je rozhodně konference, na kterou se vyplatí jet. Poměr cena / výkon je u této konference skutečně velmi příjemná. Organizačně to kluci zvládli na jedničku a vůbec se mi zdálo, že v Polsku je to pro nás Čechy takové velmi přívětivé a domácké. Na několika místech, kde nefungovala angličtina, jsme to dokonce zvládli s češtinou.

Jsem rád, že jsem tu mohl strávit nějaký čas a vracím se plný dojmů a nových inspirací. Takže díky pánové z Polského JUGu a díky Forreste.