Java konstruktor hívási sorrend

Rég írtam, valóban. Hogy újra rávezessem magam a kedvenc munkán kívüli elfoglaltságomhoz, most egy egyszerűbb témát vetek fel, ami mégis okozott pár kobak-koppanást az asztalon. Nevezetesen arról szándékozom írni, hogy a Java hogyan sorrendezi egy objektum inicializálásában résztvevő kódokat. Mert bizony több lehet, és nem egyértelmű a lefutási sorrend, ahogy azt a követkető kódrészlet szemlélteti:


public class AB{
public static abstract class A{
public A(){
doSomething();
}
protected abstract void doSomething();
}

public static class B extends A{
final String s = "1234";
final Object o = "1234";
public B(){
super();
}
@Override
protected void doSomething(){
System.out.println(s.getClass());
System.out.println(o.getClass());
}
}

public static void main(String[] args){
new B();
}
}

A példát igyekeztem egyszerűnek tartani, de talán megérdemel egy rövid magyarázatot: Két osztályt definiáltam, az egyik leszármazottja a másiknak. Érdekesség még, hogy az ős konstruktora kódot hív meg a leszármazottból absztrakt metóduson keresztűl. Egy “B” típusú objektum létrehozásához láthatóan három helyről kell kódot hívni: Az “A” és a “B” konstruktora, továbbá a “B” osztályban lévő, konstruktoron kívüli inicializálás. A probléma ezen három kódrészlet lefutásának sorrendje.

Első ránézésre a kóddal semmi probléma nincs azon kívül, hogy teljesen haszontalan. Mindkét mező final, így gondolnánk a konstruktor elött inicializálódnak, tehát nem okozhat problémát. Azonban a kód futtatásakor egy csinos NullPointerException kacsint vissza ránk. A futás kimenete:


class java.lang.String
Exception in thread "main" java.lang.NullPointerException
at AB$B.doSomething(AB.java:22)
at AB$A.(AB.java:8)
at AB$B.
(AB.java:17)
at AB.main(AB.java:27)

Láthatóan a B.doSomething() első sora lefut hiba nélkül, a probléma utána keletkezik. Tehát az “s” változó már létezik, az “o” viszont nem. A konstruktorok lefutásának sorrendje tehát: s=..,A(),o=..,B(). A két mező között csupán az a különbség, hogy az “s” mező típusa megegyezik a futásidejű értékének típusával. Ez meghatározza, hogy a mező a szülő osztály konstruktora előtt vagy után kap értéket. Érdemes kipróbálni, ha az “s” mező elöl kivesszük a final kulcsszót, az azt okozza, hogy az is a szülő konstruktor hívása után kap értéket. Vajon hogy határozódik meg a pontos sorrend, mitől függ, hogy hova ütemezi be a java a mezők értékadását?

Nyílván valahogy igyekszik meghatározni, hogy az adott értékadás kiértékelhető-e az osztály örökölt részének inicializálása nélkül vagy sem. Ennek tesztelésére tettem még egy kísérletet, kicsit módosítva a példát:


public class AB{
public static abstract class A{
protected String a;
public A(){
a = "abc";
doSomething();
}
protected abstract void doSomething();
}

public static class B extends A{
final String s = "1234"+a;
final Object o = "1234";
public B(){
super();
}
@Override
protected void doSomething(){
System.out.println(s.getClass());
System.out.println(o.getClass());
}
}

public static void main(String[] args){
new B();
}
}

Ez a kód is szépen elszáll, méghozzá a B.doSomething() első sorában! Azaz, az explicit hivatkozás egy szülő objektum-beli elemre azt eredményezi, hogy a mező értékadását a szülő konstruktor utánra ütemezi. Elég intelligensnek tűnik a dolog, de mégis beleütközik az ember, mert másra számít.

Persze elkerülhető a dolog ha a konstruktorból hívott absztrakt metódusokat anti-pattern-nek kiáltjuk ki, bár gyakran jól jön. Mégis pontosan mi határozza meg a sorrendet, és lehet-e befolyásolni valahogyan? Van valaki aki nálam sikeresebben guglizott?

Törött ablakok és hitelek

Az utóbbi időben volt szerencsém elolvasni néhány érdekes írást programozástechnikáról. Ez nem arról szól, hogy a Java/C#/C++/Lisp nyelven jó programokat írni (noha az is hasznos olvasnivaló lehet), hanem inkább afféle ötleteket mutat, amik a programozási munka menedzsmentjéhez tartoznak.

Igen, erről nem véletlen, hogy egyeseknek a [[A programozás technológiája|PT]] jut eszébe, de szerintem annál jóval gyakorlatiasabb dologról van szó. 🙂 Persze ezt az én erőteljesen elfogult véleményem mondatja csak velem, nyilván másnak ugyanolyan használhatatlan dologról van szó.

Az utóbbi időben volt szerencsém elolvasni néhány érdekes írást programozástechnikáról. Ez nem arról szól, hogy a Java/C#/C++/Lisp nyelven jó programokat írni (noha az is hasznos olvasnivaló lehet), hanem inkább afféle ötleteket mutat, amik a programozási munka menedzsmentjéhez tartoznak.

Igen, erről nem véletlen, hogy egyeseknek a PT jut eszébe, de szerintem annál jóval gyakorlatiasabb dologról van szó. 🙂 Persze ezt az én erőteljesen elfogult véleményem mondatja csak velem, nyilván másnak ugyanolyan használhatatlan dologról van szó.

Nem tudom, mennyire ismert a „törött ablakok elmélete” (Broken Window Theory), ezért megpróbálom röviden összefoglalni. A fő gondolata, hogy ha egy civilizált környéken betörik egy ablak (lehet autóé, házé), és senki nem foglalkozik vele – itt most nem arra gondolok, hogy aki betörte, annak bűntudata lesz tőle, de azt beleértem, hogy a javítás idejére bedeszkázzák, – akkor ez közepesen hosszú távon (akár néhány hónap alatt) az egész környéken a környék leromlásához, illetve a(z akár súlyosabb) bűnesetek számának növekedéséhez vezethet.

Ez a hatás nagyjából úgy keletkezhet, hogy az emberek azt látják, hogy más nem foglalkozik a problémákkal, ezért nem érzi úgy, hogy neki is tennie kell valamit. Ha valaki kételkedik az állítás igazságában, gondoljon bele, hogy hol szedne fel nagyobb eséllyel véletlenül elejtett papírzsebkendőt: a Nyugatinál a metróaluljáróban vagy egy öt csillagos hotelben a francia Riviérán.

Hogy ez hol jön a programozáshoz? Az elv ott is alkalmazható: ha nem foglalkozol a kis hibákkal, akkor aki később kapcsolódik, azt fogja látni, hogy az elődje sem gondoskodott róla, hogy elkerülje ezeket, ő sem fog vele foglalkozni (annyira). Aki dolgozott már ilyen kóddal, az tudja, miről beszélek. 🙂

Mik ezek a kis hibák? Warningok, hiányzó dokumentáció, nem kifinomult hibakezelés, gányolás… Lehetne még sorolni. És ezeket többnyire csak akkor lehet megfelelően kezelni, ha mindenki az első pillanattól fogva odafigyel ezekre, különben annyira elszaporodnak, hogy a kezelésük szinte reménytelen (próbált már valaki 1000-es nagyságrendben warningokat javítgatni?).

Jó, mi a teendő olyankor, amikor közeleg a határidőt, és még rengeteg mindent implementálni kell? Nos, ekkor jön a Brute Force Development: kódolunk, gányolunk, és reménykedünk, hogy működni fog. Gondolhatnánk, hogy ez rossz, de a gyakorlatban elkerülhetetlen. Ez nagyon gyakran „törött ablakokhoz” vezethet (nem, most kivételesen nem arról beszélek, hogy a legálisan beszerzett Windows-unk crackeltté válik 🙂 ).

Természetesen ez rossz, de mivel elkerülhetetlen, ezért kénytelenek vagyunk kezelni. Erre a kezelésre ad egy módszert a technológiai tartozás (Technical Debth) fogalma.

Ez a valós életbeli adósságok fogalmához kapcsolódik: felveszünk hitelt, hogy valami lehetőséget időben kihasználjunk (nem kell 20 évet várnunk egy lakásra, és közben albérletben élni, hanem most beköltözünk), de ez nincs ingyen (20 évig fizetjük a részletet). Akkor ne vegyünk fel hiteleket? De, ha van valami helyzet, amit így értelmesen kihasználhatunk, hosszabb távon pénzt spórolhatunk meg, akkor fel lehet venni, de ésszel. Nagyon oda kell figyelni a hitelek visszafizetésére (lásd még: válság 🙂 ).

A programozásban ehhez hasonlóan, ideiglenesen nem a legjobb, legügyesebb, legszebb megoldást választjuk, hanem rosszabb megoldást választunk, tákolunk, gányolunk. És mondjuk magunknak dokumentáljuk, hogy mik ezek a részek, és ezzel foglalkozni kell. Mi lehet ennek az értelme? Határidő, esetleg azt mondani, hogy ha működik, akkor kiadjuk, és utána belül foltozzuk a következő verzió fejlesztésének első lépéseként.

De természetesen itt is figyelni kell, ugyanis ha túl sok efféle dolgot hagyunk benne a rendszerben, akkor később ennek az lehet a következménye, hogy ahhoz, hogy új funkciót adjunk hozzá, nagyságrendekkel több munkát kell befektetni, mint az ideális lenne.

Saját tapasztalataim alapján is igazolni tudom ezt az elvet: az elmúlt héten a saját kódomat próbáltam nagyságrendekkel javítani, hogy új funkciókat adjak hozzá. Ok, vettem a fáradtságot, hogy +20% munkával javítsam azt, amit a TDK előtt BFD-vel befejeztem (visszafizettem a technológiai tartozás egy részét), annak érdekében, hogy a rendszer jobban használható legyen.

Remélem, hasznos/érdekes, amit most felvetettem, ha másnak van véleménye, kiegészítése, nagyon szívesen veszem bármilyen formában, más tapasztalataiból tanulni igenis jó dolog. 🙂

Felhasználói felületek és a programozás

Ennek az írásnak az ötlete már jó ideje motoszkál bennem. Mindig is érdekelt a programozás – magas szinten. Azaz érdekelt, hogyan lehet nagy rendszereket tervezni, érdekelt, hogy ezek a rendszerek hogyan használhatóak az egyszerű felhasználó szemében. Érdekelt, hogyan lehet megcsinálni, de valahogy sosem csináltam meg. Egyszer ki kéne próbálni, de erre a közeljövőben ismételten nem lesz időm.

Ez persze nem akadályozott meg abban, hogy utánaolvasgassak a témának. Illetve azon oldalak ajánlásait kövessem, akikre már amúgy is feliratkoztam. 🙂 Így találtam rá az Ars Technica cikksorozatára, ami a fejlesztési eszközöket, nyelveket, APIkat veszi górcső alá. Korábban már volt szerencsém az Ars Technicahoz, ők képesek voltak korábban például a Leopardot tizenegynéhány oldalban elemezni, elvárásokkal, hiányokkal és hasonló dolgokkal. Szerintem tanulságos volt, ezért érdemesnek láttam a cikksorozatba is belekóstolni.

Ennek az írásnak az ötlete már jó ideje motoszkál bennem. Mindig is érdekelt a programozás – magas szinten. Azaz érdekelt, hogyan lehet nagy rendszereket tervezni, érdekelt, hogy ezek a rendszerek hogyan használhatóak az egyszerű felhasználó szemében. Érdekelt, hogyan lehet megcsinálni, de valahogy sosem csináltam meg. Egyszer ki kéne próbálni, de erre a közeljövőben ismételten nem lesz időm.

Ez persze nem akadályozott meg abban, hogy utánaolvasgassak a témának. Illetve azon oldalak ajánlásait kövessem, akikre már amúgy is feliratkoztam. 🙂 Így találtam rá az Ars Technica cikksorozatára, ami a fejlesztési eszközöket, nyelveket, APIkat veszi górcső alá. Korábban már volt szerencsém az Ars Technicahoz, ők képesek voltak korábban például a Leopardot tizenegynéhány oldalban elemezni, elvárásokkal, hiányokkal és hasonló dolgokkal. Szerintem tanulságos volt, ezért érdemesnek láttam a cikksorozatba is belekóstolni.

Az írás alapvető példája, mint mondtam, az volt, hogy összevesse a lehetőségeket. Előrebocsátom, hogy az ő írásuk is (az enyém meg pláne) az Apple megoldását preferálja a Microsoftéval szemben, ezért aki ebből flamet csinálna, az inkább most hagyja abba. Annak semmi értelme sincs (mondom ezt én 🙂 ).

Na, ideje belevágni a témába. A vonatkozott cikksorozat engem leginkább egy vonatkozásban fogott meg: a második részben feszegette azt, hogy a Microsoft APIk mennyire nem kifinomultak – valószínűleg ez lehet az oka, hogy szerte a cégen belül is a “kerék újra feltalálása” a divat. Ezt talán a mellékelt kép is szemlélteti (a kép eredeti változata a http://arstechnica.com/articles/culture/microsoft-learn-from-apple-II.media/vista.png címen érhető el).

A Microsoft konzisztensnek nem nevezhető kínálata felhasználói felület témában

A helyzet rossz. Nagyon. A képen szereplő ablakok a Visual Studio 2005 kivételével az aktuálisan elérhető legfrissebb változatok. Érdemes megfigyelni, hogy vannak alkalmazások menüvel és menü nélkül (utóbbi esetben szalaggal vagy rejtett menüvel). További érdekesség, hogy az Office család szereplő tagjainál alapvető eltérések vannak szerkezetben (szalag nézet a Wordben, hagyományos nézet a Visioban, és az Outlook mindig is egyedi volt). Másik érdekesség az előre-hátra nyilak az Intézőben, az Internet Exporerben és a Windows Media Playerben. Pontosabban a mellette levő lefele nyíl, ami a listát jelenítené meg: minő véletlen, ebből is van háromféle változat.

Biztos, hogy van még különbség, de ezek felderítését az unatkozó olvasókra bízom. 🙂

Azzal semmi bajom sincs, hogy a Vistában a felület máshogy néz ki, mint korábban. Lehet vitatkozni rajta, hogy jobb lett vagy rosszabb, mint a korábbi, én nem teszem meg, mert csak képernyőképeken láttam a rendszert. De ez így katasztrófa. Az Ars Technica sorozatában még mondott egy érdekes példát: a Vista kezdeti változatában azért voltak gondok a hangkártyadriverekkel, mert a Microsoft a fejlesztés végső szakaszában módosította a hangrendszert. Az ok: leültek multimédiában érintett emberekkel, és azok jelezték, hogy a lejátszóprogramok feleslegesen terhelik a gépet, ha pollozzák a hangbuffer állapotát, jobb lenne, ha az értesítené őket, hogy fogyóban az adat. Felmerül a kérdés: ez miért nem került a cég multimédiás programjának, a Windows Media Player fejlesztésekor? Például mert nem használja a saját APIt?

Ezzel szemben OSX-en az Apple szinte minden programja (nem állítom, hogy minden, mert azért az sem lenne igaz) egy közös megjelenítési APIt használ, és ez az API elérhető a fejlesztők számára is. Ezen felül elérhető még [[http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/|Apple Human Interface Guidelines]] című dokumentum is, ami egyfajta szakácskönyvet ad a fejlesztők kezébe, hogy az Apple milyen elvek szerint építi fel a programjait (többé-kevésbé). Eredmény: ha jön egy programozó, aki OSXre szeretne szoftvert írni, megnézi ezt a dokumentációt, és ez alapján tervezi meg a felhasználói felületet, és a beépített APIt felhasználva valósítja meg. Következmény: a 3rd party programok is hasonlóak lesznek a beépítettekhez. Ez a Microsoftos káosznál elérhetetlen állapot…

Persze a dolog messze nem ilyen egyértelmű: a http://www.neopoleon.com/home/blogs/neo/archive/2008/03/17/29941.aspx oldalon például a szerző azt részletezi, hogy miért nem szereti az OSX APIjait. Ez érthető is. Ahogy az Ars Technicas cikk harmadik részében szerepel, az Apple által erőltetett Objective-C nyelv alapvetően különbözik a megszokott objektum-orientált nyelvektől, csak OSX-en lehet használni, az XCode nevű program semmi különöset nem nyújt egy Visual Studiohoz képest, sőt, az extrák tekintetében le is van maradva. Szintén ebben a cikkben szerepel, hogy OSX-en meg hiányolja a .NET bizonyos részeit vagy éppen az Office 2007-et. Más szóval a helyzet messze nem egyértelmű, érdemes a továbbiakban is figyelni a témát, milyen változások lesznek.

Frissítés: Az Ars Technica cikksorozatára való hivatkozásokat pótolom.

  • [[http://arstechnica.com/articles/culture/what-microsoft-could-learn-from-apple.ars|Áttekintés, történelem]]
  • [[http://arstechnica.com/articles/culture/microsoft-learn-from-apple-II.ars|A Microsoft megoldásainak összegzése]]
  • [[http://arstechnica.com/articles/culture/microsoft-learn-from-apple-III.ars|Az Apple APIk ismertetése]]

Lonely HDR, azaz HDR kép készítése egyetlen képből

Sok mindenre képes az ember, ha van egy kis ideje. Például elgondolkodhat, hogyan tudná a rengeteg közepesen jól sikerült fényképét egyszerűen feltúrbózni, amit már szívesebben mutogat bárkinek. Kis gyakorlással csodát lehet művelni Photoshop (vagy a nyílt forráskód híveinek – küztük nekem – Gimp) segítségével, azonban ez néhány ezer kép nagyságrendnél kicsit idő- és munkaigényes. Fontos tehát, hogy mindezt automatikusan tudjuk csinálni. Már csak egy jó ötlet hiányzik. Ezen segít ha kicsit ránézünk a HDR technológiára.

High Dynamic Range imaging, avagy mi is ez? – dióhéjban

Sok mindenre képes az ember, ha van egy kis ideje. Például elgondolkodhat, hogyan tudná a rengeteg közepesen jól sikerült fényképét egyszerűen feltúrbózni, amit már szívesebben mutogat bárkinek. Kis gyakorlással csodát lehet művelni Photoshop (vagy a nyílt forráskód híveinek – küztük nekem – Gimp) segítségével, azonban ez néhány ezer kép nagyságrendnél kicsit idő- és munkaigényes. Fontos tehát, hogy mindezt automatikusan tudjuk csinálni. Már csak egy jó ötlet hiányzik. Ezen segít ha kicsit ránézünk a HDR technológiára.

High Dynamic Range imaging, avagy mi is ez? – dióhéjban

Kicsit bővebb leíráshoz: http://en.wikipedia.org/wiki/High_dynamic_range_imaging

A HDR célja általában olyan képek létrehozása, amelynek minden része teljes részletességgel látszik, attól függetlenül, hogy az sötét-e vagy világos. Ami azért nehéz, mert ha a világos részt kiemelve rövid ideig exponál a gép, a sötét részek nem fognak látszódni, míg túlexponált képpel előhozhatóak a sötét részletek, de a világos rész lesz kivehetetlen. A HDR alapötlete az, hogy egyetlen kép helyett csináljunk többet, különböző exponálással. Ezen képek alapján aztán összerakható olyan kép, amelynek minden részlete a megfelelő exponálással készült.

HDR-hez több kép kell, de nekünk csak egy van?

Nyílván egyetlen képből nem nyerhető annyi információ, mint akár három különbözőből, azonban nem is ezt akaruk elérni. A cél csupán az, hogy a rendelkezésre álló képből hozzuk ki a lehető legtöbbet, és ehhez használjuk fel a HDR-nél is használt technikát. A módszer nem más, mint a képet visonylag apró szegmensekre bontjuk, és minden szegmensre kiválasztjuk a rendelkezésre álló variánsok közül a legjobbat. A HDR esetén fizikailag van több képünk, ebben az esetben ugyanazt a képet világosítjuk/sötétítjük néhányszor. A világosság változtatásával ugyan nem nyerünk információt, a kép hatását a nézőre azonban jelentősen befolyásolhatjuk. Így tehát minden szegmensre kiválasztjuk az optimálisat, elsimítjuk az illesztéseket, végül kicsit megnöveljük a színtelítettséget, hogy tényleg szép legyen.

A fenti ötlet alapján készült egy kis java program, ami mély elmélkedés árán egész szép eredményt ér el a bemeneti képpel. Letöltés után valami ilyesmit kell beírni egy parancssorba:


java -jar lonelyhdr.jar input.jpg output.jpg

Rövid várakozás után egy kicsinosítgatott kép kacsint vissza ránk:

input.jpg output

Letöltés: lonelyhdr.jar

Fontos megjegyzés: a program értelmes eredményt csak megfelelő méretű (értsd: mai átlagos fényképezőgép által készített) képpel tud elérni. A fenti kép például egy 5 megapixeles szappantartóal készült, és a képet eredeti méretében (2592 x 1944 pixel) eresztettem át a programon.

J2EE és JUnit – avagy a platformfüggő Java

Végre, beadtuk. Az UML tárgyból esedékes házi feladatot (lásd még [[J2EE – a nagy aknamező|a múltkori írást]]). Ez J2EE egyszerűen valami félelmetes. Ez a technológia szép. De tényleg…

Az implementáció után mindössze teszteseteket kellett írni az utolsó beadásra. Mindössze. Persze ez akkor sem olyan egyszerű, hiszen azt JUnitban kellett megírni, ami alapvetően maga szeretné futtatni a teszteket. Semmi gond, akkor átverjük, feltöltjük a JUnitot is a konténerbe, és ott majd látni fogja a keresett dolgokat.

Végre, beadtuk. Az UML tárgyból esedékes házi feladatot (lásd még [[J2EE – a nagy aknamező|a múltkori írást]]). Ez J2EE egyszerűen valami félelmetes. Ez a technológia szép. De tényleg…

Az implementáció után mindössze teszteseteket kellett írni az utolsó beadásra. Mindössze. Persze ez akkor sem olyan egyszerű, hiszen azt JUnitban kellett megírni, ami alapvetően maga szeretné futtatni a teszteket. Semmi gond, akkor átverjük, feltöltjük a JUnitot is a konténerbe, és ott majd látni fogja a keresett dolgokat.

Hehe, már megint optimista vagyok ezekkel a cuccokkal kapcsolatban. Ez, hogy feltöltsük a JUnitot, ez körülbelül két óra szívást jelentett a classpath, build path, referenced projects, requirements és hasonló témában projektek és pluginek viszonylatában. Ezek tulajdonképpen mind-mind egyfajta függőséget jelentenek a projektek és más projektek, esetleg libek vagy hasonlók között, de az a poén az egészben, hogy a szerepük között jelentős átfedések vannak. És ami igazán kellemetlen az az, hogy ha a helyes megoldás mellett egy nem szükséges helyen megadod a függőséget, akkor már nem jó. Lehet vele szépen játszadozni.

Jó, túl vagyunk az alapozáson, megvan a teszt keretrendszer, kezdünk teszteseteket írni. Egyszer csak egyik kolléga megkeres, hogy nagyon eszement hibaüzenetet ad egy importra: nem azt, hogy nem találja, hanem azt, hogy nem engedélyezett a használata. Remek, újabb szép körnek néz ki. Ezúttal sajnos nem tévedtem. Némi játszadozás után értettem meg, hogy tényleg látja, csak valami miatt nem akarja használni. Közben szétvertem a tesztkörnyezetet (utána újból órákba kerül, amíg mindenkinél összeáll, de erről később). Na, ekkor némi Google, meg váltogatás a különböző Eclipse környezeteim között (bizony, nekem több is van, be-be-be 🙂 ), és kiderül, hogy a probléma egészen csúnya: az Eclipse támogat egy package-korlátozást (access rule-nak hívja) a különböző pluginekre. Ok, ez önmagában nem csúnya, hisz így az Eclipse-plugin írója rákényszerítheti a felhasználó plugint, hogy az api-n keresztül érje el. De ami gáz, hogy ezt alkalmazta a beépített Java típuskönyvtárra.

Ok, módosítsuk a dolgot. Némi segítség után rájövök, hogy melyik jarban van a keresett osztály. Adjunk hozzá egy engedélyező bejegyzést a jarhoz tartozó access rule-ok közé. Újabb pofára esés, és kiderül, hogy nem írható. Remek. További leírásböngészés, és ekkor kiderül, hogy az ősét, ha tudom szerkeszteni, az is jó. Na, azt tudom, mert a globálisat engedi szerkeszteni, csak a system jarokét nem, meg a workspace-ben definiált pluginekét sem (azokat a plugin.xml szerkesztőjén lehet hakkolni). Remek, beírom az osztálynevet com.sun…. formában, örülnék, hogy megy, de nem megy. Ok, nézzünk mintát, igaza van, /-rel kell írni, és ha *-gal zárom, akkor egy package-re lebontva tudom szerepeltetni. Ok, egy részét átírom /-esre (nem kéne azért a teljes com. tartományt engedélyezni), majd csillaggal lezárom. Még mindig nem jó. Aztán kiderült. Ahhoz, hogy rekurzívan elinduljon lefelé a csomaghierarchiában, ahhoz nem árt **-gal lezárni… Na, ezután már megy.

Illetve csak az a hivatkozás. Csak a libekkel szórakozás miatt elment a futtatókörnyezet. Sebaj, rutinos róka vagyok már, nekilátok és összerakom a megfelelő fájlt (jó, most csaltam, összeklikkeltem a run dialogban). Végre megy nálam. Ekkor töltsük fel svn-re, hogy a többieknek is menjen.

Eltelik pár perc, és kiderült, hogy nem ment át. Mint utóbb kiderült, verzió- és oprendszerkülönbségek miatt. Az OSX->Windows irányban nem működik. És fordítva sem. Az lett a vége, hogy a Windows-osok megcsinálták a környezetet, majd feltöltötték svn-re, ezután én is megcsináltam az enyémet, de én nem töltöttem fel. Erre ezután minden commitnál vigyázni kellett remek. Még szerencse, hogy a Java platformfüggetlen.

De ez semmi ahhoz képest, ami ma hajnali 5 magasságában derült ki, 6 órával a beadás előtt (ameddig persze be is kellett érni az egyetemre). Megírtam már 40 tesztesetet – ez majdnem ezer sor kód, ezek segítségével több hibát is kijavítottam a tesztelt kódrészben. De tényleg. Futott minden. Amikor a kolléga közli velem, hogy a teszteseteim egy része meghal, és ez hazavágja az egész adatbázist. Nálam persze semmi ilyesmi. Némi kísérletezés után kiderül, a gond az, hogy a Windows nem eszi meg a megoldást. Pont. Akkor mutassuk be Macen. De Macen meg egyes Windowson megírt tesztesetek nem futnak. 😕

A hibát nem sikerült megoldani… Mindenesetre kezdem azt hinni, hogy olyan, hogy platformfüggetlen nem létezik. A Java legalábbis biztosan nem az. Például az AbevJava máshogy megy Windows-on, mint Linuxon vagy OSX-en. És ez a mostani hiba is megerősíti ezt az elképzelést. Azt, hogy mi lehet a hibás, csak tippelni tudom. Van egy elszúrt (értsd: feleslegesen túlbonyolított) entitáshalmazunk, van egy toplinkünk mysql adatbázishoz csatlakoztatva, van alatta oprendszer, OSGi konténer, stb. stb. stb. Erre már csak Murphyt idézném zárógondolatként:

  1. A bonyolult rendszerek hajlamosak a bonyolult meghibásodásokra.
  2. Ezzel szemben az egyszerű rendszerek is hajlamosak a bonyolult meghibásodásokra.