2013. június 9., vasárnap

PMD - Bevezetés a kódellenőrző plugin fejlesztéshez

Hibák tömkelegét találhatjuk meg a dynaTrace segítségével, de ha valamilyen minőségbiztosítási folyamat révén nem ellenőrizzük le ezeket, az egyszer már kigyomlált problémák idővel megint vissza fognak kerülni a rendszerbe. Emiatt szoktam javasolni a korábban már megtalált hibák és az ügyfelek környezetében néha több 100 oldalon lefektetett fejlesztési és keretrendszer használati szabálysértések automatizált kijelzését. Erre egy remek eszköz lesz a Sonar, kiegészítve a saját fejlesztésű PMD ill. FindBugs alapú kódellenőrző szabályokkal.

A PMD egy olyan statikus forráskód ellenőrző eszköz, amivel megtalálhatjuk a Java fejlesztők által leggyakrabban "elkövetett" kódolási hibákat. Tipikusan ilyen hibák a kivételkezelésnél üresen hagyott catch ágak, objektumok összehasonlítása az == operátorral vagy a for ciklusban történő String-ek összefűzése a StringBuilder.append() használata helyett. A PMD alapértelmezésként közel 250 szabályt tartalmaz, de támogatja a saját szabályokkal való bővítést is XPath és Java alapú kiterjesztésekkel.

A PMD-vel történő analizálás során, először is a JavaCC beolvassa az Extended Backus-Naur Form által definiált nyelvtan és legenerálja azt a parszert, ami alkalmas lesz a java nyelvű források felolvasásához, majd a JJTree add-on segítségével felépíti az adott forráskódhoz tartozó absztrakt szintaxis fát (AST). A forráskód struktúrájának olyan faszerű reprezentációja az AST, ahol az egyes csomópontok az adott nyelv egy-egy konstrukciójának felelnek meg (pl.: WhileStatement, Block, ClassOrInterfaceDefinition, stb…).

A felépített fát pedig azért nevezzük absztraktnak, mivel a forráskódnak csak a releváns részeit tartalmazza,  a java szintakszisának megfelelő magas szintű leírással. Miután a PMD felépítette a forráskód alapján az AST-t, megkezdi a csomópontok bejárását és az aktivált szabályokban definiált node-okra a Visitor Design Pattern szerint meghívódnak a callback-ek. Ezek a callback-ek tipikusan a visit(ASTWhileStatement node, Object data) {…} jellegű metódusok, amelyekben a saját szabályainkat implementálhatjuk.

A működéséből eredően, a PMD-vel csak olyan kódellenőrzési szabályokat definiálhatunk, amelyek megfogalmazhatók a forráskód szintjén. Amennyiben olyan jellegű szabályokat szeretnénk készíteni, amihez a bytecode analizálása szükséges (pl.: Hibás cast-olás kijelzése) a FindBugs kódelemzőt kell felhasználni. Mivel a Sonar platform a PMD 4.3-as verziójával kompatibilis, ezért azokat a kódellenőrző plugin-okat amelyeket a Sonar-ba is beakarunk kötni, a 4.3-as PMD verzióval kell elkészíteni. A plugin fejlesztés során a leghasznosabb eszközünk a PMD Rule Designer lesz, ami legenerálja a minta forráskód AST-jét valamint az XPath alapú PMD szabályok elkészítéséhez is segítséget nyújt.

Nézzük meg ezt a gyakorlatban is!

Indítsuk el a PMD Rule Designer-t a pmd-bin-4.3.zip bin/designer.bat paranccsal és a Source code ablakba illesszünk be egy minta kódot, majd a go gombra kattintva megjelenik az Abstract Syntax Tree ablakban a felépített AST. Ha az XPath Query ablakban megadunk egy XPath kifejezést is, akkor a jobb alsó ablakban megjelennek az XPath kifejezésre illeszkedő csomópontok és azok forráskódbeli helye is.


A fenti ábrán jól látható, hogy a java forráskódbeli kifejezések hogyan felelnek meg az AST egy-egy csomópontjának. Az AST csomópontok és a forráskód részek megfeleltetéséhez hasznos feature, hogyha az AST-n kiválasztunk egy node-ot, akkor az ehhez tartozó forráskód blokk is kijelölésre kerül. Sőt, ha az XPath találati lista elemeire kattintunk, a megfelelő forráskód blokkok is kijelölődnek!

A folytatás hamarosan következik...