2011. augusztus 24., szerda

Halálcsillag Design Pattern - implementációk

Halálcsillag Brno felett
Tényleg nagyon gyakran elmondhattam ezt a halálcsillag dolgot a régi munkahelyemen. Ezt kaptam ajándékba: egy kicsi halálcsillag. A képen éppen Brno felett lebeg.
Köszi :-)

Gyárlátogatás: konfiguráció

A következő dolog, amit mindenki totál máshogy csinál a java/j2ee/jee környezetben az a szoftver konfigurációja. A téma sajnos nem annyira "egyszerű" mint az a képesség, hogy a verziószámot meg tudjad mondani, így hát igen szép számban van rá megoldás. Ezek a megoldások még csak nem is diszjunktak, simán átfedik egymást. Egészen biztos, hogy nincsen két ugyanúgy konfigurálható java szoftver. Illetve csak ha pont ugyanaz az ember írta mondjuk 1 héten belül. Szóval oltári buhera zajlik a téren. Mint mindig.

Elvárások a konfigurációval kapcsolatban

Ha én lennék az admin, most így fejből ezeket várnám el az appoktól és fejlesztőiktől:

  1. Legalább az minor release-k között őrizze meg integrítását. Azaz a 1.0-hoz bütykölt konfig had menjen már el a 1.0.1-gyel is.
  2. Ne az alkalmazásba legyen belebuherálva (WEB-INF/classes, satöbbi), hogy amikor az upgrade során rm -rf paranccsal kezeled a régi verziót (ja, backup, csókolom!) ne vesszen el a régi bugokkal együt a konfiguráció is. Legalább a környezet-specifikus konfiguráció ne az appban legyen!

Mint fejlesztő, nagyon szeretem azt, ha nem kell a fél életemet a fejlesztői környezet összebuherálásával töltenem. Értelmes alapértékek (akár pl egy beágyazott DB), könnyű felülcsűrhetőség.
Illetve ezt csak nagyon szeretném, baromi ritka az ilyen. Remélem nem úgy képzelitek el a halálcsillag építését, hogy kiszedik a dobozból, bekapcsolják és működik.

Plain Property file-ok

A property fileok ősi java feature és a legtöbb rendszer még mindig felhasználja a konfiguráció tárolására. Ezzel persze nem rossz dolog. Máig ez a legtöbb konfigurációs megoldás alapja, de persze a tiszta és legalapabb formája az, amikor pl a konstruktorban megkapod a Properties ojjektumot magát és bányásszad ke belőle azt, ami köll. Volt egy ennél kicsit szofisztikáltabb megoldás, ami csak a teljes konfig egy részét passzolta oda... lényegtelen. Ezek tipikusan az IoC-nélküli rendszerek.

Á igen, IoC

Az IoC egy olyan ötlet volt, amiért jópárszor leégettem magam azzal hogy próbáltam megmagyarázni a főnökeimnek valamikor régen, és néha még mostanában is. Ötlet: "Do not call me, I will call you!" Azaz az IoC konténer majd beállítja neked a konfigot, összekapcsolja az ojjektumaidat, elindítja az appod ha kész, illetve elhasal ha nem sikerült (ez esetben az jó, hogy hülyeséggel nem indult el). Ebből eleinte még két faj létezett, az intrusive (pl Avalon) és a non-intrusive, tipikusan POJO jellegű. Az elöbbit mára csak CVS-múzumokban találod. Az utóbbiból se a spring volt persze az első, csak a legnépszerűbb. Volt még elötte picocontainer, nanocontainer, és már a fene se emlékszik mik. Ma Spring, Guice, és az EJB is sok inspirációt kölcsönzött a téren ezektől a projectektől. Vitatkozhatnánk róla, hogy eleget-e vagy sem, de igazából nem érdekelne.

Még itt szeretném megemlíteni azokat a böszme nagy XML fileokat amiket írunk az IoC frameworknek és együt jönnek az appal szinte minden verzióban kicsit úthuzalozva és átkombinálva. Szerintem ne akarjátok, hogy az admin ebben matasson! Az merge-hell! Sírás-rívás, jajjveszék, rollback, cancel, és hasonló kulcsszavak jutnak róla eszembe. (Egy külsős fejlesztő szívatott ilyennel éveken át)

Spring, PropertyOverrideConfigurer és PropertyPlaceholderConfigurer

Ezt a két dolgot igazából nagyon szerettem a spring-ben. Ez megoldás arra, hogy az appcontext-ben összeállított konfigurációt felülcsűrd egy property file tartalmával. Tehát ide lehet tenni az X-et ennek én nagy rajongója vagyok még most is. A különbség a két dolog lehetőség között, hogy az override configurerrel mindent felül lehet csapni (söt, olyat is ami az appcontextben nem is volt benne), míg a placeholder configurer csak a placeholdereket helyettesíti be. Azért gyanús, hogy az előre kigondoltakon kívül jól jöhet, ha időnként más beállításokat is megváltoztathatsz. Természetesen az a placeholder configurerben viszont szimpatikus, hogy az éles rendszerektől megköveteli az előre definiált placeholderek értékének beállítását, különben nem indul el. Ugyanakkor még mindig jobban szeretem, ha a rendszer értelmes defaultokkal jön, és bármít felül lehet benne csapni.

Mindkettőnek van némi hiányossága. Pl listákat és map-eket nem kezelnek. Na erre mindenkitől láttam valami saját szintaxist és saját megoldást.

Jó, de hova?

Azt a kérdést, hogy hova tegye a rendszergizda a konfig fileokat, illetve az app hol keresse, az izlés és hitviták tárgya. Volt egy melóhelyem, ahol a unix filerendszerhez kellett igazítani a struktúrát. A konfig az etc-be, a program kód meg a usr-be (usr-be?!?!?!), felhasználókkal kapcsolatos dolgok talán a home-ba, adatok a var-ba. Igen, még mindig java szoftverfejlesztésről van szó. Vicces volt egész addig amíg rá nem jöttem hogy komolyan gondolják. Utánna már nem :-D

Mindenesetre a legtöbb program egyszerűen csak a classpath-on keresi a konfigját, többnyire {appnév}.properties alatt. Ez talán a legértelmesebb dolog, de minden appszerveren máshova kell dobni, hogy a classpath alatt legyen. Had sírjon aki migrálni merészel!

JMX!

A JMX még belerúg ebbe a témába kicsit. JMX-en keresztül beállíthatod az alkalmazásod konfigurációját, meghívhatsz rajta maintenance metódusokat, stb. A JMX király dolog, de arról nem gondoskodik, hogy a container újraindítása utánra is megmaradjanak ezek a beállítások. Az az app gondja. Valószinúleg ez lehet az oka annak, hogy hibakeresés közben láttam csak JMX-et, konfiguráció beállításhoz soha. Nevezhették volna inkább java debugging extensionnak.

JNDI?

Ha már a container szolgáltatásainál tartunk. Sokat tűnődtem rajta, hogy a JNDI miért csak annyi lett, amennyi lett. Semmi mást nem csinálsz vele, csak java.sql.Datasource és java.mail.Session objektumot halászol ki belőle, többnyire hardcode-olt címről. Az innen kihalászott objektumok előre fel vannak konfigolva a környezet beállításaival: hol az adatbázis, milyen adatbázis, hány kapcsolatot nyithatok rá, satöbbi, hasonlóan az smtp szerverrel. Na jó, még arra is használjuk néha, hogy a LDAP szervereken kurkásszunk valamit. Ennyi?
Tehát akkor az adatbázis és SMTP eléréssel kapcsolatos infókat akkor ott tartjuk. A többit miért nem? És ha a többit nem ott, akkor azt miért? Nem lenne jobb egybe tartani?
Kipróbáltam pár appszervert, a GUI/web-es felületeken keresztül egyik sem volt hajlandó a fenti kettőtől eltérő ojjektumot elhelyezni a JNDI fában. Kézzel be lehet haxolni.

Adatbázis

Remélem mindenki érzi, hogy egy komoly robosztus ACID-compliant replikált és backupolt nagy teljesítményű, 24/7 365 felügyelt RDBMS a legrojszrojszabb hely a világon, ahova a konfigját az ember berakhatja. Szóval legkevésbé sem ritka, hogy az appok az adatbázisban tartják a konfigjukat. Akkor már csak az a kérdés, hogyan éred el az adatbázist, de ezt többnyire a JNDI megválaszolja.

Én nem érzem a késztetést :-) Csupán technikai oldalról, nem értem mi haszna van az ACID viselkedésnek akkor, amikor olyan adatokról van szó, ami csak akkor változik, amikor éppen bütyküljük a rendszert. Sokkal hasznosabb ha gyorsan és egyszerűen hozzá lehet férni, mindig. Továbbá nagyon nagyon szép ha pl valami verziókövetőben tárolhatjuk, hogy tudjuk ki buherált rajta és mit, mikor hogy nézett ki. Egy text-file sokkal szimpatikusabb. Na ezt talán inkáb oda kellett volna írnom a propertyfile-hoz. Na mindegy, úgyis elcsesztem már pár helyen ezt a cikket.

2011. augusztus 17., szerda

Gyárlátogatás: verziószám

Tipikus igény a szoftverekkel szemben, hogy meg tudják mondani a saját verziószámukat. Ez főleg azért kell, hogyha a kedves felhasználó meglát egy bogarat benne, meg tudja mondani, hogy melyik verzióban látta. Legalábbis hogy esélye legyen rá. Erre szedtem össze az általam eddig látott és használt megoldásokat, azzal együt hogy mi a tipikus elba**** velük kapcsolatban. Nemcsak hogy egyik sem tökéletes megoldás, de mindegyik szerintem elég töketlen. Persze a sajátját mindenki szereti :-)

Build script

Ez volt a leggyakoribb. Az ötlet annyi, hogy amikor buildelsz, akkor generáljon neked egy számot bele egy file-ba, amit valószinűleg besúvaszt utánna a classpath-ra. Ezt persze csak inkrementálgatni kell. Láttam olyat, hogy ez a file csak úgy "floating around" azaz akik release-t csináltak azok tudták a számozást, aztán volt olyan hogy visszakommitolták legalább időnként a verziókövetőbe. Ja még ezen belül is két különböző műfaj van, van aki verzió számot tart számon, van aki build számot. Szóval a kombinációk száma igen magas.
A tipikus elba:

  • Amikor nincs meg a file a classpathon, akkor valami törik
  • Elfelejted inkrementálni a build számot
  • Elfelejted a verziószámot bepakolni a verziókövetőbe, mielött tegelsz



Database, config

Olyat is láttam, hogy az emberek a konfigurációba, vagy gyakrabban az adatbázisba írják bele, hogy mennyi a szoftver verziószáma. Az egyébként tetszik, hogy az adatbázisban valahol benne legyen az, hogy milyen patcheket hajtottak végre rajta és milyen verzió satöbbi a jelenlegi schema, de akkor most az operátorra bíztuk, hogy felülbuherálja a verziószámot.
Elba:

  • Azon felül hogy anyukádat emlegetik közben, még rizikó tényező hogy az operátor valamikor visszacsinálja vagy átírja, vagy éppen ellenkezőleg: elfelejti átírni.
  • Az fenti elfelejtések simán ide is passzolnak

SVN-way


Ezt én találtam ki és hát primitív mint a szerzője: Csinálj egy osztályt pl Version néven, tegyél bele egy final static String mezőt, aminek az értéke legyen ennyi: "$HeadURL: http://svn.blf.hu/fubar/trunk/src/main/hu/blf/Version.java $", plusz egy metódust, ami fubar és az src közül kibányássza neked ami ott van: pl ennyi: StringUtils.substringBefore(StringUtils.substringAfter(version, "/fubar/"), "/src/"), ne felejtsd el a végén az svn property-k között a keywords-be beleírni azt hogy "HeadURL".
A build numebert nyilván hanyagolja. Csak azt adjuk oda bárkinek is, amit szépen betegeltünk.
Jó, a nyilvánvaló hátrányok elött felsorolnám hogy miért szerettem ezt:

  • Soha nem sikerült elszúrnom :) A Version osztály mindig valami értelmeset ad vissza. Pl azt hogy "trunk". A legdurvább elcseszés esetén semmit, de nem NullpointerException-t.
  • A release során simán meg lehet róla feledkezni. A release nálam ennyi: mvn release:prepare release:perform (így "howto release" manuált se írtam soha)
  • Ja és ez az egész substringes dolog csak a cicoma rajta, sima statikus text/html fileokkal is működhet, ha érti a felhasználód a HeadURL-t hogy mi az.
Akkor jöjjön a hátrány:
  • Totálisan SVN függő - azért volt ilyen a CVS-ben is, de arra már kiemlékszik
  • Az SVN-re meg most úgy fintorgunk mint a CVS-re úgy 6-7 évvel ezelött. Valahogy akkor jött ki az SVN, nem?
Még annyit a megoldás portolhatóságáról, hogy a git pl nemcsak hogy nem csinálja, de elvben is ellenzi. Linus Torvalds szerint írjál scriptet. Szerintem meg ... :-) Na mindegy, nekem ez nem tetszik, túlságosan könnyen elcseszhető. Meg bújja a git elba manuálját az, akinek nincs jobb szórakozása.

Ennyi... részemről

De kiváncsi lennék a ti tapasztalataitokra, linkeljétek vagy írjátok ide nyugodtan! Köszi előre is!

2011. augusztus 3., szerda

ping brno

No, messzemenőbb tapasztalatokat nem tudok mesélni a Red Hat-ről, tekintve hogy pár napja vagyok csak itt. Szóval első impressziók:
  • Rövid eligazítás után egyből kezembe nyomták a gépemet, egy ThinkPad-ot, amit magamban csak TankPad-nak nevezek. Elég izmos gép, nagy ram, 4 core, nagy vincsi. Dokking sztésön, extra képernyő, egy angol billentyűzetet is sikerült kukáznom. Hardwer-ügyileg soha nem voltam ilyen jól elátva.
  • Az már az első látogatásomkor lejött, hogy a régi munkahelyeimhez képest baró csendes az iroda. Engem mondjuk a zaj nem nagyon zavart sehol sem, de jónéhány régi munkatársam mondott fel a zaj miatt. Itt inkáb ilyen könyvtár jellegű a hangulat.
  • Minden gépen linux van, én újabban az eddig gyűlölt Gnome 3-at hajtom, lassan megszokom.
  • Van Ingyen Ebéd! Hétfőn gyümölcsök, amúgy kb folyamatosan műzli. Az egészséges táplálkozáson túl pl tegnap esti release partin volt sülthús és sör is.
  • Na igen, a technikai témák jobban pörögnek mindenképpen. Örülök neki, mert ezért jöttem ide. Sajnos tegnap kicsit el voltam havazva (és ez folytatódni látszik) de volt egy JBoss AS 7 release party.
  • Ehhez kb hozzá lehetek szokva, de hiába költöztem ide, majdnem mindenki remote.
  • Vannak viszont magyarok, rajtam kívül hárman. Még nem volt időm megkeresni mindenkit :-( Eléggé el vagyok havazva.
Egyébként a város:
  • Egy része ugyanolyan koszos büdös, mint Budapest. Cejl bizonyos szempontból még Budapestet is alulmúlja, nyóckerszerű rohadó belváros. A város többi része tele van építkezésekkel, az egész nő mint a gomba.
  • Zseniális a villamoshálózat. Meg olcsó is. A legdrágább jegy forintba átszámolva 250-270 ft között lehet, ezért egy órán át utazhatsz a városon keresztül ha jól értettem akárhány átszállással. A legolcsóbb jegy 90 forint körül van (8 CZK), ez csak 10 perces utakra elég. Remélem nem értettem félre semmit, ellenőrrel még nem találkoztam.
  • Ez a része, ahol mi vagyunk (Královó Pole) egész csinos, parkos, tele van különféle egyetemekkel és van egy hatalmas infópark
  • A táj szerintem bejön azoknak, akik szeretnek túrázni (az IT szakmában tipikus)
  • 10 évnyi Budapest után totálisan megdöbbentő, hogy ha a zebrához érek, megállnak az autók az úton, hogy átengedjenek.
  • A sör a legkevésbé sem érdekel, de amúgy a kaja, főleg a tejtermékek (ami az alap üzemanyagom) lényegesen olcsóbbak a hazainál.
  • A lakások és albérletek viszont marha drágák.