Blog

Blog from August, 2007

A Hibernate mítosz

Terjeng egy mítosz a Hibernate HQL nyelvének "sebezhetetlenségéről"... vagyis az SQL injection elleni védettségéről. Pedig a HQL ugyanúgy sebezhető, mint az SQL: ha rosszul használjuk. Nézzünk miképp is néz ki ez:

String goodParameter = "Raj lane";
Query badQuery = session.createQuery("from Address a where a.street='" + goodParameter + "'");

Látszik, hogy a paramétert hozzáfűzzük mezei szövegművelettel, amely lehetőséget ad a HQL injection elvégzésére:

String badParameter = "la' or '1'='1";
Query reallyBadQuery = session.createQuery("from Address a where a.street='" + badParameter + "'");

Eredményül nem az utcára szűkítést kapjuk, hanem a tábla teljes tartalmát, mivel a feltételhez odakerült egy '1'='1', mégpedig VAGY kapcsolatban a többi feltétellel. Az HQL injection ellen a paraméterek átadásával tudunk védekezni:

String badParameter = "la' or '1'='1";
Query reallyBadQuery = session.createQuery("from Address a where a.street=:street");
reallyBadQuery.setParameter("street", badParameter);

Így a trükk semmit nem ér... :)

A DevX portálon a népszerű MythBusters sorozathoz híven körüljárták a több magból álló gépek teljesítményét, illetve teljesítményproblémáit. Első körben körüljárják az "Alkalmazásom lassú, de megmenti Moore törvénye" című mítoszt, amelyet sok fejlesztő használ mentségképp. Moore törvénye nagyjából azt mondja ki, hogy másfél évente megduplázódik az elektronikai berendezések sebessége. A fejlesztők pedig erősen támaszkodtak erre a folyamatra: egy három év alatt kifejlesztett programot úgy tervezhették meg, hogy a jelenleginél négyszer gyorsabb rendszeren fog futni, s erre igen sok példát találunk a játékfejlesztők háza táján, ahol gyakran túltervezik a játékok hardverigényét. Sajnos Moore törvénye irányt váltott, a gyártók nem tudnak könnyedén frekvenciát növelni, egy-két évvel ezelőtt megjelentek a többmagos processzorok, amelyek pont azonos órajelen dolgoztak, mint a tavalyi széria, csak több mag figyelt a lapkán... és az egy szálra megírt programunk csúfosan lassú lesz.

Gyakori kijelentés, hogy "Az Application Server majd skálázza a programom", amely szintén egy mítosz, s a Java Enterprise kiadása óta makacsul tartja magát a fejlesztők körében. Azonban az alkalmazás szerver csak akkor képes megfelelően skálázni a programunkat, ha azt úgy írjuk meg. Ha nem a célnak megfelelően írjuk meg, akkor egy olyan programokból álló halmazt kapunk, amelyek egymás lábába harapva próbálnak szóhoz jutni: az értékes processzoridőt pedig üzenetek továbbítására és lock-ok feloldására váró szálak közötti váltásra pazaroljuk.

Ha az AS mégse válna be, akkor a fejlesztők előkapják a cilinderből "A cluster majd megoldja a problémát" felíratú nyulat... sokszor hiába. A processzorok számát növelve az egyes processzorok hasznos teljesítménye jelentősen csökkenhet. A csökkenés mértékét Amdahl törvénye írja le, a mellékelt ábra szerint, aholis a szekvenciálisan (más szóval egy atomi műveletként) végrehajtott kód aránya szerint jelentősen romolhat a cluster teljesítménye. Már 1% ilyen kód esetén is 100 processzornál 50 processzor felesleges.

Ha a fejlesztők főnöke is ismeri a fenti tényeket, akkor a fejlesztők még mindig mondhatják, hogy "A párhuzamos rendszerekre nehéz fejleszteni", dehát ez is mítosz. Egyszerűen csak ismerni kell pár fogalmat (deadlock starvation, stb)... és minden szépen a helyére kerül. :)

A TheScreenCast szerverére felkerült egy oktatóvideó, amely a GWT telepítését és rövidre fogott használatát mutatja be. A két részből álló videó első része a GWT letöltését, telepítését, illetve a projektek szerkezetét hordozza; a második részben pedig egy saját alkalmazás (FirstApp) elkészítését követhetjük lépésről-lépésre.

Thomas Einwaller elmélkedett a hatos Java újdonságairól, amelyekkel meg tudjuk találni a Java alkalmazásunk memóriazabáló részeit. Persze most mindenki felhördül, hogy a Java hogy lehet memóriazabáló... amikor ott az automatikus szemétgyűjtő. Ha nem törődünk az példányainkkal megfelelő gondossággal, akkor előfordulhat, hogy a memóriában maradnak, mert van még rájuk referencia (akár körkörös is lehet!). Ezernyi módja van a Java programunk étvágyának... és alig van néhány módszerünk a hiba megkeresésére. Első lépésként futtatnunk kell a jmap parancsot, amelynek megadjuk a futó JVM PID számát, illetve pár egyéb paramétert:

[javaforum@javaforum:~]$ /opt/SDK/jdk/bin/jmap -dump:live,format=b,file=javaforum.bin 13878
Dumping heap to javaforum.bin ...
Heap dump file created
[javaforum@javaforum:~]$ ls -l javaforum.bin
-rw------- 1 javaforum other 106338209 Aug  7 20:47 javaforum.bin

A program futása során egyszerűen készít egy dump-ot a JVM heap területéről, amelyben aztán a jhat program kedvére turkálhat:

[javaforum@javaforum:~]$ /opt/SDK/jdk/bin/jhat -J-mx768m javaforum.bin
Reading from javaforum.bin...
Dump file created Tue Aug 07 20:47:51 CEST 2007
Snapshot read, resolving...
Resolving 891772 objects...
Chasing references, expect 178 dots... [...]  ....
Eliminating duplicate references... [...] ...
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.

A gépen, ahol futtatjuk a jhat programot, kinyílik egy 7000-es számú port, amelyen egy egyszerű webszervert futtat a jhat, ahol végig tudjuk kattintgatni a JVM lementett állapotát, érdemes megnézni, hogy melyik osztályból mennyi példány létezik, és azokra honnan kerül hivatkozás... és még sok egyéb információt is ki tudunk bányászni az adatrengetegből.

IFoo vagy FooImpl?

Megfontolásra érdemes vita kerekedett ki a Thinking In Java blogon. A vita alapja, hogy egy elnevezési konvenció szerint az interfész osztályokat akár IFoo néven illethetjük, mint Interface Foo. A blog vitaindító cikke szerint ez egy elavult és rossz dolog (lásd még Hungarian notation). A cikkre természetesen jött egy ellenkező tartalmu válasz, amely igen éles vitát generált... ebben az első reakcióban a lényeg az, hogy ha az interfész neve Foo, és az implementáció neve FooImpl az miért rosszabb, mint az IFoo és a Foo név...

Mindenki döntse el maga... :)