2013. december 10., kedd

Firefox OS - Közös fejlesztés a Mozilla hétvégén

A hobbi Android projektemmel még csak néhány hónapja foglalkozom, de máris felkeltette az érdeklődésemet egy új platform a Firefox OS. Kíváncsi voltam a közösségre és ami mögötte van, így meglátogattam az egyik Mozillás workshop-ot. Mivel a résztvevőknek egy prototípust kellett magukkal hozni találkozóra, az androidos SonarQube alkalmazásomat portoltam át (legalábbis elkezdtem) a Firefox OS alá. Az egész napos fejlesztői találkozó néhány bevezető előadással indult, majd mindenki nekiállt a fejlesztésnek. A "hackelés" végig jó hangulatban zajlott, megtanultam pár hasznos fejlesztési fogást és persze megismerkedtem a hazai közösség tagjaival is.


A workshop-on mindenki kapott egy Geeksphone Keon készülékeket, amivel a Mozilla nem titkolt célja, hogy a fejlesztők minél több webappot készítsenek. A SonarQube alkalmazás portolását természetesen folytatom és blogolok is majd erről. Az appot pedig hamarosan publikálom a Firefox Marketplace-en.

2013. december 3., kedd

Appra magyar - Mobil alkalmazás fejlesztő verseny

A Microsoft által kezdeményezett, az Apple, az eNET, a Telekom és a Telenor által egyaránt támogatott Appra magyar! projekt a legtehetségesebb hazai mobil fejlesztők felkutatását tűzte ki célul. Az Informatikai, Távközlési és Elektronikai Vállalkozások Szövetsége (IVSZ) által indított alkalmazásfejlesztő versenyre így én is beneveztem a SonarQube Android alkalmazásomat az üzleti kategóriába. A versenyhez tartozik egy közönség díj, melyre itt egy Facebook-os like-al tudtok szavazni december 5-ig!


De ami a legfontosabb használjátok az alkalmazást bármerre is jártok... :)

http://appramagyar.hu/

2013. november 28., csütörtök

SonarQube - Android alkalmazás fejlesztés

Ahogy Kocka is megírta, nem lehetsz Rambo és Batman egyszerre. Nem fér bele az idődbe hogy mindenből profi legyél, maxiumum 1-2 dologra tudsz igazán jól fókuszálni. Ezzel én teljes mértékben egyetértek, de azért annyival kiegészíteném, hogy a fókuszt néhány évente érdemes másra áthelyezni. Ez leginkább azért fontos, hogy a munkád ne váljon egyfajta rutin feladattá és mindig új dolgokat fedezhess fel! 

Mivel mostanában sokat foglalkoztam a SonarQube kód analizáló eszközzel, azt találtam ki hogy fejlesztek hozzá egy Android alapú kliens alkalmazást. Ennek az első verziója pár hete el is készült. A forráskódot megnyitottam, ezzel csatlakoztam a SonarQube Community fejlesztőihez, így hivatalosan is ez lett a SonarQube Android-os alkalmazása. Szuper! Persze az alkalmazás még koránt sincs kész, ahogy a szabadidőm engedi folytatom a fejlesztést, a hivatalos wiki oldalra fel is raktam a tervezett jövő évi roadmap-et!


A következő bejegyzéseimben az alkalmazás fejlesztésének érdekesebb pontjairól fogok mesélni, addig pedig megosztom a fontosabb linkeket. Természetesen minden észrevételt ill. Google Play értékelést szívesen fogadok!

https://play.google.com/store/apps/details?id=hu.balazsbakai.sq

2013. október 31., csütörtök

dynaTrace - Nemcsak tűzoltásra!

A dynaTrace egy hasznos eszköz az éles környezetben felmerült teljesítménybeli és stabilitási problémák beazonosításához, de lássuk be ez nem más mint tűzoltás! Én azt javaslom, hogy ne csak akkor kezdjünk el foglalkozni a problémákkal ha már ég a ház, mert ilyenkor biztos sokkal nagyobb lesz a kárunk és a javítási költség is!


A problémákat jóval korábban, már a fejlesztés-tesztelés fázisban ki kellene mutatni, így azok gyorsan orvosolhatók! Felmerülhet a kérdés, hogy miért használjunk dynaTrace-t amikor ott vannak a már jól bevált teszteszközök? A dynaTrace-t nem a teszteszközök helyett, hanem azokkal integrálva érdemes használni! Az alapvető probléma a teszt eszközökkel, hogy azok csupán rámutatnak a sokáig tartó kérésekre ill. hibákra, de nem tudják felfedni a problémák valódi okát, mivel nem látnak bele az alkalmazásba!

A dynaTrace integrálható a legtöbb kereskedelmi és nyílt teszteszközzel, legyen az terheléses (JMeter, LoadRunner), felületi (Selenium) vagy éppen egység teszt (JUnit, TestNG). A leghatékonyabb eredményt akkor érhetjük el, amikor ezt a folyamatos integrációs környezetünkbe is beillesztjük.

A gyakorlatban ez úgy néz ki, hogy egy CI eszköz (gombnyomásra vagy ütemezve) meghajtja az alábbi lépéseket:
  1. Forráskód letöltése az SCM-ből
  2. A build eszköz lefordítja a kódot, létrejönnek a build termékek
  3. Lefuttat egy SonarQube kód analizálást
  4. Átszól egy REST-es interface-n a dynaTrace-nek, hogy kezdheti a session mentést
  5. Lefuttatja a dynaTrace-szel integrált unit teszteket
  6. Telepíti a web-alkalmazást a tesztkörnyezetbe
  7. Lefuttatja a dynaTrace-szel integrált felületi és terheléses teszteket
  8. Átszól egy REST-es interface-en a dynaTrace-nek, hogy zárja le a session mentést
Nézzük is meg, hogy mit nyertünk vele:
  • Minden egyes release-hez automatikusan létrejön egy dynaTrace session, ami tartalmazza a PurePath-okat és minden mérési eredményt a dinamikus jellemzőkről (lekérdezések ideje, kivételek száma, válaszidők, stb...)
  • Minden egyes release-hez megkapjuk a kód statikus jellemzőit (System.out.println()-ek száma, stb...)
  • Mivel a trendekből kiolvashatjuk a dinamikus (dynaTrace) és statikus (SonarQube) jellemzőket, a negatív elváltozásokat azonnal felismerhetjük
  • Tetszőleges 2 release jellemzőit is összehasonlíthatjuk

Persze a dynaTrace a fejlesztőknek is tartogat hasznos funkciókat. Az Eclipse ill. az MS Visual stúdióval történő integrációt követően, a dynaTrace-ben megjelenő metódusokra kattintva átugorhatunk a fejlesztőkörnyezetünkben lévő projekt megfelelő metódusára!

Legközelebb pedig egy teljesen új témával jelentkezem, ez pedig az An...

http://www.compuware.com/en_us/application-performance-management.html

2013. szeptember 26., csütörtök

HOUG Szakmai nap 2013 - Rendszerhangolás a hardvertől az alkalmazásig

Előadóként meghívást kaptam a HOUG 2013-as szakmai napjára, ahol a Java szekcióban a szerver oldali optimalizálásról fogok egy 30 perces előadást tartani. A rendezvény 2013. október 9-én, a Rubin Wellness & Conference Hotel-ben kerül megrendezésre. A részvétel ingyenes, csak egy rövid előzetes regisztráció szükséges.


Az előadásom tartalma:
  • A JSF működése (röviden…)
  • Terheléses tesztek készítése JSF alapú web-alkalmazásokhoz
  • Problémák a terheléses tesztekkel
  • Az alkalmazások gyenge pontjainak beazonosítása
  • Nézzük meg a gyakorlatban…
  • A performancia és stabilitási problémák megelőzése

A prezentációm pedig itt érhető el!

2013. szeptember 14., szombat

JMeter - JSF alkalmazások terheléses tesztelése 2.

Egy korábbi bejegyzésben már írtam a JMeter általános használatáról, most pedig az előző elméleti ismeretekre építve kifejezetten a JSF-es web-alkalmazások JMeter-es terheléses teszteléséről lesz szó. Kezdjünk is neki!

Először is felvettem a szükséges JMeter konfigurációs elemeket, majd a JMeter Proxy Server segítségével rögzítettem egy tesztesetet, ami két HTTP kéréses keresésből állt. Az első kérés egy HTTP GET volt amivel lekértem a /CustomerSearch/search.jsf oldalt. Ez volt a JSF terminológia szerint az initial request, amikor is a szerver oldalon felépül a JSF komponensfa. Ezután kitöltöttem keresés űrlap mezőit majd egy HTTP POST kéréssel átküldtem a szervernek az adatokat és válaszként megkaptam a keresési eredményeket. Ez a második kérés már egy JSF postback volt, amihez az űrlap rejtett mezőjébe generált JSF komponensfa azonosítója, a viewStateId is elküldésre került.

A szkriptelési feladatunk, hogy a teszt futtatásakor a viewStateId-t mindig aktualizáljuk, mivel az minden lefutáskor más értéket fog kapni!

Az első megoldás az alábbi ábrán is látható JMeter Post Processor, a Regular Expression Extractor használata lehetne, miszerint az initial kéréshez tartozó válasz forrásából kinyerjük a javax.faces.ViewState értékét, majd a JAVAX_FACES_VIEWSTATE változóba eltárolva, a postback kérésnél a ${JAVAX_FACES_VIEWSTATE} kifejezéssel passzoljuk tovább!


Ez így elsőnek jónak tűnik, de mi lehet ezzel a probléma? A tapasztalat azt mutatja, hogy a JSF-re épülő keretrendszerek néha több sorba is megtörik a viewStateId átadására használt rejtett input mezőt, pl. a következőképpen:

<input id="javax.faces.ViewState" 
name="javax.faces.ViewState" type="hidden" value="aCe2XnokY5W3qRKTuTgT12YSQ0gxrqOMV9PcIU3FrDsUykah
" />

Ez azért probléma, mivel a JMeter-es reguláris kifejezéseket nem tudunk több sorban elhelyezkedő inputra illeszteni. De akkor hogy szedjük ki a viewStateId? Aki ismeri a JMeter eszköztárát annak a válasz egyszerű, a reguláris kifejezés helyett használjuk az XPath Extractor Post Processor-t az alábbi ábra szerint.


Ezek után már tényleg nincs más dolgunk, mindössze annyi, hogy a második postback kérésnél cseréljük le a beégetett viewStateId-t, az XPath kifejezésnél megadott változóra.


A folytatásban pedig arról fogok írni, hogy milyen előnyökkel jár, ha a dynaTrace-t a szoftverfejlesztési folyamatainkba is beillesztjük, legyen szó a fejlesztői ill. teszt eszközökről vagy egy CI platformról!

2013. szeptember 3., kedd

JMeter - JSF alkalmazások terheléses tesztelése 1.

Nemrég JSF-es web-alkalmazások tesztelésével és az eredmények dynaTrace-es kiértékelésével foglalkoztam a Raiffeisen Banknál, de a Szerencsejáték Zrt-nél, a Magyar Közút-nál valamint a ShiwaForce-nál is tartottam oktatásokat mind a JMeter használatáról mind pedig a teszteszközök (Selenium, JMeter, LoadRunner, JUnit) dynaTrace-es integrációjáról. Így következő bejegyzésekben erről a témáról és a dynaTrace tesztelési folyamatokba való illesztéséről fogok írni.

Még mielőtt nekikezdenénk a JSF alapú alkalmazások teszteléséhez érdemes megérteni a JSF működését, amihez az alábbi JSF életciklus ábra lesz a segítségünkre.


A JSF esetében alapvetően kétfajta kérés létezik, az initial és a postback. Az initial request (HTTP GET) hatására a szerver oldalon létrejön a kért oldalhoz tartozó komponensfa, melynek a csomópontjai az oldalon található elemek lesznek (UIForm, UIOutput, UIInput, stb...). Az initial kérések során csak a Restore View és az Render Response fázis fog lefutni, azaz felépül a komponensfa (+ eseménykezelők, validátorok, konverterek jóváhagyásra kerülnek, majd a view elmentésre kerül a FacesContext-be) ami alapján lerendelődik a HTML oldal. Postback kérések esetén tipikusan egy form mezői kerülnek átküldésre a szerver oldalra (HTTP POST), ahol létezik már az oldalhoz tartozó komponensfa, egy korábbi initial kérés következtében. Alapesetben a postback kérések elküldésekor mind a 6 JSF fázis lefut, ahol is a komponensfa aktualizálása mellett a megfelelő lépések után a managed bean-ekbe beíródnak az értékek.

A komponensfát legtöbbször a szerveroldali webes session-ban tároljuk és az ehhez tartozó azonosítót rejtett mezőként adjuk át az oldalon. Erre azért van szükség mert a HTTP protokoll állapotmentes és az azonosítás miatt a postback kérésekkel mindig továbbítani kell az initial kéréssel létrehozott komponensfa id-ját, ami általában így néz ki:

<input id="javax.faces.ViewState" name="javax.faces.ViewState" type="hidden" value="abcdefghijklmn123456" />

Miért is kell ezeket tudnunk a teszteléshez?

Azért, mert a rögzített tesztek HTTP kéréseinél, az elküldött javax.faces.ViewState paraméterek értéke már nem lesz érvényes a teszt futtatásakor, így azokat szkriptelve mindig aktualizálni kell. A következő cikkben pedig ennek a gyakorlati módját fogom megmutatni.

2013. augusztus 12., hétfő

dynaTrace - Te még nem használod?

Ezt a cikket egy összefoglalónak szántam azoknak akik gyorsan egy átfogó képet szeretnének kapni a dynaTrace hibakeresési ill. monitorozó képességeiről és remélhetőleg a bejegyzés végére mindenkinek kiderül, hogy miért mondogatom mindig azt, hogy a dynaTrace nélkül most már soha többé nem akarok szoftvert fejleszteni! 

PurePath technológia

A PurePath technológia lehetővé teszi, hogy JAVA, .NET, PHP, C rendszereken keresztül az összes felhasználó összes kérését lekövessük a hívási láncon keresztül, akár éles környezetben is a 4% alatti overhead-nek köszönhetően (így a hibákat nem kell a teszt környezetben reprodukálni). Sőt a technológiát kliens oldalon is használhatjuk a dynaTrace AJAX Edition kiegészítővel.


Az idő információk és a hívási lánc felrajzolásán túl elkaphatjuk a metódus argumentumokat ill. visszatérési értékeket, megtekinthetjük a keletkezett kivételeket és naplóüzeneteket, elcsíphetjük az SQL lekérdezések paramétereit is.

A gyökér okok gyors meghatározása

A dynaTrace közel 30 dashletet (Response Time HotSpots, Exceptions, Browser Errors, stb...) ad ahhoz, hogy a hibák gyökér okait minél gyorsabban beazonosítsuk és ahhoz is lehetőséget nyújt hogy bármikor tovább fúrjunk egy másik dashlet felé. Példaként a baloldali dashlet a metódus HotSpot-okat mutatja a kijelölt metódus hívási lánccal együtt, a jobb oldali pedig a database HotSpot-okat a hívó féllel.


Architekturális ábra a kapcsolódó rendszerekkel

A TransactionFlow dashlet, a kiválasztott időablakra vonatkozólag megmutatja a rendszer aktuális architektúráját, az áthaladó kérések irányát, a problémás komponenseket valamint a rétegek között eltelt időket is.


A felhasználói műveletek teljes lekövetése avagy mit csinált az user

Probléma esetén a felhasználók rendszerint betelefonálnak a help desk-re, hogy ez meg az nem működik, hibával találkoztak a felületen. Ilyenkor a legelső kérdés az szokott lenni, hogy mit csinált a felhasználó, mire kattintott. Ezen információk összegyűjtése nem mindig könnyű feladat. Persze a dynaTrace-szel egyszerű a dolgunk, csak leszűrünk a felhasználó nevére és megnézzük a látogatása során végrehajtott akciókat, majd szükség szerint tovább fúrunk a PurePath-okhoz.


Monitorozás és riasztás

A dynaTrace-t sokan csak egy hibafeltáró eszköznek gondolják, de az üzemeltetés számára leginkább a monitorozó és riasztási képességek bizonyulnak a leghasznosabbnak. Az alapértelmezett dashboard-ok mellett a rendelkezésre álló measure-ökre feliratkozva akár egy adott metódus vagy lekérdezés válaszidejét esetleg hívásszámát is monitorozhatunk. Ha a monitorozott metódus válaszideje meghaladna egy határt (riasztás), automatikusan készíthetünk heap és thread dump-ot valamint a problémás időszakhoz tartozó PurePath-okat session-ként is exportálhatjuk, amit egy harmadik félnek átadva már képes lesz analizálni a gyökér okokat.

Üzleti tranzakciók kialakítása

A PurePath-ok szűrésével és csoportosításával az üzlet számára fontos jellemzőket is vizualizálhatjuk. Az alábbi ábrán például a bevételek alakulását (metódus paramétereket elfogva és összeadva) követhetjük utazási irodánként ill. úticél szerint csoportosítva. Egy másik példaként az egyik nagy légitársaságnál tartott piloton, a felhasználói élményt (válaszidők és a hibák száma szerint számolva) kellett monitorozni a különböző platformról jövő felhasználok szerint csoportosítva, ahol is jól látszott hogy az Android 2.x-et használó felhasználóknál nagyobb az elégedetlenség és a visszafordulás aránya.


A legújabb technológiák folyamatos támogatása

A dynaTrace legújabb kiadásával az új alkalmazás szerver verziók mellett a Cloud, BigData és Mobil technológiák is támogatást élveznek, csak néhányat megemlítve: IIS8, JBoss AS 7, Glassfish 3.1, WebSphere AS 8.5, Weblogic 12, Cassandra, Mongo DB, HBase, Hadoop 2.x, Solr.


Gyors telepíthetőség és beüzemelés

Az agent alapú technológiának köszönhetően a telepítéshez a forráskódot NEM kell módosítani, pl. Java esetén csak egy JVM argumentumot kell beilleszteni az alkalmazást futtató szerverhez. A kollektorok és a dynaTrace szerver elindítása után, minden további konfigurációt egy Eclipse alapú vastag kliens alkalmazáson keresztül végezhetünk el.

Már 2 éve a piacvezető APM megoldás

A Gartner elemzése szerint 2011-ben és 2012-ben is a Compuware dynaTrace volt a vezető APM megoldás, amihez hozzájön, hogy a Fortune 500-ból jelenleg 386 a Compuware ügyfele.


És ez még csak a kezdet, a dynaTrace-t nemcsak az éles hibák felkutatásához és monitorozásához használhatjuk, de a fejlesztői és a tesztkörnyezetben is nagy segítségünkre lehet, mivel már a fejlesztés korai szakaszában kimutathatjuk az esetleges problémákat, amivel elkerülhető az éles környezetbe való kijutásuk.

2013. augusztus 3., szombat

Goldenblog 2013 - Szavazz a Seamplex-re!

Ebben az évben is beneveztem a GoldenBlog versenyre, mégpedig a Biznisz kategóriába! A szavazás augusztus 1-től egészen augusztus 21-ig tart, szavazni pedig a Facebook-os hozzáféréssel lehet a jobb oldali "szavazz" gombra kattintva. A díjazás az előző évhez képest annyiban módosult, hogy a közönség díj (a legtöbb szavazatot összegyűjtőnek) és a szakmai zsűri díj mellett különdíjak is lesznek.

Ha tetszik a blogom és hasznosnak találtad az írásaimat szavazz a Seamplex-re!


2013. július 15., hétfő

PMD - XPath alapú kódellenőrző plugin fejlesztés 2.

Még mindig az XPath alapú plugin fejlesztésnél maradunk, de most egy kicsit összetettebb példát fogok bemutatni.

Explicit (forráskódbeli) GC hívások kijelzése 


A kódból nem javasolt a szemétgyűjtés kikényszerítése, mivel ilyenkor mindig teljes GC-zés történik, azaz a fiatal és öreg heap területeken is megtörténik a takarítás, ami akár hosszabb időre is megállítja az alkalmazás futását. Bár a -DisableExplicitGC JVM argumentummal letiltható az explicit gc használata, a kódbeli hívás tiltása mégis javasolt a "véletlenül kifelejtett" beállítások miatt!

A szabály elkészítéséhez először is kigyűjtöttem a GC forráskódból történő meghívásainak az eseteit:

1. Runtime.getRuntime().gc();
2. Runtime rt=Runtime.getRuntime(); rt.gc();
3. java.lang.Runtime.getRuntime().gc();
4. Java.lang.Runtime rt=java.lang.Runtime.getRuntime(); rt.gc();
5. System.gc();
6. java.lang.System.gc();
7. Runtime és System statikus importja, getRuntime().gc(); ill gc(); meghívása.

Az egyszerűség kedvéért az alábbi szabály most csak az 1. és a 2. esetet fedi le, azonban könnyen kibővíthető a többi eset detektálásához is. Lássuk!

//StatementExpression/PrimaryExpression/PrimaryPrefix
[
./Name[@Image = 'Runtime.getRuntime'] and ../PrimarySuffix[@Image = 'gc']
or
ends-with(Name/@Image, '.gc') and substring-before(Name/@Image, '.') = 
//VariableDeclarator/VariableDeclaratorId/
@Image[../../../Type/ReferenceType[ClassOrInterfaceType/@Image='Runtime']]
]


A szabály a //StatementExpression/PrimaryExpression/PrimaryPrefix kifejezésre illeszkedő csomópontok halmazára fogalmaz meg két feltételt egy logikai vagy kapcsolattal elválasztva. A feltétel első része azokra a csomópontokra illeszkedik, amelyeknek PrimaryPrefix alatti Name csomópontjának a neve Runtime.getRuntime és a PrimaryExpression csomópont alatt tartalmaz egy olyan PrimarySuffix-es node-ot, aminek a neve gc. A feltétel második része pedig olyan Runtime típusú példány deklarációkat keres ahol is a példányon a gc() metódus meghívásra került az adott lokális scope-on belül.

Mivel a feltétel második részének a megvalósítása összetettebb kifejezést eredményezett, ezért a részletes ismertetést az alábbi AST alapján fogom bemutatni.


Az ends-with(Name/@Image, '.gc') kifejezésrész olyan csomópontokra fog rámutatni ami a PrimaryPrefix alatt található és a neve a .gc –re végződik. Az AST példában ez lesz a Name:rt.getRuntime.gc csomópont.

substring-before(Name/@Image, '.')=//VariableDeclarator/VariableDeclaratorId/@Image[../../../Type/ReferenceType[ClassOrInterfaceType/@Image = 'Runtime'

A fenti kifejezés pedig az előzőleg kiválasztott csomópontok névből levágja a legelső pont előtti előtagot, a példa szerint az rt-t, ezután a változó deklarációkra illesztett útvonallal (//VariableDeclarator/VariableDeclaratorId) visszakeresi hogy a lokális scope-n belül ennek a példánynak a típusa Runtime volt-e. Amennyiben talál ezen feltételeknek megfelelő csomópontot a szabály kijelzi a hibát.

Összegzésként elmondhatom hogy az XPath alapú kifejezésekkel általában tömören és jól olvashatóan fogalmazhatjuk meg a szabályainkat. Ha netán mégis nehézségekbe ütköznénk akkor arra is megvan a lehetőség hogy Java nyelven fogalmazzuk meg a szabályainkat.

2013. július 7., vasárnap

PMD - XPath alapú kódellenőrző plugin fejlesztés 1.

A múltkori bejegyzésben átismételtük az XPath alapú szabályok alapjait, most pedig nézzünk meg néhány egyszerű gyakorlati példát a kód ellenőrző plugin-ok fejlesztésre.

Statement használatának a kijelzése


Általános esetben érdemes elkerülni a java.sql.Statement használatát, helyette pedig a java.sql.PreparedStatement paraméter binding-gal való alkalmazása javasolt. XPath alapú szabállyal megfogalmazva ez a következőként nézne ki: 

//ClassOrInterfaceType[@Image='java.sql.Statement' or @Image='Statement']

A fenti kifejezéssel minden olyan osztály és interface típusú deklaráció kijelzésre kerül, aminek a neve Statement vagy java.sql.Statement. Érdemes megemlíteni, hogy a csomagnévvel specifikált nevet és az egyszerű osztálynevet is definiálni kell a szabályban, mivel a fejlesztők mindkét verziót használhatják a forráskódban! A szabállyal azonban probléma jelentkezhet abban az esetben, ha a kódbázisban egy saját Statement osztály is használatban van, mivel erre is illeszkedne a szabály második feltétele. Megoldásként az előbbi szabályt érdemes kibővíteni az import deklarációkra vonatkozó megkötésekkel:

//ClassOrInterfaceType[(@Image='Statement' or @Image='java.sql.Statement')
and (/ImportDeclaration/Name[@Image='java.sql.Statement'] 
or /ImportDeclaration/Name[@Image='java.sql'])]

SELECT * jellegű lekérdezések kijelzése


Az SQL query-k készítésekor érdemes előre megadni az oszlopneveket, így a lekérdezések végrehajtásakor valóban csak azok az adatok kerülnek át a klienshez amire szükség is lesz. A szabály megsértését az alábbi XPath alapú kifejezéssel tudnánk kijelezni:

//Expression[descendant::Literal[contains(upper-case(@Image), 'SELECT')]
and descendant::Literal[contains(@Image, '*')  ]]

Ez a kifejezés minden olyan string-re illeszkedik akár összefűzésen keresztül is, ahol a select és a * literálok is szerepelnek. Mivel nem lehetünk biztosak abban, hogy a kódban a select betűit kis vagy nagy betűsen, netán vegyesen adták meg, ezért az upper-case() XPath függvénnyel nagybetűsre alakítjuk a vizsgálat előtt.

A folytatásban pedig egy összetettebb példát fogunk megnézni.

2013. július 1., hétfő

PMD - Az XPath kifejezések használata

XPath alapú szabályokat legegyszerűbben a PMD Rule Designer segítségével készíthetünk, amivel a célunk az AST megfelelő csomópontjaira illeszkedő kifejezés létrehozása az adott szabályra vonatkozólag. Mielőtt elkezdenénk a PMD-s kódellenőrző kiegészítőket fejleszteni, érdemes egy kicsit felfrissíteni az XPath tudásunkat.


Az XPath kifejezések lehetőséget adnak arra, hogy bizonyos feltételek mentén kiválasszunk egy csomópontot vagy csomópont halmazt az AST-n. A fenti ábrán látható mintakódot ill. AST-t felhasználva nézzük meg a leggyakrabban használt XPath kifejezéseket.

Hivatkozás a gyerek csomópontokra

 A "/" segítségével az aktuális csomópont gyerekét tudjuk elérni, ami alapesetben a gyökér csomópont. Az alábbi kifejezéssel a gyökér node-tól kezdődően eljuthatunk a ResultType node-ig: 
/TypeDeclaration/ClassOrInterfaceDeclaration/ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/MethodDeclaration/ResultType

Hivatkozás a leszármazott csomópontokra

A "//" operátorral az aktuális node leszármazottaira vonatkozó illeszkedést fogalmazhatunk meg. Példaként az előző kifejezés helyett használhattuk volna a //ResultType kifejezést is, mivel a mintakódot tekintve ugyanarra a node-ra illeszkednek.

Attribútumok és feltételes szerkezetek

A "@" segítségével egy adott csomópont valamelyik attribútumára hivatkozhatunk. Érdemes megjegyezni, hogy a PMD által felépített AST fában az elem nevét mindig a @Image property-vel érhetjük el. A //Literal[@Image='"hello world"'] kifejezés a mintakód AST-jának a legutolsó csomópontjára fog illeszkedni ahol is "[]" jelek között a csomópont nevére vonatkozó feltételt adtunk meg.

Az XPath beépített függvényeinek használata

Az XPath kifejezések használata során igénybe vehetjük a beépített függvényeket is. Példaként a contains() ill. a starts-with() függvényeket használhatjuk ahhoz, hogy kiválasszuk a minta AST fa legutolsó csomópontját: //Literal[contains(@Image,'hello')] ill. //Literal[starts-with(@Image,'"hel')] .

"Wild card"-ot használó kifejezések

Egy adott helyen a "*" karakter bármilyen node-ot reprezentálhat. A //ClassOrInterfaceBodyDeclaration/*/ResultType kifejezés minden ResultType típusú node-ra illeszkedni fog, aminek a nagyszülője ClassOrInterfaceBodyDeclaration típusú.

Az "XPath Axis"-t használó kifejezések

Az Xpath Axis lehetőséget ad arra, hogy az aktuális csomópont-hoz viszonyítva a rokonsági fok alapján lekérjünk a kívánt node-ok halmazát. A //Arguments/descendant::PrimaryPrefix kifejezéssel minden olyan PrimaryPrefix csomópontot visszakapunk, amelyek egy Arguments típusú csomópont leszármazottai. Összehasonlításként ugyanez a kifejezés a "*" karakterrel megfogalmazva a //Arguments/*/*/*/PrimaryPrefix kifejezés lett volna.

Az érdeklődők számára a további XPath lehetőségekről a w3schools.com tutorial-t ajánlanám. A folytatásban pedig néhány gyakorlati példát fogok mutatni az XPath alapú plugin fejlesztéshez.

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

2013. május 25., szombat

SZSZK 2013 - Szoftverminőség-biztosítás open source eszközökkel

Frissítve: 2013.06.05. - Lesz workshop is!

Az FSF.hu Alapítvány 2013. június 8.-án ismételten megrendezi a Szabad Szoftver Konferencia és Kiállítást Budapesten, az Óbudai Egyetem Bécsi úti épületében. A konferencia reggel fél tíztől délután ötig fog tartani. Három szekcióban párhuzamosan zajlanak majd a szakmai előadások, ezekkel párhuzamosan az aulában szabad szoftverekkel és szabad kultúrával kapcsolatos kiállítás lesz.

A konferenciára, a Szoftverminőség-biztosítás open source eszközökkel - Hol a határ? címmel egy olyan gyakorlatias előadással készülök, ami a reményeim szerint jópár hasznos eszközt és technikát fog tartogatni a kezdő és haladó Java fejlesztőknek egyaránt. Idézem az előadásom beharangozóját:

"Az előadás során áttekintjük azokat az open source eszközöket és legjobb gyakorlatokat, amelyek a Java platformon hozzájárulhatnak a szoftver folyamataink biztosításához és a minőségi követelmények betartásához. Megnézzük az open source eszközök legfontosabb előnyeit néhány saját példával illusztrálva, majd megmutatom hogy hol van az a határ, ahol már kereskedelmi termékeket is érdemes bevetni.Címszavakban: Jenkins, Ant, Maven, Nexus, SVN, GIT, JUnit, TestNG, JMeter, Selenium, Sonar, PMD, CheckStyle, FindBugs."

Az előadást követő workshop-on gyakorlatban is kipróbálhatod mindazt amit elméletben már elsajátítottál. Egészen a telepítéstől kezdve a konfiguráláson át megismerkedhetsz a Jenkins és a Sonar használatával, felveszünk egy Java alapú projektet majd megvizsgáljuk a kódminőségi jellemzőit. A workshop-on való aktív részvételhez kérlek kövesd a konferencia honlapján közzétett útmutatásokat!

Érdemes eljönni, mert a program alapján nemcsak hasznos tudáshoz juthatnak a résztvevők, de a szervezők jóvoltából a reggel érkező és a rendezvény végéig maradó hallgatók között két 120GB-os és egy 250GB-os SSD is kisorsolásra kerül.


Az előadás prezentációját ide, a workshop útmutatóját pedig ide töltöttem fel.

2013. május 7., kedd

DPC Java Bar - Hibakeresés dynaTrace-szel

Frissítve: 2013.05.30.

A DPC Java Bar meetup-on 2013. május 23-án 18:00 órai kezdéssel, egy bemutatót fogok tartani a dynaTrace-el történő probléma beazonosításról Java Enterprise környezetben.

A DPC Java Bar a DPC Consulting és a HOUG.j Java Szakosztály közös rendezvénysorozata. A szokásos meetup formátummal (rövid bevezető előadások) ellentétben, a JavaBar keretében inkább mélyebb szakmai előadások hangzanak el (főleg Java, JS, HTML5), előismereteket is igénylő, kifejezetten haladó témákban. A 60 perces prezentációt kötetlen beszélgetés követi, ahol is a szervezők mindenkit jávai kávéval várnak. Érdemes megemlíteni, hogy a JavaBar pár hónapja hivatalosan is bejegyzett Java Felhasználói Csoport (JUG) lett. A helyszín limitált mérete miatt előzetes jelentkezés szükséges a meetup.com/bpjavabar címen.

Az előadáson, a rövid bevezető ismeretek után egy korábbi dynaTrace pilot-omat felhasználva (természetesen az ügyfél hozzájárulásával ill. a nevek kitakarásával) fogom bemutatni a hibafeltárás menetét, egészen a gyökér okok meghatározásáig és megoldási javaslatokig. Az előadást ezután egy hosszabb live demo fogja követni, ahol is részletesen megmutatom a dynaTrace lehetőségeit nemcsak a hibafeltárás hanem a monitorozás területén is, valamint ismertetem az üzleti tranzakciók szerepét és használatát is!

Kedvcsinálóként az előadás tartalma:

Bevezetés
  • dynaTrace architektúra
  • PurePaths
  • Transaction Flow
Hibafeltárás dynaTrace-szel
  • Nyomozás a magas szerver oldali válaszidők után
  • Egy sokáig tartó keresés okának a feltárása
  • Kliens oldali problémák beazonosítása
dynaTrace live demo
  • Egy kiválasztott felhasználó látogatásának lekövetése
  • dynaTrace dashletek
  • Monitorozás: beépített, ill. saját dashboard-ok készítése
  • Üzleti tranzakciók kialakítása 

A prezentáció itt érhető el.

2013. április 28., vasárnap

Sonar - A metrikák értelmezése 3.

Ahogy a múltkori bejegyzésemben is említettem, nemcsak a csomagok kialakításánál, hanem az osztályok és metódusok szintjén is érdemes odafigyelni a tervezésre!

A célunk, hogy a projekt osztályai minél függetlenebbek legyenek egymástól (laza csatolás), az osztályok metódusai pedig minél jobban kötődjenek az adott osztályhoz (erős kohézió)! Ha az osztályok szorosan kapcsolódnak egymáshoz, akkor az osztályokon végzett módosítások továbbgyűrűzhetnek a többi osztály felé és más osztályokra is hatással lehetnek. Ha pedig valamely osztály két metódusa nem használ közös attribútumokat ill. metódusokat, akkor valószínűleg nincs is közös tulajdonságuk, így ezeket két különböző osztályba kellene kiszervezni.

Afferent Coupling, Efferent Coupling

Az Afferent Coupling értéke azoknak az osztályoknak a számát adja, amelyek a kiválasztott osztályt használják, így ha a kiválasztott osztályban módosítások történnek, ezekre az osztályokra lehet majd hatással. Az Efferent Coupling értéke pedig azt mutatja, hogy a kiválasztott osztály hány másik osztálytól függ, azaz hogy hány másik osztályt importált be (vagy hivatkozott be).

Az alábbi példát tekintve, a ReaderInitializationException osztály Efferent Coupling értéke 1, mivel a funkcionalitásához csak egy másik osztályt, mégpedig az InitializationException osztályt használja fel és importálja be, amit a source fül alatt le is ellenőrizhetünk. Az Afferent Coupling értéke pedig 6, mivel ennyi osztály használja a ReaderInitializationException osztályt.



RFC (Response For Class)

Az RFC értéke az osztályok felelősségét mutatja, aminek az értéke az osztály minden metódusával ill. külső metódushívással (kivéve getter/setter) eggyel növekszik. Az alacsony RFC értékre és az oszlop diagram balra tolódására kell törekedni, általánosságban pedig elmondható, hogy csak a több száz RFC értékkel bíró osztályokra érdemes ránézni és a javításukat megfontolni.

 
Példaként nézzük meg az alábbi forráskód részletet, ahol is a TestRFC osztály RFC értéke 6 lesz a kommenteknél megjelölt hívások miatt.
public class TestRFC {
 //Empty TestRFC constructor   -> +1
 private Person p=new Person(); //new Person()  -> +1
 public void testMethod1(){ //testMethod1() -> +1
  System.out.println("test1"); //System.out.println(…) -> +1
 }
 public void testMethod2(){ //testMethod2() -> +1
  System.out.println(p.toString()); //p.toString()  -> +1
 }
}

LCOM4 (Lack Of Cohesion Of Methods)

Az LCOM4, a Single Responsibility Principle tervezési minta betartásához nyújt segítséget, miszerint minden osztálynak csak 1 felelőssége legyen ami hozzásegít ahhoz, hogy megszűnjenek a hatalmas osztályok és helyettük sok kicsi, könnyen tesztelhető, gyorsan átlátható és módosítható osztály jöjjön létre! Megjegyezném, hogy a munkám során már nem egyszer találkoztam 10.000 kódsort meghaladó osztályokkal, amik ugye nem javadoc-al voltak tele... :)

Az LCOM4 metrika arra a felépítésre épít, hogy az egymással kapcsolatos metódusok, ugyanazokkal az osztály szintű (nem metódus hatókörű) változókkal dolgoznak vagy egymást hívják. Egy kohézív osztályban tehát csak összetartozó metódusok találhatók, amelyek kizárólag az osztály funkciójának a biztosításáért dolgoznak. A nem kohézív osztályok egynél több felelősséggel is rendelkeznek, így ezeket az egyes felelősségek szerint több kisebb osztályba kell kiszervezni.

Mivel az LCOM4 az osztályonkénti felelősségek számát jelöli, ezért csak akkor tekinthető elfogadhatónak, ha az értéke 1. A 0 értékkel rendelkező osztálynak nincsen konkrét felelőssége, az 1-nél több értékkel rendelkező osztályoknak pedig több felelősségük van.

Az alábbi osztálynál - a standard szabály szerint számítva - az LCOM4 értékének 3-nak kellene lennie, így a megadott osztályt 3 másik osztályra kellene szétbontani, melyek a következő metódusokat ill. attribútumokat tartalmaznák:
  1. video, playVideo(), stopVideo(), restartVideo()
  2. audio, playAudio()
  3. autoSleep()
public class AudioVideoManager   {

 private Video video;
 private Audio audio;

 public void playVideo() {
  video.play(); 
 }  

 public void stopVideo() {
  video.stop();
 }

 public void restartVideo() {
  stopVideo();
  playVideo();
 }

 public void playAudio() {       
  audio.play(); 
 }
 
 public void autoSleep() {  
  System.out.println("auto sleep");   
 } 
}
A valós életbeli példákon nézve a tapasztalat azt mutatja, hogy standard szabály túl sok ’false positive’ értéket jelezne, ezért a Sonar egy feltunningolt LCOM4 algoritmussal dolgozik, miszerint ha az LCOM4==1, lehetséges hogy további szétbontás is szükséges azonban az LCOM4>1 esetén biztosan kijelenthető, hogy szét kell bontani az osztályt. A fenti kódrészletnél az LCOM4 értéke a módosított szabály miatt így nem 3, hanem 1 lesz.


Ha az LCOM4 widget-en az LCOM4>1 linkre kattintunk, akkor az osztályok kiválasztása után az LCOM4 tab aktivizálódik, ahol megtekinthetjük, hogy ezt az osztályt milyen metódusok mentén kellene kisebb osztályokra szétbontani.


A Sonar metrikák elemzése ezzel a cikkel véget ért, legközelebb egy kicsit más témával jelentkezem.

2013. március 23., szombat

HOUG 2013 - Beszélgetés az ALM eszközökről

Meghívást kaptam a Magyarországi Oracle felhasználok konferenciájára (HOUG), ahol is az alkalmazás életciklus menedzsment eszközökről fogok beszélgetni Verhás Istvánnal és Varga Péterrel. A konferencia a siófoki Azúr Hotelben kerül megrendezésre április 8-10 között, a kerekasztali beszélgetésre pedig április 8-án fog sor kerülni 16:00 órai kezdettel. A rendezvényen egyébként érdekes előadások és workshopok is várhatók: CDI a gyakorlatban, Vaadin kedvcsináló, WebSocket kommunikáció.

Idézem a hivatalos beharangozót:

"Kerekasztal beszélgetés: Hagyjanak már nyugodtan kódolni! - avagy application lifecycle management eszközök és létjogosultságuk. Varga Péter (DPC Consulting Kft), Verhás István (Verhás és Verhás Szoftver Manufaktúra Kft.), Bakai Balázs (Telvice Kft.), Csepeli Csaba (AFF Group)"

"A fejlesztők és a projektvezetők között örökké felmerül a vita, hogy kellenek-e a (tágabb értelemben vett) ALM eszközök, vagy csak hátráltatják az "igazi" munkát. És ha kellenek, akkor melyiket érdemes használni a rengeteg kereskedelmi és nyílt forrású termék közül (csak illusztrációképp: sonar, hudson, jenkins, hg, git, checkstyle, maven, junit, mockito, jira, findbugs, dynaTrace, ...)? "

A konferencia részletes programjáról ezen a linken találsz információkat. Ha érdekelnek az ALM eszközök és az Oracle technológiái, akkor Neked is itt a helyed!

 

2013. március 7., csütörtök

JUM XXII - Banki stabilizációs projekt, dynaTrace

2013. március 20-án, 18:00 órától megrendezésre kerül a Java User Meeting (JUM) következő alkalma a SZTAKI előadótermében (1132 Budapest, Victor Hugo u. 18-22), amelyen a tavalyi banki stabilizációs projektről és a dynaTrace-ről fogok egy közel 50 perces előadást tartani! Gyertek el minél többen, a dynaTrace-szel kapcsolatos kérdéseiteket most személyesen is feltehetitek. 

Kedvcsinálóként pedig az előadás tartalma:
  • dynaTrace Architecture
  • PurePaths and Sensors
  • dynaTrace dashlets (Transaction Flow, Response Time Hotspots, ...)
  • Thread and Heap dump analysis features
  • Monitoring Dashboards
  • Banki problémák és a stabilizáció eredményei
  • Feltárt problémák áttekintése
  • A kód minőségbiztosítás banki bevezetése
  • Jövőbeli irányok kijelölése, a dynaTrace tesztkörnyezeti integrációja
  • dynaTrace LIVE DEMO
  • Kérdések

Találkozunk a JUM-on!

2013. március 3., vasárnap

Sonar - A metrikák értelmezése 2.

A múltheti bejegyzésem folytatásaként most a komplexitás és a csomagok közötti függőségek jellemzőiről fogok írni!

Complexity

A komplexitást a metódusokban található feltételes és vezérlési szerkezetek száma határozza meg, azaz az értéke a for, do, while, break, continue, if, else, case, default, return, catch, throw, throws, finally, &&, ||, ?, :, ^, &, | szerkezetekkel eggyel fog nőni. A widget jobb oldalán egy oszlop diagramon látható a projekt összes metódusának, ill. fájljának a komplexitás szerinti eloszlása. A komplexitásnál az alacsonyabb értékek tekinthetők jónak, mivel ezek kevesebb metódusonkénti feltételes és vezérlési szerkezetet, így karbantarthatóbb kódot jelentenek. A widget jobb oldali oszlop diagramja akkor tekinthető ideálisnak amikor baloldalra súlyozódik, mivel ilyenkor az egyszerűbb metódusok vannak többségbe. Általánosan elmondható, hogy a metódusonkénti 2.5 érték jónak tekinthető, 7 felett pedig már érdemes refaktorálni, azaz átszervezni a metódus kódját!


Package Tangle Index

Habár a Java projekteket jar-okba, csomagokba, fájlokba, osztályokba és metódusokba szervezzük ettől még nem feltétlenül lesz az alkalmazásunk moduláris! A tervezésnél figyelnünk kell arra, hogy az osztályok lazán csatoltak és erősen összetartóak legyenek (LCOM4, RFC) valamint arra is, hogy a csomagok között ne alakuljanak ki függőségi körök (Package Tangle Index). A package tangle index tehát a projekt csomagjai között kialakult függőségeket mutatja, aminek a feloldásához a Dependency Structure Matrix (DSM) használatát ajánlja a Sonar. Két java package között akkor alakul ki körbefüggés, amikor az egyik csomag valamelyik java osztályának egy másik csomag valamely java osztályára van referenciája és ez fordítva is teljesül! A csomagok közötti függőségeket azért érdemes elkerülni, mert ezek a csomagok egy szoros egységet fognak alkotni - ezzel csökkentve a modularitást - így azok majd nem választhatók el a későbbiekben egymástól! 

A következőkben a TinyJEE project, Doxia :: Include - Macro-ján keresztül fogom ismertetni a csomagok közötti függőségek felkutatását és azok feloldását. Az alábbi ábrán látható Sonar widget szerint 2-nél több körbefüggés van a projektben és ezek megszüntetéséhez 1 helyen kell a csomagok közötti függőségeket szétvágni, ami úgy tűnik hogy nem lesz nehéz feladat mivel csak 1 fájlt fog érinteni a módosítás!


Ha rákattintunk a widget-en található valamelyik linkre, akkor az alábbi ábrán látható függőségi struktúra mátrixhoz (DSM) jutunk, ami segítségünkre lesz a függőségek feloldásához. A táblázat sorainak első celláiban az egyes java csomagok nevei találhatóak, az oszlop nevek pedig ehhez hasonlóan alakulnak csak helyhiány miatt nincsenek feltüntetve. A gyanúsított függőségeket a piros négyzetek jelölik, így a munkát is itt kell kezdeni.

 

Ha kétszer rákattintunk az  org.tinyjee.maven.dim sorban található piros négyzet 1-es számára, akkor a táblázat alatt megjelenik, hogy a org.tinyjee.maven.dim.utils csomagból egy osztályának (AbstractAliasHandler) referenciája van a org.tinyjee.maven.dim csomag RequestParameterTransformer osztályára.


Látható, hogy a kattintás során a piros négyzet háttere lilára vált és a táblázatban kijelölődik egy másik cella is lila színűre. Ha ebben a cellában található 3-as számra kétszer rákattintunk, akkor az alábbi ábra szerint a táblázat alatt megjelennek a konkrét függőségek listája. Az org.tinyjee.maven.dim csomagban vannak olyan osztályok, amelyek a org.tinyjee.maven.dim.utils csomag osztályaira tartanak referenciát, ami az előző ábrát tekintve pont fordított, azaz megállapítható, hogy az említett 2 csomag között körbefüggés áll fent amit érdemes megszüntetni a modularitás fenntartása érdekében!


Látható, hogy a DSM segítségével gyorsan felderíhetők a csomagok közötti függőségek. A Sonar további eszközöket is biztosít a forráskód minőségének feljavításához amelyekről hamarosan olvashatsz a blogon.