Kipróbáltam a 6-os netbeans preview-jét, de előbb egy kis történelem.
Annak idején JBuilder-rel kezdtem, majd NetBeans-re váltottam, mert ingyenes, teljesen java, platformfüggetlen és frankó volt. Aztán a munkatársaim ajánlották az Eclipse-et, mert látták hogy a NetBeans-szel kicsit döcög a gépem és mindig egyszerűbb szoftvert cserélni, mint hardvert bővíteni. (Nem azért egyszerűbb szoftvert cserélni, mert nehéz beletenni a gépbe plusz X mega RAM-ot, hanem mert ezt meg is kell szerezni valahonnan, el kell menni érte, szét kell szedni a gépet (ami kockázat) és fennáll a veszély, hogy a többieknek is hirtelen szükségük lesz bővítésre.) Tehát igaz hogy az Eclipse nem full java és nem teljesen platformfüggetlen, de kevesebb memóriát igényelt és ezért az alkalmazásváltások nem okoztak nagy szürke képernyőket pár másodpercig. Döcögős volt az átállás, de most (pár évre rá) már teljesen megszoktam és megszerettem. Néhány projektben nem is tudnánk mást használni, mert erre vannak meg azok a pluginek amik nekünk kellenek.
Mostanában nagyon nyomják a Netbeans-t. A Sun konferencián is külön előadást kapott (Roumen volt az előadó). Minden elképzelhető dolgot beleintegrálnak a MIDP grafikus GUI szerkesztőtől kezdve a Ruby támogatáson és a JSF GUI szerkesztőn keresztül a JBI-ig. Csak azt nem tudom hogy a fejlesztők hány százalékának van ezekre így együtt szüksége. Valószínűleg 0, szóval a dolog inkább a marketingnek szól.
Ha megnézem a hamarosan megjelenő Eclipse 3.3-as feature listáját, akkor pedig csupa csip-csup dolgokat látok, amiket valószínűleg észre sem vennék egyébként, de kódolás közben igazán hasznos lehet egyik-másik.
Egy éve volt szerencsém a Sun Java Sun Enterprise 8-hoz ami a Netbeans-ra épül és nem dobtam hátast tőle -konkrétan egy nagy rakás szerencsétlenség volt, úgyhogy talán némi szkepticizmussal vágtam bele a 6-os preview kipróbálásába.
Az installálás és az indítás oké. Mellesleg közben kicseréltem alatta a Java-t 5-ösről 6-osra és ezután nem volt hajlandó elindulni, a beállítást pedig nem tudtam megtalálni, tehát gyorsan újrainstalláltam.
Úgy gondoltam hogy kipróbálom a MIDP alkalmazásfejlesztőt -úgyis most vettem egy frankó Nokia 6300-ast, csinálok rá valami kis progit. Első körben a flow diagram nagyon meggyőző, csak amikor szaporodnak a képernyők (4 fölé) akkor már nem nagyon lehet őket értelmesen elhelyezni. Az összekötő vonalak mindig a képernyő ugyanazon (jobb) oldaláról indulnak és ugyanazon (bal) oldalára érkeznek, ezért max egy wizard szerű képernyő flow-t lehetne belőle szépen összerakni. Bizonyos command-okhoz tartozó vonalak meg sem jelennek. A képernyőszerkesztő nagyjából oké. A generált kód -mint mindig- hagy maga után kívánnivalót. A NetBeans sajátossága, hogy a generált kódba nem enged belenyúlni, nem engedi szerkeszteni. Mindenhol lazy inicializálást használtam, ami azt jelenti hogy csak akkor hozza létre a kontrollt ha szükség van rá és ha már létrehozta, később azt a példányt használja (singleton pattern). Viszont nem tudtam berakni semmi közös részre azokat a kódrészeket, amik a kontroll egyéb tulajdonságait megváltoztatnák másodszori és többedszeri megjelenítéseknél. Tehát minden egyes helyre be kellett tenni a kontroll megjelenítés után, és ez csúnya. Pl. ha egy képernyőre öt helyről lehet bemenni, akkor öt helyre kellett betenni a képernyőt friss adatokkal feltöltő kódrész hívását.
A kódszerkesztő talán azért tűnik szokatlannak, mert nagyon a kezemben vannak már az Eclipse shortcut-jai, de néhány kódkiegészítés azért mellen ütött. Eclipse-ben statikus metódusba eleve nem lehet beírni a "this" referenciát, mert aláhúzza hibának. NB-ben be lehet írni, sőt felajánlja utána a statikus metódusokat is (ctrl+space), amiket ha kiválasztok persze már fordítási hibát jelez. Ha kivételt dobó kódrészt akarok try catch -csel körbevenni és többféle exception-t is el kell kapni, amelyek esetleg egymás leszármazottai, a catch blokkokat néha rossz sorrendben teszi ki, emiatt szintén fordítási hiba keletkezik. Közben a try catch-en belüli kódot is átírja úgy, hogy kiírja az osztályok nevét a teljes package névvel függetlenül attól, hogy az import megvan. Még egy refaktorolási diszkrepanciával találkoztam amikor véletlenül sikerült azonos nevű osztályokat kialakítanom különböző csomagban. Utána fél óráig kellett böngésznem a kódot hogy visszacsináljam. Tehát a kódszerkesztő, kódkiegészítő, refaktorolós rész leírta magát nálam.
Még a buildelésről pár szó: a MIDP projekt létrehozásánál a Netbeans megcsinált mindent ami egy ilyen projekthez kell, a buildelés pedig gyakorlatilag egy Ant script futtatásából áll. Ez szimpatikus. Az Ant script viszont nem fut valami gyorsan és az emulátor sem ugrik fel túl hirtelen (20 mp egy 2G RAM-os Centrinoval) de azért használhatónak titulálható.
Valamelyik Javaposse-ban hallgattam, hogy az Eclipse inkább hackelésre, kódvarázslásra jó, a Netbeans pedig prototípusok gyors összedobálására. Maximálisan egyetértek. Végszónak annyi, hogy ismét az a benyomásom mint az SJSE8-nál, hogy még mindig kicsit összetákolt dologgal találkoztam, de már sokkal jobb, és kíváncsian várom az igazi 6-os verziót. Hajrá Prága!
2007-06-26
Netbeans 6 pre kipróba
2007-05-09
Paláver (a.k.a Java User Meeting)
Volt egy összeröffenés a Victor Hugo utcában, amit a javaforum-on szerveztek össze. Néhány előadás 7-től 10-ig este, nagyon hasznos volt. Igazából leírták róla páran amit akartak és amivel nagyrészt egyet is értek, úgyhogy itt vannak a linkek:
2007-04-04
jTDS JDBC Driver
Nemrégiben egy Microsoft SQL szerverrel üzemelő java webalkalmazásban belefutottam egy-két problémába. Eredetileg az MS-ről letöltött JDBC drivert használtam DataSource-ba ágyazva, ami nagyjából működött is. Az egyik nagy hiányosság volt, hogy ha a DataSource elvesztette a kapcsolatot az adatbázissal, nem állította helyre automatikusan.
Próbáltam letölteni egy frissebb verziót és kénytelen voltam installálni, (ami azt jelentette, hogy a Start menümbe is belepiszkított) de a frisebb verzió sem reconnect-ált.
Hosszas keresés után sem jutottam eredményre, nem találtam auto reconnect paraméterezhetőséget, vagy amit találtam az nem működött.
Valahol viszont találtam egy linket a jTDS-re, ami egy 100% javaban írt LGPL-es MS SQL szerverhez és Sybase-hez kapcsolható JDBC 3.0 driver. Nagyon jól használható a doksija, egyszerű a telepítése (nem kell telepíteni, csak a jar-t kell bepottyantani valahova).
Be is izzítottam és azóta boldogan fut a webalkalmazás a jTDS-sel, reconnect-ál ha az adatbázis szerver bukfencezik egyet.
2007-03-22
Oracle java tárolt eljárások, múltidézés: jdk1.3
Oracle-ben lehetséges az adatbázisszerverre feltöltött java programokat tárolt eljárásként futtatni. Ezzel a feature-rel, valamint az Oracle 10g és 9.2 ehhez kapcsolódó diszkrepanciáival találkoztam. A google-n "Oracle loadjava" kulcsszavakkal kitűnő cikkeket lehet keresni, amelyek elmagyarázzák a dolog lényegét, úgyhogy ezt nem részletezem, csak dióhéjban a lényeg:
Ha valami ok folytán olyan logika végrehajtására van szükség adatbázisban lévő adatokkal, amit tárolt eljárással nem lehet megoldani (pl. bonyolultabb számítások), a külső számítás használata pedig előnytelen, a java tárolt eljárás hívása egy jó módszer lehet. A felhasznált java osztályokat vagy jar fájlokat először be kell tölteni az adatbázisba az adatbázisszerver bin könyvtárában lévő loadjava parancssori eszközzel vagy máshogy (google). A java osztályokon belül a szokásos módon JDBC-n keresztül érhető el az adatbázis és a teljes standard java API használható, plusz azok a könyvtárak amiket feltöltünk. A java osztályok metódusai wrapper függvényeken keresztül érhetőek el, amiket ugyanúgy lehet hívni mint a tárolt eljárásokat, akár triggerből is. A wrapper függvény tartalmazza a hívandó java osztályt és a metódust a teljes szignatúrával. A metódusnak akár Clob-ok is átadhatóak paraméterként.
És most pár probléma / érdekesség amivel találkoztam:
- Az Oracle 10g Express Edition nem támogatja ezt a feature-t, csak a Standard Edition vagy fölfelé.
- Az Oracle 10g java1.4-et használ, az Oracle 9.2 pedig java1.3-at. Erre a fejlesztés során gondolni kell. Nem néztem utána hogy ezeket le lehet-e cserélni, de az Oracle elég érdekesen áll a jdk-khoz. Ha például installálok egy adatbázisszervert, a path-ot átírja a saját jdk-jára ami felülvágja az eddig használt (újabb) jdk-mat, ha esetleg volt olyan.
- A loadjava parancssori eszköz az adatbázisszerverhez tartozik, tehát az adatbázisszervert tartalmazó gépen kell futtatni. (Jelenlegi tudásom szerint.)
- Oracle 9.2-nél a loadjava -nál nem működik a -thin opció, bár ez a működést nem befolyásolja, csak a driver kiválasztásánál van szerepe.
- Ha a loadjava-hoz megadjuk a -resolve opciót, a betöltés után végigellenőrzi a betöltött osztályokat. Ha nem adjuk meg ezt az opciót, az ellenőrzés az első futtatás során fog megtörténni. Amelyik osztályokkal gond van, vagy nem történt meg rájuk az ellenőrzés, azok invalidok: select dbms_java.longname(object_name),uo.* from user_objects uo where object_type='JAVA CLASS' and trunc(created) = trunc(sysdate) and status = 'INVALID'
- Bizonyos osztályhibákat úgy kezel az Oracle, hogy lecseréli a bájtkódot egy exception dobásra. Ilyenkor egy warningot ad a konzolra (ORA-29552: verification warning), az osztályt viszont érvényesnek titulálja. Pl. ha olyan metódust akarunk hívni egy másik osztályból, ami nem létezik, akkor pontosan ez történik. A futáskor fog egy RuntimeException dobódni.
- Itt van még egy átfogó írás a témában.
- Az adatbázisszerveren belül tárolt eljárásokként a java kód párszor lassabban fut, mint normál módon, jre-vel futtatva. Ez nálam 4-5-szörös lassulást jelentett.
- Nem tudta futtatni az Ant-ot, mert az már újabb jre-t igényel. Az ant-futtatáshoz explicite meg kellett adni egy újabb jre-t.
- Ugyanígy a JUnit tesztesetekkel, meg kellett adni explicite egy újabb jre-t. Ez mégegy érv amellett, hogy a JUnit teszteket érdemes különálló projektbe rakni. Korántsem biztos, hogy a tesztesetek ugyanabban a környezetben futnak, mint a tesztelendő projekt.
- A build.xml -ben a javac targetnél nem fogadta el a target="1.2", source="1.3" opciókat, hanem az executable megadásával tudtam megmondani, hogy melyik jdk-ból használja a javac-ot.
- Találkoztam olyan kódrészekkel, amelyek 1.4-es és 1.3-as java-ban is értelmesen néznek ki, viszont az 1.4-es és 1.3-as fordító mást fordít belőle. Pl.:
StringBuffer sb1 = new StringBuffer();
StringBuffer sb2 = new StringBuffer();
sb1.append(sb2);
Java 1.4-ben van StringBuffer.append(StringBuffer) metódus, tehát egy 1.4-es fordító ezt fogja fordítani. Az 1.3-as java fordító viszont a StringBuffer.append(Object) metódust fogja alkalmazni. Hiába azonos a forráskód, 1.4-essel fordítva nem fog futni 1.3-as java-ban, mert nem fogja találni a StringBuffer.append(StringBuffer) metódust. - Azzal is szembesültem, hogy az 1.4-es java-ba már rengeteg dolgot beletettek az 1.3-hoz képest, pl. az XML-lel kapcsolatos csomagokat. Sokat kellett találgatni, hogy mi is nem volt még akkor benne? Szerencsére a jdom -nál amit használtam jól le volt írva, hogy a jdk1.3-ast és 1.4-et használóknak milyen könyvtárakat kell még feltölteniük.
2007-02-20
Spring MVC tapasztalatok
Megcsináltam egy teljes webalkalmazást Spring MVC-vel és Acegi Security-vel pár hét alatt. Az a véleményem, hogy ez a páros régi kérés-válasz alapú webalkalmazások készítésére nagyjából jó, de modernebb Ajax-os vastagkliensekre már nem. Ahogy ajax-os trükkök kerülnek kilátásba, egyre közelebb érzek egy komplexitásrobbanást, drótozások és hibalehetőségek tömkelegét. Nem jó hogy controllerekker és view-mappelésekkel kell szórakozni amikor a B logikával kellene foglalkozni.
Az Acegi Security mondhatni bevált, bár kicsit bonyolult a konfigurációja a Spring-en belül. (Bonyolult életet lehelni bele és megérteni. Amikor alapvetően működik, onnantól már oké.) A programozása viszont kifejezetten kényelmes. Jó ötlet a ThreadLocal változók használata. Mivel open source, nem gond bővítmények írása sem.
Mit is kell csinálnom, ha egy olyan alap funkciót akarok létrehozni, hogy egy combobox változása szerver interakció után változást okozzon a képernyőn a kliensben. Ez kb. egy kétsoros kód kéne hogy legyen. Ellenben:
- Rá kell tenni a combobox onChange eseménykezelőjére egy javascript event-et. Célszerű dojo-val elküldeni a szervernek.
- Controllert mappelni a http kérésre, megcsinálni a logikát ami a választ adja.
- Megcsinálni a választ, ami lehet egy egyszerű jsp lap(részlet).
- A képernyőn csinálni egy div-et ahova a választ be lehet illeszteni.
Persze szép volt, jó volt, jó alkalmazás lett.
