2010. augusztus 28., szombat

Servlet 3.0 első kör

Nagyon érdekelt a servlet 3.0 és közismerten türelmetlen tipus vagyok, letéptem hát a legfrissebb specifikációt és kipróbáltam rajta pár dolgot. A kipróbált implementációk:
  • Jetty 8
  • glassfish 3.0
  • tomcat 7
Hát eléggé fej-fej mellett voltak, úgy tünt kb mind ugyanaddig jutott el. A kisérletsorozatnak nem sikerült kizökkentenie a jetty-pártiságomból. Továbbra is a jetty volt a fejlesztés során a legkönyebben használható. A 8-as verzióhoz is van maven plugin. Pedig próbálgattam a glassfish 3 embedded pluginjét, igazából pozitív meglepetés volt, de hot deployt nem csinált. Szóval minden eltévedésem után újra kellett startolni és packagelni. A tomcat 7.0 az meg maradt a maga kis bemásolom és újraindítom megoldással. Magad uram ha integrációd nincsen.

Servlet annotációk

Iiiigen... aki velem dolgozik, az tudja mennyire nem komállom azt, hogy mindent annotálunk. Az XML HELL sem volt jó, de most elmentünk egy még rosszabb irányba. XML konfigurációkkal még megvolt az esélye annak, hogy áttekinthető marad. Mindenesetre gyors prototype alkalmazásokat az ember biztosan szivesebben tol össze úgy, hogy csak ráannotál a szervletére. Működött is mindenhol.

Azt soha nem értettem egyébként hogy a servlet ikonja az mi akart lenni. Valami ősi dolog lehet a Delphis és Progress-es időkből.

Opcionális búcsú a web.xml-től

Hát igen, ha nincs benne semmi érdekes, akkor le is törölhetjük és a dolog megy nélküle is. Persze ha már egy adatbázis kapcsolat kellene a la JNDI (ami végülis egy hasznos dolog), akkor vissza is jön egyből. Oké, szóval marad, adatbázisa kb mindenkinek van és az operátorok akarják babrálni. (Vajon miért pont azt az egy resource-ot? Az összes többivel miért nem foglalkoznak?)

Asynchron servlet support

Ez talán a legűberebb dolog mióta gyáva programózó vagyok, de az utóbbi 5 évben biztosan a legfontosabb dolog számomra. Nagyon egyszerő, ez történik: amikor úgy véled, hogy sokáig tartó művelet közeledik (pl vársz egy JMS üzenetre) egyszerűen azt mondod, hogy ez a request innentől asszinkron fog kiszolgálódni. Így:
req.startAsync();
Ezután elkérheted a requesthez tartozó AsyncContext ojjektumot

AsyncContext asyncContext = req.getAsyncContext();
Ezt akár bedobhatod egy másik szál által kezelt listába, ahol a lassú műveletre váró összes többi kliens várakozik. Az az egy szál le fogja tudni kezelni minden requestedet. Például valahogy így

asyncContext.getResponse().getWriter().write("gedappa!\n");
Eddig csúcs :) Na akkor most jön a gubanc. Azt is biztosan szeretnénk tudni, hogy mikor kellene ezt a AsyncContext objektumot kidobnunk a listából. Erre tök jó lett volna az AsyncListener osztály. Ami meg is van, kiválló. Példányosul is szépen az implementáció, még mindig oké, de aztán NoSuchMethodError amikor regisztrálni próbáltam, mind a 3 servlet containerben. Ez vagy valami kis lemaradás a specifikációhoz képest, vagy valami szokásos sünös-orákulumos gányolmány.

Elfelejtettem azzal kezdeni, hogy ennek mi értelme van. Talán már kiderült a fentiekből: megszabadulunk az millió kiszolgáló száltól, maradnak csak simán a TCP kapcsolatok. A NIO után végre a következő lépés.

Pár dolgot biztosan érdemes a async kedvéért átgondolni az üzemeltetésben is: például sokan használnak apache httpd-t a servlet container elött, mert példul még php és perl meg egyéb ingyombingyomokat is ezzel a szerverrel hajtanak. A httpd régebben single process per connection cucc volt, most már lehet külön szálakat is használni, de vicces hogy ott álnak majd a szálak, amig a java VM-ben megoldottuk hogy ne kelljen állniuk. Nekem nagyon gyanús, hogy ilyen esetekben sokkal érdemesebb lesz kihozni a servlet containert a httpd mögül. (és persze van, aki azt kérdezi: mit keresett ott addig, ha csak a java elött állt? kiválló kérdés...)

Hát ennyit akartam elmondani már jórég óta, csak mindig belémfolytották a szót. Egyébként komolyan gondolom, hogy ezt a lépést a java világ legnagyobb előrelépésének tartom az utóbbi 4-5 évre. Mondjuk nem kis lépés, de azért szivesen látnék nagyobb lépéseket is.