<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>jTechnics</title>
	
	<link>http://jtechnics.anzix.net</link>
	<description>Java 0-24</description>
	<lastBuildDate>Tue, 02 Mar 2010 20:09:30 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/jtechnics" /><feedburner:info uri="jtechnics" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>hg mq és a ci</title>
		<link>http://feedproxy.google.com/~r/jtechnics/~3/Nucj5KHc4wg/</link>
		<comments>http://jtechnics.anzix.net/2010/02/24/hg-mq-es-a-ci/#comments</comments>
		<pubDate>Wed, 24 Feb 2010 22:13:15 +0000</pubDate>
		<dc:creator>elek</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[hg]]></category>
		<category><![CDATA[mq]]></category>

		<guid isPermaLink="false">http://jtechnics.anzix.net/?p=382</guid>
		<description><![CDATA[UPDATE:  OMG, mennyire felületes voltam. hg help qinit, és ne is olvassátok tovább. Ez mindent megoldott.
A .hgrc-mbe egyretöbb extension szivárog be:
[extensions]
hgshelve=/home/elek/satupad/hgshelve/hgshelve.py
hgext.fetch=
hgext.rebase=
hgext.graphlog =
transplant =
hgext.color =
hgext.purge =
hgext.mq =
Az egyik legújabb játékom az MQ extension. Nagyon nagy vonalakban arról van szó, hogy a rendes changelog tetején még ül egy rakás patch (konkrét patch fájl gyűjtemény egy könyvtárban), [...]]]></description>
			<content:encoded><![CDATA[<p><strong>UPDATE: </strong> OMG, mennyire felületes voltam. hg help qinit, és ne is olvassátok tovább. Ez mindent megoldott.</p>
<p>A .hgrc-mbe egyretöbb extension szivárog be:</p>
<pre>[extensions]
hgshelve=/home/elek/satupad/hgshelve/hgshelve.py
hgext.fetch=
hgext.rebase=
hgext.graphlog =
transplant =
hgext.color =
hgext.purge =
hgext.mq =</pre>
<p>Az egyik legújabb játékom az MQ extension. Nagyon nagy vonalakban arról van szó, hogy a rendes changelog tetején még ül egy rakás patch (konkrét patch fájl gyűjtemény egy könyvtárban), amik bár külön álló fájlok, az mq extension a saját parancsaival úgy kezeli, mint a hg changelogon szánkáznál időben előre és hátra.</p>
<p>Két tipikus használata van. Egyrészt el lehet játszani, hogy pullozok regy public repositoryból, és csinálok néhány patchet. Amikor frissítik a public repositoryt, akkor a patcheken időben visszalépkedek, ekkor changesetek helyett csak patch fájlok lesznek belőlük, pullozok egyet, és megint előre lépkedek és applyolom a patcheket.</p>
<p>(Ez így leírva kicsit bonyolultnak tűnik, de ki kell egyszer próbálni, és akkor érthetővé válik, én se nagyon értettem, amíg nem kezdtem el használni.)</p>
<p>Egy másik felhasználási mód, amikor szerkeszteni akarok egy commitot. Ilyenkor convertálom a changeseteket patchekké, a patch fileban szerkesztem (akár a commit message-t is), majd vissza konvertálom a patch changeseteket rendessé. Természetesen fizikailag ezek már más changesetek lesznek, tehát nem érdemes akkor próbálkozni ezzel, ha már pusholtuk is a changeseteket.</p>
<p>És most a probléma. Alapvetően ezt csináltam</p>
<ol>
<li>leszedtem az aspectj maven plugin-t svnből és egy svn hg bridge-en keresztül hg-be konvertáltam</li>
<li>csináltam hozzá néhány patchet, hogy kicsit jobban működjön</li>
</ol>
<p>A patchet ilyenkor a .hg/patches alá kerülnek. Akinek ott vannak a patchek alatt az én fájljaim az tudja buildelni az én változatomat, kinek nincs, az nem. Mivel azt akarom, hogy más is lássa a változtatásokat, ezért a hg qinit -c parancsot használtam, ami a .hg/patches-ben inicializál egy másik hg repót, ahol verziózza a patcheket. (E nélkül a patchek csak nálam lokálisan lennének meg).</p>
<p>A proléma az, hogy a .hg/patches repó természetesen egy másik repó, mint ami a fő kódot tartalmazza, és innentől kezdve egy rendes buildhez (pl. a Hudsonon) nem elég hg clone-t mondanom, hanem a hg clone után még a .hg/patches-hez egy másik hg clone is kéne, amit ugye a Hudson nem fog megcsinálni nekem.</p>
<p>Azt csinálhatnám, hogy a patcheimet átalakítom rendes changesetté, csak ezt meg pont nem akarom, mert akkor elveszik pl. a patch neve mint információ, meg a következő SVN frissítéskor kicsit bonyolult lenne a helyzet.</p>
<img src="http://feeds.feedburner.com/~r/jtechnics/~4/Nucj5KHc4wg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jtechnics.anzix.net/2010/02/24/hg-mq-es-a-ci/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://jtechnics.anzix.net/2010/02/24/hg-mq-es-a-ci/</feedburner:origLink></item>
		<item>
		<title>Metamodellek</title>
		<link>http://feedproxy.google.com/~r/jtechnics/~3/VcHE-uAK4Og/</link>
		<comments>http://jtechnics.anzix.net/2010/01/31/metamodelek/#comments</comments>
		<pubDate>Sun, 31 Jan 2010 11:15:32 +0000</pubDate>
		<dc:creator>elek</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[jpa2]]></category>
		<category><![CDATA[liquidform]]></category>
		<category><![CDATA[metamodel]]></category>
		<category><![CDATA[mockito]]></category>

		<guid isPermaLink="false">http://jtechnics.anzix.net/?p=370</guid>
		<description><![CDATA[Néha hasznos lenne, hogy ha egy objektum struktúra felépítésére tudnék típusosan hivatkozni.
Nem találtam jobb nevet erre, mint a JPA 2.0 zsargonjából kölcsönzött Metamodel kifejezést, de talán egy példán keresztül világosabb lesz, mire gondolok. Tegyük fel hogy szeretnék egy Java Bean to Java Bean mapper-t, hasonlót a dozer-hez, csak egyrészt programmatikusan szeretném konfigurálni (nem XML-ből), másrészt [...]]]></description>
			<content:encoded><![CDATA[<p>Néha hasznos lenne, hogy ha egy objektum struktúra felépítésére tudnék típusosan hivatkozni.</p>
<p>Nem találtam jobb nevet erre, mint a JPA 2.0 zsargonjából kölcsönzött Metamodel kifejezést, de talán egy példán keresztül világosabb lesz, mire gondolok. Tegyük fel hogy szeretnék egy Java Bean to Java Bean mapper-t, hasonlót a <a href="http://dozer.sourceforge.net/">dozer</a>-hez, csak egyrészt programmatikusan szeretném konfigurálni (nem XML-ből), másrészt én akarom részletesen megmondani, hogy mit másoljon, és csak azt másolja, amit szeretnék. </p>
<p>Tegyük fel, hogy van egy managed JPA entitás struktúránk, amiből szeretnék egy detached változatot, de úgy, hogy én mondom meg, hogy az egyes objektum kapcsolatokból melyik legyen kifejtve és melyik ne. Ezt a vázolt mapper alkalmazással fogom elérni, belemondom, hogy melyik atribútuomkat másolja, és egy adott entitásból egy ugyanolyan detached állapotú osztályhierarchiát másol.</p>
<p>Hogy mit másol, azt megadhatom mondjuk Expression Language szerű kifejezéssekkel. Pl.:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">Mapper<span style="color: #339933;">&lt;</span>Partner<span style="color: #339933;">&gt;</span> m <span style="color: #339933;">=</span> MapperFactory.<span style="color: #006633;">create</span><span style="color: #009900;">&#40;</span>Partner.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
m.<span style="color: #006633;">config</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;partner.nev&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
m.<span style="color: #006633;">config</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;partner.cim.varos&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
Partner managed <span style="color: #339933;">=</span> ....
<span style="color: #006633;">Partner</span> detached <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Parner<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
m.<span style="color: #006633;">copy</span><span style="color: #009900;">&#40;</span>managed,detached<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>És itt szeretném elérni azt, hogy a 2. és a 3. sorban típusosan adhassam meg a másolási szabályokat.</p>
<p> Jelenleg két ötletem van erre:</p>
<p><strong>APT</strong></p>
<p>Az első az, amit a JPA2.0 is alkalmaz. Generálunk meta osztályokat mondjuk PartnerMeta, CimMeta, stb.néven, és azokba begeneráljuk a típusok leírását. Pl.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">Mapper<span style="color: #339933;">&lt;</span>Partner<span style="color: #339933;">&gt;</span> m <span style="color: #339933;">=</span> MapperFactory.<span style="color: #006633;">create</span><span style="color: #009900;">&#40;</span>Partner.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
m.<span style="color: #006633;">config</span><span style="color: #009900;">&#40;</span>PartnerMeta.<span style="color: #006633;">nev</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
m.<span style="color: #006633;">config</span><span style="color: #009900;">&#40;</span>PartnerMeta.<span style="color: #006633;">cim</span>.<span style="color: #006633;">varos</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>A JPA2 mondjuk Partner_-nek hívná  metamodel osztályt, és nem lenne rekurzív, tehát a Partner_.cim az nem egy Cim_ a JPA2-ben, ezért a fenti definíciót nem is tudnánk használni. Persze nem egy ördöngősség saját metamodelt kitalálni és az APT eszközzel viszonylag elegánsan lehet generálni ezeket az osztályokat (már ha beszélhetünk eleganciáról bármilyen generált kód esetében): Elég egy jól irányzott jar-t elhelyezni a fordítás idejű classpathba és már generálódnak is az osztályaink (lásd még SPI).</p>
<p>A JPA2 API-ját még nem használtam, de azért idemásolom az íze kedvéért egy <a href="http://weblogs.java.net/blog/lancea/archive/2009/12/15/generating-jpa-20-static-metamodel-classes-using-eclipselink-20-and-n">cikkből</a>, hogy hogy megy ez:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">Root<span style="color: #339933;">&lt;</span>Team<span style="color: #339933;">&gt;</span> team <span style="color: #339933;">=</span> cq2.<span style="color: #006633;">from</span><span style="color: #009900;">&#40;</span>Team.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
cq2.<span style="color: #006633;">select</span><span style="color: #009900;">&#40;</span>team.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span>Team_.<span style="color: #006633;">name</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">where</span><span style="color: #009900;">&#40;</span>cb.<span style="color: #006633;">like</span><span style="color: #009900;">&#40;</span>team.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span>Team_.<span style="color: #006633;">name</span><span style="color: #009900;">&#41;</span>, <span style="color: #0000ff;">&quot;Longfellow%&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p><strong>cglib</strong></p>
<p>A másik megoldás a futás idejű byte-code generáláshoz vezet. Ezt csinálja pl. a <a href="http://code.google.com/p/liquidform/">liquidform</a>:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">Person p <span style="color: #339933;">=</span> LiquidForm.<span style="color: #006633;">use</span><span style="color: #009900;">&#40;</span>Person.<span style="color: #000000; font-weight: bold;">class</span>, <span style="color: #0000ff;">&quot;p&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003399;">List</span> people <span style="color: #339933;">=</span> em.<span style="color: #006633;">createQuery</span><span style="color: #009900;">&#40;</span>
    select<span style="color: #009900;">&#40;</span>p<span style="color: #009900;">&#41;</span>.<span style="color: #006633;">from</span><span style="color: #009900;">&#40;</span>Person.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">as</span><span style="color: #009900;">&#40;</span>p<span style="color: #009900;">&#41;</span>.<span style="color: #006633;">where</span><span style="color: #009900;">&#40;</span>like<span style="color: #009900;">&#40;</span>p.<span style="color: #006633;">getSurname</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, <span style="color: #0000ff;">&quot;Smith%&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    .<span style="color: #006633;">getResultList</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>és a <a href="http://mockito.org/">Mockito</a>:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">Partner partner <span style="color: #339933;">=</span> mock<span style="color: #009900;">&#40;</span>Partner.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
when<span style="color: #009900;">&#40;</span>partner.<span style="color: #006633;">getNev</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">thenReturn</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;valami&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
assertEquals<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;valami&quot;</span>,partner.<span style="color: #006633;">getNev</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Látható, hogy egyes függvények paraméter gyanánt egy függvényhívást kapnak (pl. partner.getNev()) és nem a függvény hívás visszatérési értéke az érdekes, hanem maga a hívás, mintha egy metamodel egy elemét adnánk meg.</p>
<p>De hogy lehetséges ez? Nem tudom megállni, hogy ne <a href="http://monkeyisland.pl/2008/12/09/more-of-devoxx-more-on-interfaces/">idézzem</a> a Mockito szerőjét <a href="http://monkeyisland.pl">Szczepan Faber</a>-t:</p>
<blockquote><p>
&#8230;I was asked if Mockito is able to mock concrete classes? The answer is yes, Mockito doesn’t care if you mock an interface or a class. Mockito can do it thanks to primordial voodoo magic only ancient shamans understand these days (you guessed right – it’s the cglib library).
</p></blockquote>
<p>A <a href="http://cglib.sourceforge.net/">cglib</a> egy futási idejű bytecode generátor, ami az <a href="http://asm.ow2.org/">ASM</a> nevű bytecode manipulátort használja. Gyakorlatilag proxy szerű objektumokat tudunk vele létrehozni, amire mi mondhatjuk meg, hogy az egyes metódusok mit csináljanak. Mindkét megoldás úgy kezdődött, hogy csináltunk egy saját Partner osztályt a Mockito.mock vagy Liquidbase.use factory-val. Na ez az osztály már nem egy rendes Partner, hanem a memóriában összerakott saját bytecode-ból áll.</p>
<p>A mockito ebbe a bytecode-ba azt írja bele, hogy egy ThreadLocal polcra tedd el az adott hívás tényét (pl. partner.getNev meghívodott). Aztán a when metódus már meg se nézi milyen paramétert kapott (partner.getNev() visszatérési értékét), hanem erről a polcról megnézi, hogy épp mi futott le, és ezért már tudja, hogy amikor a mockolt osztályon legközelebb meghívódik a getNev(), akkor mit kell visszaadni. (A when metódus természetesen később hívódik meg, mint a partner.getNev(), mert előszőr a when argumentumait kell kiértékelni).</p>
<p>A liquidform ennél kicsit egyszerűbbet utat választott. A partner.getNev() meghívásakor ő is feljegyzi, hogy milyen hívás történik éppen, és visszaad egy visszatérési típusnak megfelelő objektumot, de előszőr egy globális Map-ben a kettőt összerendelni. A like(p.getNev(), &#8220;Smith%&#8221;) metódust ezért érdeklik a visszatérési értékek, mert ez alapján megkeresi, hogy a Map-ben van-e rá bejegyzés, és ha van, akkor onnan kimatekolja, hogy a p.nev értéket kell berakni majd String szinten a készülő Querybe.</p>
<p>A liquidform megoldásának azonban van egy nagy hátránya: nem tud primitív típusokat kezelni. Mivel a Map-ben létező objektum referenciákra tudja megmondani az elérési utat, ezért egy visszaadott long értékkel nem tud mit kezelni. Persze meg lehetne a liquidformot is okosítani a Mockito módszerével, de akkor egy másik  problémába ütközünk. A like(p.getNev(), &#8220;Smith%&#8221;) híváskor a polcon az szerepel, hogy egy pszeudó hívás érkezett a bytecode lekvárunkba, aki ezt gondosan feljegyezte. Majd ez után kapunk két String paramétert. Hogy melyik String paramétert kell feloldani a polcunkon lévő hívási információból, azt csak akkor tudnánk megmondani, hogy ha egy kitűntetett String értéket lefoglalnánk annak a jelzésére, hogy az a visszatérési érték nem számít, ehelyett használd a polcon lévő hívási információt. Másik lehetőség, hogy ha a paraméterek minden esetben felcserélhetők, akkor azt mondjuk, hogy a metamodeles hívás mindig az első kell, hogy legyen.</p>
<p>Hát itt tartok éppen a gondolataimban.</p>
<img src="http://feeds.feedburner.com/~r/jtechnics/~4/VcHE-uAK4Og" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jtechnics.anzix.net/2010/01/31/metamodelek/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://jtechnics.anzix.net/2010/01/31/metamodelek/</feedburner:origLink></item>
		<item>
		<title>Robotics</title>
		<link>http://feedproxy.google.com/~r/jtechnics/~3/7xLfrlt6YhU/</link>
		<comments>http://jtechnics.anzix.net/2010/01/24/robotics/#comments</comments>
		<pubDate>Sun, 24 Jan 2010 20:01:03 +0000</pubDate>
		<dc:creator>elek</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[robocode]]></category>
		<category><![CDATA[robot]]></category>
		<category><![CDATA[todo]]></category>

		<guid isPermaLink="false">http://jtechnics.anzix.net/?p=367</guid>
		<description><![CDATA[Ezt azóta meg akarom írni, amikor is több mint két hete olvastam egy sci-fi regényt: Zsoldos Péter: Ellenpont
A regény eleje táján derül ki az az alapfelállás, hogy egy távoli bolygón éppen robotok dolgoznak. A robotok jól specializáltak: van amelyik energiát tud termelni, van amelyik űrkutatásokat végez, van amelyik szöveget elemez, van amelyik koordinál. Minden robot [...]]]></description>
			<content:encoded><![CDATA[<p>Ezt azóta meg akarom írni, amikor is több mint két hete olvastam egy sci-fi regényt: <em><a href="http://mek.oszk.hu/01700/01704/01704.htm">Zsoldos Péter: Ellenpont</a></em></p>
<p>A regény eleje táján derül ki az az alapfelállás, hogy egy távoli bolygón éppen robotok dolgoznak. A robotok jól specializáltak: van amelyik energiát tud termelni, van amelyik űrkutatásokat végez, van amelyik szöveget elemez, van amelyik koordinál. Minden robot rendelkezik alrobotokkal, akik a nagy robotnak az inteligens karjai, az adott területért felelős központ irányítja őket (és persze közvetve a koordinátor). A robotok nagyon jól tudnak alkalmazkodni a környezetekhez, szép lassan agy előre írt program szerint kifejlesztik a gyártó sorokat és a technológiát, hogy eljussanak az űrön keresztül a szomszédos bolygókra.</p>
<p>A sztori persze folytatódik tovább, ami engem lenyűgözött, az az egész programozása. Egyszerűen annyira jól működik a dolog, hogy rögtön arra gondoltam, hogy jó lenne egy ilyet leprogramozni.</p>
<p>Valamikor a kilencvenesek években lehetett még, amikor a bátyám egy háziján keresztül ismerkedtem meg valamelyik egyetem projektjével, ahol Java focicsapatokat kellett programozni, majd ezek vívtak meg egymással. A játékosok egy interfacen keresztül látták a tér egy bizonyos szegletét, tudtak hanggal kommunikáli, és persze volt egy futtató környezet, ahol össze mérhették a tudásukat.</p>
<p>Most keresni kezdtem, de már nem nagyon találtam ennek a bajnokságnak. Csak a <a href="http://robocode.sourceforge.net/">robocode</a>-ra találtam rá, ahol tankokat kell irányítani egy térben (ahogy néztem a robocode nagy kalsszikus, sajnos nekem ez is kimaradt eddig), és aztán pont másnap olvastam egy <a href="http://queue.acm.org/icpc/">versenyről</a> hasonló témában. (El is kezdtem nézegetni, de most úgy látom, hogy a februári leadásig nem nagyon lesz már időm).</p>
<p>Jó lenne egyszer valami kis hazai háziverseny valami hasonlóból. És jó lenne egyszer komolyabban megismerkedni a neurális hálókkal, genetikus algoritmusokkal, és valami éles alkalmazást írni.</p>
<img src="http://feeds.feedburner.com/~r/jtechnics/~4/7xLfrlt6YhU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jtechnics.anzix.net/2010/01/24/robotics/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://jtechnics.anzix.net/2010/01/24/robotics/</feedburner:origLink></item>
		<item>
		<title>YAML</title>
		<link>http://feedproxy.google.com/~r/jtechnics/~3/9P-jHe5P-LM/</link>
		<comments>http://jtechnics.anzix.net/2009/12/15/yaml/#comments</comments>
		<pubDate>Tue, 15 Dec 2009 22:07:22 +0000</pubDate>
		<dc:creator>elek</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[db4o]]></category>
		<category><![CDATA[yaml]]></category>

		<guid isPermaLink="false">http://jtechnics.anzix.net/?p=365</guid>
		<description><![CDATA[Ahogy azt egy kedves szomszéd szokta monda, a törpök élete se mindig csak játék és mese. Ez különösen így van, ha a törpök db4o-t használnak. Ráadásul BigDecimal-t akarnak perzisztálni, amihez tartozó kiterjesztés csak a legújabb SNAPSHOT artifactokban van benne.
És valószínű ennek a folyománya az, ami rendszeresen szembe jön, egy exception (hová is lenne az életünk [...]]]></description>
			<content:encoded><![CDATA[<p>Ahogy azt egy kedves <a href="http://iwillworkforfood.blogspot.com/">szomszéd</a> szokta monda, a törpök élete se mindig csak játék és mese. Ez különösen így van, ha a törpök db4o-t használnak. Ráadásul BigDecimal-t akarnak perzisztálni, amihez tartozó kiterjesztés csak a legújabb SNAPSHOT artifactokban van benne.</p>
<p>És valószínű ennek a folyománya az, ami rendszeresen szembe jön, egy exception (hová is lenne az életünk exceptionök nélkül), ami valahogy így néz ki:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">Caused by<span style="color: #339933;">:</span> com.<span style="color: #006633;">db4o</span>.<span style="color: #006633;">ext</span>.<span style="color: #006633;">InvalidSlotException</span><span style="color: #339933;">:</span> id<span style="color: #339933;">:</span> <span style="color: #cc66cc;">5182</span>
        at com.<span style="color: #006633;">db4o</span>.<span style="color: #006633;">internal</span>.<span style="color: #006633;">marshall</span>.<span style="color: #006633;">UnmarshallingContext</span>.<span style="color: #006633;">invalidSlot</span><span style="color: #009900;">&#40;</span>UnmarshallingContext.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">81</span><span style="color: #009900;">&#41;</span>
        at com.<span style="color: #006633;">db4o</span>.<span style="color: #006633;">internal</span>.<span style="color: #006633;">marshall</span>.<span style="color: #006633;">UnmarshallingContext</span>.<span style="color: #006633;">read</span><span style="color: #009900;">&#40;</span>UnmarshallingContext.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">49</span><span style="color: #009900;">&#41;</span>
        at com.<span style="color: #006633;">db4o</span>.<span style="color: #006633;">internal</span>.<span style="color: #006633;">ObjectReference</span>.<span style="color: #006633;">read</span><span style="color: #009900;">&#40;</span>ObjectReference.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">281</span><span style="color: #009900;">&#41;</span>
        at com.<span style="color: #006633;">db4o</span>.<span style="color: #006633;">internal</span>.<span style="color: #006633;">ObjectReference</span>.<span style="color: #006633;">read</span><span style="color: #009900;">&#40;</span>ObjectReference.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">267</span><span style="color: #009900;">&#41;</span>
        at com.<span style="color: #006633;">db4o</span>.<span style="color: #006633;">internal</span>.<span style="color: #006633;">ObjectContainerBase</span>.<span style="color: #006633;">getHardObjectReferenceById</span><span style="color: #009900;">&#40;</span>ObjectContainerBase.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">956</span><span style="color: #009900;">&#41;</span>
        at com.<span style="color: #006633;">db4o</span>.<span style="color: #006633;">internal</span>.<span style="color: #006633;">marshall</span>.<span style="color: #006633;">AbstractReadContext</span>.<span style="color: #006633;">classMetadataForObjectId</span><span style="color: #009900;">&#40;</span>AbstractReadContext.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">85</span><span style="color: #009900;">&#41;</span>
        at com.<span style="color: #006633;">db4o</span>.<span style="color: #006633;">internal</span>.<span style="color: #006633;">marshall</span>.<span style="color: #006633;">AbstractReadContext</span>.<span style="color: #006633;">readObject</span><span style="color: #009900;">&#40;</span>AbstractReadContext.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">57</span><span style="color: #009900;">&#41;</span>
        at com.<span style="color: #006633;">db4o</span>.<span style="color: #006633;">internal</span>.<span style="color: #006633;">marshall</span>.<span style="color: #006633;">AbstractReadContext</span>.<span style="color: #006633;">readAtCurrentSeekPosition</span><span style="color: #009900;">&#40;</span>AbstractReadContext.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">46</span><span style="color: #009900;">&#41;</span>
        at com.<span style="color: #006633;">db4o</span>.<span style="color: #006633;">internal</span>.<span style="color: #006633;">OpenTypeHandler</span>.<span style="color: #006633;">read</span><span style="color: #009900;">&#40;</span>OpenTypeHandler.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">172</span><span style="color: #009900;">&#41;</span>
        at com.<span style="color: #006633;">db4o</span>.<span style="color: #006633;">internal</span>.<span style="color: #006633;">Handlers4</span>.<span style="color: #006633;">readValueType</span><span style="color: #009900;">&#40;</span>Handlers4.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">313</span><span style="color: #009900;">&#41;</span>
        at com.<span style="color: #006633;">db4o</span>.<span style="color: #006633;">internal</span>.<span style="color: #006633;">marshall</span>.<span style="color: #006633;">AbstractReadContext</span>.<span style="color: #006633;">readAtCurrentSeekPosition</span><span style="color: #009900;">&#40;</span>AbstractReadContext.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">48</span><span style="color: #009900;">&#41;</span></pre></div></div>

<p>És így tovább.</p>
<p>A hiba teljesen kiszámíthatatlanul, ugyanakkor jól reprodukálhatóan előjön. Pl. előveszek egy backup db4o file-t, megnyitom, teszek-veszek benne, lezárom az alkalmazást. A következő megnyitáskor már nem nyílik meg az adatbázis. Ha viszont ugyanazt a cselekmény sort újra végigviszem az elmentett db4o file-on ugyanúgy elszáll.</p>
<p>Tehát előszőr is ki kéne dobni a db4o-ból a BigDecimal-okat, amihez át kéne konvertálni a sémát. (Tegyük fel, hogy egy számlázó programban sosem fogok beleütközni a float korlátaiba). Ha nincs több BigDecimal mezőm, akkor használhatom a stabil db4o változatot. A másik meg, hogy szükségem lesz egy dump file formátumra. Egyrészt mivel féltem a már bent lévő adatokat, másrészt mert a mező típus konvertálás is nagy szívás egy meglévő db4o adatbázison, az egyik legegyszerűbb megoldás, hogy kidumpolom az adatbázist, majd típus refaktor után vissza.</p>
<p>Mi legyen a dump formátum. Kapásból a JAXB és Json jutnak eszembe, de ezek ahogy én tudom nem támogatják a referenciák kezelését. (Ha az objektum fában többszőr is előfordul ugyanaz az objektum, akkor visszatöltés után ne két, hanem csak egy objektum legyen, amire két helyről mutat referencia.</p>
<p>És itt jön kébe a <a href="http://en.wikipedia.org/wiki/Yaml">YAML</a>, amit pont tudja mindezt. </p>
<p>Előszőr a jYaml-t próbáltam, ami alapból egyszerűen működik, de régóta nem fejlesztik, és túlságosan is elnézően bánt a Yaml fájl hibáival. Aztán jött a <a href="http://code.google.com/p/snakeyaml/">Snakeyaml</a>. Ez már tette a dolgát mint a kisangyal.</p>
<p>Objektum mentése:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">Yaml yaml <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Yaml<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
yaml.<span style="color: #006633;">dump</span><span style="color: #009900;">&#40;</span>eztmentemel, <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">FileWriter</span><span style="color: #009900;">&#40;</span>file<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Objektum betöltése:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">Yaml yaml <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Yaml<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
DatabaseBackup backup <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>DatabaseBackup<span style="color: #009900;">&#41;</span> yaml.<span style="color: #006633;">load</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">FileInputStream</span><span style="color: #009900;">&#40;</span>file<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Maga a Yaml file meg valahogy így néz ki.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #339933;">!!</span>net.<span style="color: #006633;">anzix</span>.<span style="color: #006633;">nona</span>.<span style="color: #006633;">entity</span>.<span style="color: #006633;">DatabaseBackup</span>
felhasznalok<span style="color: #339933;">:</span>
<span style="color: #339933;">-</span> email<span style="color: #339933;">:</span> geza@hutira.<span style="color: #006633;">net</span>
  partner<span style="color: #339933;">:</span> <span style="color: #339933;">&amp;</span>id001
    partnerek<span style="color: #339933;">:</span>
    <span style="color: #339933;">-</span> <span style="color: #339933;">&amp;</span>id005
      partnerek<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span>
      szamlak<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span>
      torzs<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>adoszam<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">null</span>, bankszamlaSzam<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">null</span>, nev<span style="color: #339933;">:</span> Asztal kft., szamlaCim<span style="color: #339933;">:</span> Sötét út 20.,
        szamlaIrsz<span style="color: #339933;">:</span> <span style="color: #0000ff;">'1111'</span>, szamlaVaros<span style="color: #339933;">:</span> Budapest<span style="color: #009900;">&#125;</span>
      tulajdonos<span style="color: #339933;">:</span> <span style="color: #339933;">*</span>id001
....</pre></div></div>

<p>Itt már rögtön látszik is a referencia kezelése. A partner objektum instance azonosítója id001, és a partnerek listában található egyik partner tulajdonos mezője pont erre mutat vissza referenciával.</p>
<p>Mivel a db4o-val egy paranccsal elmenti az objektumfát, ezért 3 sorban tudok backupolni és visszatölteni a backupot, és a yaml file-t minimálisan módosítgatva (segít a nagyerejű grep parancs) még a típus konverziókat is sikerült viszonylag kis fájdalom árán meglépni.</p>
<p>Yaml a mi barátunk.</p>
<img src="http://feeds.feedburner.com/~r/jtechnics/~4/9P-jHe5P-LM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jtechnics.anzix.net/2009/12/15/yaml/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://jtechnics.anzix.net/2009/12/15/yaml/</feedburner:origLink></item>
		<item>
		<title>printStackTrace()</title>
		<link>http://feedproxy.google.com/~r/jtechnics/~3/zfLDTBv6dOE/</link>
		<comments>http://jtechnics.anzix.net/2009/12/07/printstacktrace/#comments</comments>
		<pubDate>Mon, 07 Dec 2009 14:42:48 +0000</pubDate>
		<dc:creator>elek</dc:creator>
				<category><![CDATA[exception]]></category>

		<guid isPermaLink="false">http://jtechnics.anzix.net/?p=360</guid>
		<description><![CDATA[Régóta tervezem, hogy indítok egy blogot, amiben csak exceptionok vannak. Egy munkahelyi csatorna már van, ahol ilyenekkel bombázom a kolegákat, nem mintha megoldást várnék tőlük, sőt. De úgy gondolom, hogy az exceptionok olyan méltatlanul mellőzőtt ipari képződmények, amik maguk egyszerűségében és monotonitásában valódi művészi értéket hordoznak.
Persze igazából egy stack trace megosztó social site lenne jó. [...]]]></description>
			<content:encoded><![CDATA[<p>Régóta tervezem, hogy indítok egy blogot, amiben csak exceptionok vannak. Egy munkahelyi csatorna már van, ahol ilyenekkel bombázom a kolegákat, nem mintha megoldást várnék tőlük, sőt. De úgy gondolom, hogy az exceptionok olyan méltatlanul mellőzőtt ipari képződmények, amik maguk egyszerűségében és monotonitásában valódi művészi értéket hordoznak.</p>
<p>Persze igazából egy stack trace megosztó social site lenne jó. Napi exception, hasonló exceptionnel barátkozó fejlesztők, ismerős exceptionok bejelölése, stb. </p>
<p>Amíg a nagyra törő álmok megvalósulnak, addig is itt egy kategória, ahová mintegy ilusztárcióként feltöltök egy-egy szép darabot.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">javax.<span style="color: #006633;">ejb</span>.<span style="color: #006633;">EJBException</span><span style="color: #339933;">:</span> The bean encountered a non<span style="color: #339933;">-</span>application exception<span style="color: #339933;">;</span> nested exception is<span style="color: #339933;">:</span>
java.<span style="color: #006633;">lang</span>.<span style="color: #006633;">reflect</span>.<span style="color: #003399;">UndeclaredThrowableException</span>
at org.<span style="color: #006633;">apache</span>.<span style="color: #006633;">openejb</span>.<span style="color: #006633;">core</span>.<span style="color: #006633;">ivm</span>.<span style="color: #006633;">BaseEjbProxyHandler</span>.<span style="color: #006633;">convertException</span><span style="color: #009900;">&#40;</span>BaseEjbProxyHandler.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">358</span><span style="color: #009900;">&#41;</span>
at org.<span style="color: #006633;">apache</span>.<span style="color: #006633;">openejb</span>.<span style="color: #006633;">core</span>.<span style="color: #006633;">ivm</span>.<span style="color: #006633;">BaseEjbProxyHandler</span>.<span style="color: #006633;">invoke</span><span style="color: #009900;">&#40;</span>BaseEjbProxyHandler.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">286</span><span style="color: #009900;">&#41;</span>
at $Proxy54.<span style="color: #006633;">existsValami</span><span style="color: #009900;">&#40;</span>Unknown Source<span style="color: #009900;">&#41;</span>
at hu.<span style="color: #006633;">xxx</span>.<span style="color: #006633;">xxx</span>.<span style="color: #006633;">xxx</span>.<span style="color: #006633;">ValamiServiceV1X0Test</span>.<span style="color: #006633;">testExistsValami</span><span style="color: #009900;">&#40;</span>ValamiServiceV1X0Test.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">59</span><span style="color: #009900;">&#41;</span>
at sun.<span style="color: #006633;">reflect</span>.<span style="color: #006633;">NativeMethodAccessorImpl</span>.<span style="color: #006633;">invoke0</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">Native</span> <span style="color: #003399;">Method</span><span style="color: #009900;">&#41;</span>
at sun.<span style="color: #006633;">reflect</span>.<span style="color: #006633;">NativeMethodAccessorImpl</span>.<span style="color: #006633;">invoke</span><span style="color: #009900;">&#40;</span>NativeMethodAccessorImpl.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">39</span><span style="color: #009900;">&#41;</span>
at sun.<span style="color: #006633;">reflect</span>.<span style="color: #006633;">DelegatingMethodAccessorImpl</span>.<span style="color: #006633;">invoke</span><span style="color: #009900;">&#40;</span>DelegatingMethodAccessorImpl.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">25</span><span style="color: #009900;">&#41;</span>
at java.<span style="color: #006633;">lang</span>.<span style="color: #006633;">reflect</span>.<span style="color: #003399;">Method</span>.<span style="color: #006633;">invoke</span><span style="color: #009900;">&#40;</span><span style="color: #003399;">Method</span>.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">597</span><span style="color: #009900;">&#41;</span>
at org.<span style="color: #006633;">junit</span>.<span style="color: #006633;">runners</span>.<span style="color: #006633;">model</span>.<span style="color: #006633;">FrameworkMethod</span>$1.<span style="color: #006633;">runReflectiveCall</span><span style="color: #009900;">&#40;</span>FrameworkMethod.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">44</span><span style="color: #009900;">&#41;</span>
at org.<span style="color: #006633;">junit</span>.<span style="color: #006633;">internal</span>.<span style="color: #006633;">runners</span>.<span style="color: #006633;">model</span>.<span style="color: #006633;">ReflectiveCallable</span>.<span style="color: #006633;">run</span><span style="color: #009900;">&#40;</span>ReflectiveCallable.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">15</span><span style="color: #009900;">&#41;</span>
at org.<span style="color: #006633;">junit</span>.<span style="color: #006633;">runners</span>.<span style="color: #006633;">model</span>.<span style="color: #006633;">FrameworkMethod</span>.<span style="color: #006633;">invokeExplosively</span><span style="color: #009900;">&#40;</span>FrameworkMethod.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">41</span><span style="color: #009900;">&#41;</span>
at org.<span style="color: #006633;">junit</span>.<span style="color: #006633;">internal</span>.<span style="color: #006633;">runners</span>.<span style="color: #006633;">statements</span>.<span style="color: #006633;">InvokeMethod</span>.<span style="color: #006633;">evaluate</span><span style="color: #009900;">&#40;</span>InvokeMethod.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">20</span><span style="color: #009900;">&#41;</span>
at org.<span style="color: #006633;">junit</span>.<span style="color: #006633;">internal</span>.<span style="color: #006633;">runners</span>.<span style="color: #006633;">statements</span>.<span style="color: #006633;">RunBefores</span>.<span style="color: #006633;">evaluate</span><span style="color: #009900;">&#40;</span>RunBefores.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">28</span><span style="color: #009900;">&#41;</span>
at org.<span style="color: #006633;">junit</span>.<span style="color: #006633;">internal</span>.<span style="color: #006633;">runners</span>.<span style="color: #006633;">statements</span>.<span style="color: #006633;">RunAfters</span>.<span style="color: #006633;">evaluate</span><span style="color: #009900;">&#40;</span>RunAfters.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">31</span><span style="color: #009900;">&#41;</span>
at org.<span style="color: #006633;">junit</span>.<span style="color: #006633;">runners</span>.<span style="color: #006633;">BlockJUnit4ClassRunner</span>.<span style="color: #006633;">runChild</span><span style="color: #009900;">&#40;</span>BlockJUnit4ClassRunner.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">73</span><span style="color: #009900;">&#41;</span>
at org.<span style="color: #006633;">junit</span>.<span style="color: #006633;">runners</span>.<span style="color: #006633;">BlockJUnit4ClassRunner</span>.<span style="color: #006633;">runChild</span><span style="color: #009900;">&#40;</span>BlockJUnit4ClassRunner.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">46</span><span style="color: #009900;">&#41;</span>
at org.<span style="color: #006633;">junit</span>.<span style="color: #006633;">runners</span>.<span style="color: #006633;">ParentRunner</span>.<span style="color: #006633;">runChildren</span><span style="color: #009900;">&#40;</span>ParentRunner.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">180</span><span style="color: #009900;">&#41;</span>
at org.<span style="color: #006633;">junit</span>.<span style="color: #006633;">runners</span>.<span style="color: #006633;">ParentRunner</span>.<span style="color: #006633;">access</span>$000<span style="color: #009900;">&#40;</span>ParentRunner.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">41</span><span style="color: #009900;">&#41;</span>
at org.<span style="color: #006633;">junit</span>.<span style="color: #006633;">runners</span>.<span style="color: #006633;">ParentRunner</span>$1.<span style="color: #006633;">evaluate</span><span style="color: #009900;">&#40;</span>ParentRunner.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">173</span><span style="color: #009900;">&#41;</span>
at org.<span style="color: #006633;">junit</span>.<span style="color: #006633;">internal</span>.<span style="color: #006633;">runners</span>.<span style="color: #006633;">statements</span>.<span style="color: #006633;">RunBefores</span>.<span style="color: #006633;">evaluate</span><span style="color: #009900;">&#40;</span>RunBefores.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">28</span><span style="color: #009900;">&#41;</span>
at org.<span style="color: #006633;">junit</span>.<span style="color: #006633;">internal</span>.<span style="color: #006633;">runners</span>.<span style="color: #006633;">statements</span>.<span style="color: #006633;">RunAfters</span>.<span style="color: #006633;">evaluate</span><span style="color: #009900;">&#40;</span>RunAfters.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">31</span><span style="color: #009900;">&#41;</span>
at org.<span style="color: #006633;">junit</span>.<span style="color: #006633;">runners</span>.<span style="color: #006633;">ParentRunner</span>.<span style="color: #006633;">run</span><span style="color: #009900;">&#40;</span>ParentRunner.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">220</span><span style="color: #009900;">&#41;</span>
at org.<span style="color: #006633;">apache</span>.<span style="color: #006633;">maven</span>.<span style="color: #006633;">surefire</span>.<span style="color: #006633;">junit4</span>.<span style="color: #006633;">JUnit4TestSet</span>.<span style="color: #006633;">execute</span><span style="color: #009900;">&#40;</span>JUnit4TestSet.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">62</span><span style="color: #009900;">&#41;</span>
at org.<span style="color: #006633;">apache</span>.<span style="color: #006633;">maven</span>.<span style="color: #006633;">surefire</span>.<span style="color: #006633;">suite</span>.<span style="color: #006633;">AbstractDirectoryTestSuite</span>.<span style="color: #006633;">executeTestSet</span><span style="color: #009900;">&#40;</span>AbstractDirectoryTestSuite.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">140</span><span style="color: #009900;">&#41;</span>
at org.<span style="color: #006633;">apache</span>.<span style="color: #006633;">maven</span>.<span style="color: #006633;">surefire</span>.<span style="color: #006633;">suite</span>.<span style="color: #006633;">AbstractDirectoryTestSuite</span>.<span style="color: #006633;">execute</span><span style="color: #009900;">&#40;</span>AbstractDirectoryTestSuite.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">165</span><span style="color: #009900;">&#41;</span>
at org.<span style="color: #006633;">apache</span>.<span style="color: #006633;">maven</span>.<span style="color: #006633;">surefire</span>.<span style="color: #006633;">Surefire</span>.<span style="color: #006633;">run</span><span style="color: #009900;">&#40;</span>Surefire.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">107</span><span style="color: #009900;">&#41;</span>
at sun.<span style="color: #006633;">reflect</span>.<span style="color: #006633;">NativeMethodAccessorImpl</span>.<span style="color: #006633;">invoke0</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">Native</span> <span style="color: #003399;">Method</span><span style="color: #009900;">&#41;</span>
at sun.<span style="color: #006633;">reflect</span>.<span style="color: #006633;">NativeMethodAccessorImpl</span>.<span style="color: #006633;">invoke</span><span style="color: #009900;">&#40;</span>NativeMethodAccessorImpl.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">39</span><span style="color: #009900;">&#41;</span>
at sun.<span style="color: #006633;">reflect</span>.<span style="color: #006633;">DelegatingMethodAccessorImpl</span>.<span style="color: #006633;">invoke</span><span style="color: #009900;">&#40;</span>DelegatingMethodAccessorImpl.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">25</span><span style="color: #009900;">&#41;</span>
at java.<span style="color: #006633;">lang</span>.<span style="color: #006633;">reflect</span>.<span style="color: #003399;">Method</span>.<span style="color: #006633;">invoke</span><span style="color: #009900;">&#40;</span><span style="color: #003399;">Method</span>.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">597</span><span style="color: #009900;">&#41;</span>
at org.<span style="color: #006633;">apache</span>.<span style="color: #006633;">maven</span>.<span style="color: #006633;">surefire</span>.<span style="color: #006633;">booter</span>.<span style="color: #006633;">SurefireBooter</span>.<span style="color: #006633;">runSuitesInProcess</span><span style="color: #009900;">&#40;</span>SurefireBooter.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">289</span><span style="color: #009900;">&#41;</span>
at org.<span style="color: #006633;">apache</span>.<span style="color: #006633;">maven</span>.<span style="color: #006633;">surefire</span>.<span style="color: #006633;">booter</span>.<span style="color: #006633;">SurefireBooter</span>.<span style="color: #006633;">main</span><span style="color: #009900;">&#40;</span>SurefireBooter.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">993</span><span style="color: #009900;">&#41;</span>
Caused by<span style="color: #339933;">:</span> java.<span style="color: #006633;">lang</span>.<span style="color: #006633;">reflect</span>.<span style="color: #003399;">UndeclaredThrowableException</span>
at $Proxy55.<span style="color: #006633;">getEM</span><span style="color: #009900;">&#40;</span>Unknown Source<span style="color: #009900;">&#41;</span>
at hu.<span style="color: #006633;">xxx</span>.<span style="color: #006633;">xxx</span>.<span style="color: #006633;">xxx</span>.<span style="color: #006633;">ValamiServiceV1X0</span>.<span style="color: #006633;">queryValamiFind</span><span style="color: #009900;">&#40;</span>ValamiServiceV1X0.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">52</span><span style="color: #009900;">&#41;</span>
at hu.<span style="color: #006633;">xxx</span>.<span style="color: #006633;">xxx</span>.<span style="color: #006633;">xxx</span>.<span style="color: #006633;">ValamiServiceV1X0</span>.<span style="color: #006633;">existsValami</span><span style="color: #009900;">&#40;</span>ValamiServiceV1X0.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">64</span><span style="color: #009900;">&#41;</span>
at sun.<span style="color: #006633;">reflect</span>.<span style="color: #006633;">NativeMethodAccessorImpl</span>.<span style="color: #006633;">invoke0</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">Native</span> <span style="color: #003399;">Method</span><span style="color: #009900;">&#41;</span>
at sun.<span style="color: #006633;">reflect</span>.<span style="color: #006633;">NativeMethodAccessorImpl</span>.<span style="color: #006633;">invoke</span><span style="color: #009900;">&#40;</span>NativeMethodAccessorImpl.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">39</span><span style="color: #009900;">&#41;</span>
at sun.<span style="color: #006633;">reflect</span>.<span style="color: #006633;">DelegatingMethodAccessorImpl</span>.<span style="color: #006633;">invoke</span><span style="color: #009900;">&#40;</span>DelegatingMethodAccessorImpl.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">25</span><span style="color: #009900;">&#41;</span>
at java.<span style="color: #006633;">lang</span>.<span style="color: #006633;">reflect</span>.<span style="color: #003399;">Method</span>.<span style="color: #006633;">invoke</span><span style="color: #009900;">&#40;</span><span style="color: #003399;">Method</span>.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">597</span><span style="color: #009900;">&#41;</span>
at org.<span style="color: #006633;">apache</span>.<span style="color: #006633;">openejb</span>.<span style="color: #006633;">core</span>.<span style="color: #006633;">interceptor</span>.<span style="color: #006633;">ReflectionInvocationContext</span>$Invocation.<span style="color: #006633;">invoke</span><span style="color: #009900;">&#40;</span>ReflectionInvocationContext.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">158</span><span style="color: #009900;">&#41;</span>
at org.<span style="color: #006633;">apache</span>.<span style="color: #006633;">openejb</span>.<span style="color: #006633;">core</span>.<span style="color: #006633;">interceptor</span>.<span style="color: #006633;">ReflectionInvocationContext</span>.<span style="color: #006633;">proceed</span><span style="color: #009900;">&#40;</span>ReflectionInvocationContext.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">141</span><span style="color: #009900;">&#41;</span>
at org.<span style="color: #006633;">apache</span>.<span style="color: #006633;">openejb</span>.<span style="color: #006633;">core</span>.<span style="color: #006633;">interceptor</span>.<span style="color: #006633;">InterceptorStack</span>.<span style="color: #006633;">invoke</span><span style="color: #009900;">&#40;</span>InterceptorStack.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">122</span><span style="color: #009900;">&#41;</span>
at org.<span style="color: #006633;">apache</span>.<span style="color: #006633;">openejb</span>.<span style="color: #006633;">core</span>.<span style="color: #006633;">stateless</span>.<span style="color: #006633;">StatelessContainer</span>._invoke<span style="color: #009900;">&#40;</span>StatelessContainer.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">221</span><span style="color: #009900;">&#41;</span>
at org.<span style="color: #006633;">apache</span>.<span style="color: #006633;">openejb</span>.<span style="color: #006633;">core</span>.<span style="color: #006633;">stateless</span>.<span style="color: #006633;">StatelessContainer</span>.<span style="color: #006633;">invoke</span><span style="color: #009900;">&#40;</span>StatelessContainer.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">174</span><span style="color: #009900;">&#41;</span>
at org.<span style="color: #006633;">apache</span>.<span style="color: #006633;">openejb</span>.<span style="color: #006633;">core</span>.<span style="color: #006633;">ivm</span>.<span style="color: #006633;">EjbObjectProxyHandler</span>.<span style="color: #006633;">businessMethod</span><span style="color: #009900;">&#40;</span>EjbObjectProxyHandler.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">217</span><span style="color: #009900;">&#41;</span>
at org.<span style="color: #006633;">apache</span>.<span style="color: #006633;">openejb</span>.<span style="color: #006633;">core</span>.<span style="color: #006633;">ivm</span>.<span style="color: #006633;">EjbObjectProxyHandler</span>._invoke<span style="color: #009900;">&#40;</span>EjbObjectProxyHandler.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">77</span><span style="color: #009900;">&#41;</span>
at org.<span style="color: #006633;">apache</span>.<span style="color: #006633;">openejb</span>.<span style="color: #006633;">core</span>.<span style="color: #006633;">ivm</span>.<span style="color: #006633;">BaseEjbProxyHandler</span>.<span style="color: #006633;">invoke</span><span style="color: #009900;">&#40;</span>BaseEjbProxyHandler.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">281</span><span style="color: #009900;">&#41;</span>
... <span style="color: #cc66cc;">30</span> more
Caused by<span style="color: #339933;">:</span> java.<span style="color: #006633;">io</span>.<span style="color: #003399;">NotSerializableException</span><span style="color: #339933;">:</span> org.<span style="color: #006633;">apache</span>.<span style="color: #006633;">openejb</span>.<span style="color: #006633;">persistence</span>.<span style="color: #006633;">JtaEntityManager</span>
at java.<span style="color: #006633;">io</span>.<span style="color: #003399;">ObjectOutputStream</span>.<span style="color: #006633;">writeObject0</span><span style="color: #009900;">&#40;</span><span style="color: #003399;">ObjectOutputStream</span>.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">1156</span><span style="color: #009900;">&#41;</span>
at java.<span style="color: #006633;">io</span>.<span style="color: #003399;">ObjectOutputStream</span>.<span style="color: #006633;">writeObject</span><span style="color: #009900;">&#40;</span><span style="color: #003399;">ObjectOutputStream</span>.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">326</span><span style="color: #009900;">&#41;</span>
at org.<span style="color: #006633;">apache</span>.<span style="color: #006633;">openejb</span>.<span style="color: #006633;">core</span>.<span style="color: #006633;">ivm</span>.<span style="color: #006633;">BaseEjbProxyHandler</span>.<span style="color: #006633;">copyObj</span><span style="color: #009900;">&#40;</span>BaseEjbProxyHandler.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">501</span><span style="color: #009900;">&#41;</span>
at org.<span style="color: #006633;">apache</span>.<span style="color: #006633;">openejb</span>.<span style="color: #006633;">core</span>.<span style="color: #006633;">ivm</span>.<span style="color: #006633;">BaseEjbProxyHandler</span>.<span style="color: #006633;">copy</span><span style="color: #009900;">&#40;</span>BaseEjbProxyHandler.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">301</span><span style="color: #009900;">&#41;</span>
at org.<span style="color: #006633;">apache</span>.<span style="color: #006633;">openejb</span>.<span style="color: #006633;">core</span>.<span style="color: #006633;">ivm</span>.<span style="color: #006633;">BaseEjbProxyHandler</span>.<span style="color: #006633;">invoke</span><span style="color: #009900;">&#40;</span>BaseEjbProxyHandler.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">283</span><span style="color: #009900;">&#41;</span>
... <span style="color: #cc66cc;">45</span> more</pre></div></div>

<p>(Élesebb észrevehetik, hogy egy maven által futtato junit tesztből próbálok standalone összerántani egy EJB konténert OpenEJB-vel, hogy konténeren kívül futtathassam az integrációs teszteket. Egyelőre kevés sikerrel)</p>
<img src="http://feeds.feedburner.com/~r/jtechnics/~4/zfLDTBv6dOE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jtechnics.anzix.net/2009/12/07/printstacktrace/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://jtechnics.anzix.net/2009/12/07/printstacktrace/</feedburner:origLink></item>
		<item>
		<title>Db4o tapasztalatok</title>
		<link>http://feedproxy.google.com/~r/jtechnics/~3/iKaT8pDa3M0/</link>
		<comments>http://jtechnics.anzix.net/2009/12/06/db4o-tapasztalatok/#comments</comments>
		<pubDate>Sun, 06 Dec 2009 21:47:16 +0000</pubDate>
		<dc:creator>elek</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[db4o]]></category>

		<guid isPermaLink="false">http://jtechnics.anzix.net/?p=357</guid>
		<description><![CDATA[Aktuálisan kedvenc állatorvosi lovam, egy wicket + guice + warp-persistes alkalmazás. Illetve a technológiák gyakran változnak benne, például alig egy órája dobtam ki az utolsó JPA függőséget is belőle, és teljesen átáltam db4o-ra. (A JasperReport helyét is könnyen átveheti a BIRT, illetve a Salve is sorban áll tesztelésre)
Az első tapasztalatok:

Nem árt tudni, hogy GPL, tehát [...]]]></description>
			<content:encoded><![CDATA[<p>Aktuálisan kedvenc állatorvosi lovam, egy wicket + guice + warp-persistes alkalmazás. Illetve a technológiák gyakran változnak benne, például alig egy órája dobtam ki az utolsó JPA függőséget is belőle, és teljesen átáltam db4o-ra. (A JasperReport helyét is könnyen átveheti a BIRT, illetve a Salve is sorban áll tesztelésre)</p>
<p>Az első tapasztalatok:</p>
<ol>
<li>Nem árt tudni, hogy GPL, tehát az über titkos üzleti alkalmazásban nem használhatom.</li>
<li>Érezhetően gyors. Mondjuk iszonyú kis adatbázisom van, gondolom jól betölti az egészet a memóriába.</li>
<li>Az API-ja csábítóan egyszerű. Queryket írni annonymous-inner-class-okkal igazi fényűzés.</li>
<li>Cascade-ra ugyanúgy gondolni kell. Objektum lekérésnél alapból 5 mélységű a rekurzió, de update/store-nál default nincs rekurzió. Eltartott egy ideig míg rájöttem, miért nem megy rendesen. A rekurzió szintje állítható teljes adatbázis, entitás és mező szinten is. Csak kérni kell.</li>
<li>A séma változásra ez is érzékeny (különösen, ha az <a href="http://developer.db4o.com/Resources/view.aspx/Reference/Implementation_Strategies/Refactoring_and_Schema_Evolution/Refactoring_Class_Hierarchy">objektum hierarhia</a> változik)</li>
<li>A managed-detached objektumokra ugyanúgy figyelni kell. Amíg nem sikerült összeraknom számos esetben elszabadultak az objektumok, és megsokszorozódtak. (Csak egy oc.store() metódus van, és ha detached-et akarok updatelni, akkor lelkiismeret furdalás nélkül létrehoz új objektumot.)</li>
<li>Alapból tud olyat, hogy minden objektumnak van ID-ja (van UUID-ja is, de az nem kellett). Ebben az a furcsa, hogy az ID egy belső dolog, és nem az entitásban van tárolva, hanem API-ból lekérdezhető: kedves konténer, ennek a managed objektumnak mennyi az ID-ja? Az viszont nem meglepő, hogy egy detached objektumnak már nem lehet elkérni. Talán van valami merge itt is, de még nem találtam meg. Igaz nem is nagyon kellett, mert a Wicket detachable modeljei pont tudják azt, hogy az ID-t eltárolják, amíg még managed az entitás, és az alapján visszatöltik, amikor kell.</li>
<li>Nagyon barátságosan tesztelhető, mert egy statikus függvény meghívásával át lehet az egészet in-memory db-re állítani. Onnantól kezdve csak iniciaálizálni kell benle pár adatot, és mehetnek az integráiós(abb) tesztek.</li>
<li>Constraintek Java API-ból adhatóak meg. A Bean Validation Frameworkot valószínű 5 sorból be fogom tudni kötni.</li>
<li>Nincs jó felület, ahol meg tudom nézni a tartalmát, és alap szerkesztéseket tudok végrehajtani. Egy BeanShell-t próbáltam már rá állítani, de még nem sikerült összelőni.</li>
<li>Elég jó doksija van, pedig még csak főleg a tutorialt olvastam, a reference manualnak csak a részeit.</li>
<li>Érdekes következménye van annak, hogy minden objektumot el tud menteni. Pl. a JPA-ból kiszelektált csoda objektumokat nem érdemes rögtön elmenteni, mert előhúzás után a lazy mezők rosszul fogják érezni magukat. Ugyanígy a BigDecimal serializálása alapból nem triviális, ennek a kezelésére külön kiterjesztést kell bekapcsolni (bekapcsolt kiterjesztéssel szerkesztett db fájlt olvasni legközelebb szintén csak bekapcsolt kiterjesztéssel rendelkező konténerrel lehet).</li>
</ol>
<p>Szóval egyelőre barátok maradunk és bent marad. Még meg kell nézni a tranzakciókat, a Bean Validation Frameworkot bele reszelni, és majd byte[]-el kell még tesztelni.</p>
<img src="http://feeds.feedburner.com/~r/jtechnics/~4/iKaT8pDa3M0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jtechnics.anzix.net/2009/12/06/db4o-tapasztalatok/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://jtechnics.anzix.net/2009/12/06/db4o-tapasztalatok/</feedburner:origLink></item>
		<item>
		<title>Wicket + IoC</title>
		<link>http://feedproxy.google.com/~r/jtechnics/~3/98R_QyztVjA/</link>
		<comments>http://jtechnics.anzix.net/2009/11/30/wicket-ioc/#comments</comments>
		<pubDate>Mon, 30 Nov 2009 20:09:27 +0000</pubDate>
		<dc:creator>elek</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://jtechnics.anzix.net/?p=355</guid>
		<description><![CDATA[Ha wicketben elnavigálunk egy statfull oldalról, akkor azt a keretrendszer leserializálja és elrakja. Ha az új oldalról mondjuk a backkel visszamegyünk, akkor az előző oldal példányt vissza serializálja és azt rendereli le. Ha azonban a serializálás közben egy nem serializálható mezőt talála az oldal objektumon, akkor dob egy kivételt (nem a felületen, csak az alkalmazás [...]]]></description>
			<content:encoded><![CDATA[<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Ha wicketben elnavigálunk egy statfull oldalról, akkor azt a keretrendszer leserializálja és elrakja. Ha az új oldalról mondjuk a backkel visszamegyünk, akkor az előző oldal példányt vissza serializálja és azt rendereli le. Ha azonban a serializálás közben egy nem serializálható mezőt talála az oldal objektumon, akkor dob egy kivételt (nem a felületen, csak az alkalmazás szerver logjában), és amikor vissza akarunk térni, már csak egy Page Expired oldal fogad.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">A Wicket és az IoC kapcsolódási pontja az IComponentInstantiationListener osztály. A beregisztrált listenerek minden komponens létrehozásakor meghívódnak a Component osztály konstruktorában. Mivel a leszármaztatott komponensben első lépésben meghívjuk a szülő osztály konstruktorát, ezért ha egy beregisztrált listener injektál az annotált mezőkebe, akkor azoknak értéke már a konstruktorban elérhető. Ilyen okos konstruktor, azonban csak a Component osztályban van, a Model-ek és DataProviderekben nem.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Van még egy másik dolog, ami a Wicketben alap, hogy a Model-ek egy jó része Detachable, azaz az oldal elrakásakor nem serializálódik úgy ahogy van, hanem csak a fontos mezők kerülnek elmentésre. Ezzel csökkenthető az állapot által elfoglalt hely nagysága. Tipikusan pl. ha egy model egy JPA entitást tárol, akkor elég elrakáskor a primary key-t elrakni, és amikor a komponens fát előhúzza a wicket, akkor az Id alapján újra betölti az entitás az adatbázisból. Már ha éppen kéznél van a Modelben egy EntityManager. ServiceLocator.getInstance() típusú trükkel mindenhol kéznél lehet, de IoC-vel már bonyolultabb a probléma, mert az EntityManager nem serializálható, és a jól beinjektált objektumot nem tudja elserializálni a wicket. Ha meg transient, akkor a Modelt elserializálja, de elővétel után az EntityManager helyett egy nagy null lesz.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Mi a megoldás? A wicket-guice azt csinálja, hogy egy un. LazyInitProxy-t használ. Ez a nevének megfelelően egy olyan proxy, ami az első híváskor inicializál a hasába egy adott osztályt, amihez majd híváskor proxyzza a kérést. A wicket-guice amikor a Component-ekbe kéne injektálnia, nem az Guice-os Injectort használja, hanem kézzel végig szánkázik a potenciális injektálandó mezőkön, és ahová injektálni kell, oda ő injektál egy proxy-t, amibe belírja a cél mező típusát és a rajta lévő annotációt. A proxy tehát tudja ezt a két értéket, ami már elég kulcs, hogy szükség esetén ez alapján az Injectortól elkérje a megfelelő példányt, aminek tovább kell adni a kérést. És persze a csak mező és annotáció típust hordozó proxy szerű objektum vidáman serializálható.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Ezzel a trükkel a Component szinten lévő @Injectálandó szolgáltatások helyére egy speciális serializálható referencia kerül. Viszont az ily módon beinjektált osztály által hivatkozott szolgáltatók már hagyományos Guice IoC szinten jönnek létre.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">A megoldás tehát az, hogy a Page-ekbe rakunk @Inject-eket, és a Modelek és DataProviderek megkapják konstruktor paraméterbe a beinjektált szolgáltatásokat, hiszen mi tudjuk, hogy első szinten azok serializálható visszatölthető referenciák.</div>
<p>Ha wicketben elnavigálunk egy statfull oldalról, akkor azt a keretrendszer leserializálja és elrakja. Ha az új oldalról mondjuk a backkel visszamegyünk, akkor az előző oldal példányt vissza serializálja és azt rendereli le. Ha azonban a serializálás közben egy nem serializálható mezőt talál az oldal objektumon, akkor dob egy kivételt (nem a felületen, csak az alkalmazás szerver logjában), és amikor vissza akarunk térni, már csak egy Page Expired oldal fogad.</p>
<p><span style="background-color: #ffffff;">A Wicket és az IoC kapcsolódási pontja az IComponentInstantiationListener osztály. A beregisztrált listenerek minden komponens létrehozásakor meghívódnak a Component osztály konstruktorában. Mivel a leszármaztatott komponensben első lépésben meghívjuk a szülő osztály konstruktorát, ezért ha egy beregisztrált guice-os listener injektál az annotált mezőkebe, akkor azoknak értéke már a konstruktorban elérhető lesz. Ilyen okos konstruktor, azonban csak a Component osztályban van, a Model-ek és DataProviderekben nem.</span></p>
<p><span style="background-color: #ffffff;">Van még egy másik dolog, amire épül a Wicket, hogy a Model-ek egy jó része Detachable, azaz az oldal elrakásakor nem serializálódik úgy ahogy van, hanem csak a fontos mezők kerülnek elmentésre (hogy mi fontos, azt mi implementáljuk). Ezzel csökkenthető az oldal állapotok által elfoglalt hely nagysága. Tipikusan pl. ha egy model egy JPA entitást tárol, akkor elég elrakáskor a primary key-t elrakni, és amikor a komponens fát előhúzza a wicket, akkor az Id alapján újra betölti az entitást az adatbázisból. </span></p>
<p><span style="background-color: #ffffff;">Már ha éppen kéznél van a Modelben egy EntityManager. ServiceLocator.getInstance() típusú trükkel mindenhol kéznél lehet, de IoC-vel már bonyolultabb a probléma, mert az EntityManager nem serializálható, és a jól beinjektált objektumot nem tudja elserializálni a wicket. Ha meg transient, akkor a Modelt el tudja serializálni, de elővétel után az EntityManager helyett egy nagy null lesz, mert elővételkor nem fut le a Listener, hogy injektáljon.</span></p>
<p>Mi a megoldás? A wicket-guice azt csinálja, hogy egy un. LazyInitProxy-t használ. Ez a nevének megfelelően egy olyan proxy, ami az első híváskor inicializál a hasába egy adott osztályt, amihez majd híváskor proxyzza a kérést. A wicket-guice amikor a Component-ekbe kéne injektálnia, nem az Guice-os Injectort használja, hanem kézzel végig szánkázik a potenciális injektálandó mezőkön, és ahová injektálni kell, oda ő injektál egy proxy-t, amibe belírja a cél mező típusát és a rajta lévő annotációt. A proxy tehát tudja ezt a két értéket, ami már elég kulcs, hogy szükség esetén ez alapján az Injectortól elkérje a megfelelő példányt, aminek tovább kell adni a kérést. És persze a csak mező és annotáció típust hordozó proxy szerű objektum vidáman serializálható.</p>
<p><span style="background-color: #ffffff;">Ezzel a trükkel a Component szinten lévő @Injectálandó szolgáltatások helyére egy speciális serializálható referencia kerül. Viszont az ily módon beinjektált osztály által hivatkozott szolgáltatók már hagyományos Guice IoC szinten jönnek létre.</span></p>
<p>A megoldás tehát az, hogy a Page-ekbe rakunk @Inject-eket, és a Modelek és DataProviderek megkapják konstruktor paraméterbe a beinjektált szolgáltatásokat, hiszen mi tudjuk, hogy első szinten azok serializálható visszatölthető referenciák.</p>
<p><em>PS: kitakarítottam a commentek közül az 500 spamet, találtam három értékes kommentet (miért nem kaptam róluk emailt??), amire mindjárt válaszolok. kicsit újra rendet raktam itt. Jól megült itt a por, mióta utoljára itt jártam.</em></p>
<img src="http://feeds.feedburner.com/~r/jtechnics/~4/98R_QyztVjA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jtechnics.anzix.net/2009/11/30/wicket-ioc/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://jtechnics.anzix.net/2009/11/30/wicket-ioc/</feedburner:origLink></item>
		<item>
		<title>openjpa:sql</title>
		<link>http://feedproxy.google.com/~r/jtechnics/~3/iorqkPB_7sI/</link>
		<comments>http://jtechnics.anzix.net/2009/09/14/openjpasql/#comments</comments>
		<pubDate>Mon, 14 Sep 2009 20:21:08 +0000</pubDate>
		<dc:creator>elek</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[JPA]]></category>
		<category><![CDATA[openjpa]]></category>

		<guid isPermaLink="false">http://jtechnics.anzix.net/?p=352</guid>
		<description><![CDATA[A probléma: a JPA entitás struktúra folyamatosan fejlődik. Bármikor képes szeretnék lenni az entitásoknak megfelelő adatbázis struktúrát létrehozni, illetve egy meglévő adatbázis struktúrát minél kevesebb adatvesztéssel frissíteni.
Az első követelményt szinte minden JPA provider tudja, a második viszont már keményebb dió. Az Eclipselink pl. csak a drop-and-create szolgáltatást ajánlja, azaz törli az összes táblámat, és újra [...]]]></description>
			<content:encoded><![CDATA[<p>A probléma: a JPA entitás struktúra folyamatosan fejlődik. Bármikor képes szeretnék lenni az entitásoknak megfelelő adatbázis struktúrát létrehozni, illetve egy meglévő adatbázis struktúrát minél kevesebb adatvesztéssel frissíteni.</p>
<p>Az első követelményt szinte minden JPA provider tudja, a második viszont már keményebb dió. Az Eclipselink pl. csak a drop-and-create szolgáltatást ajánlja, azaz törli az összes táblámat, és újra létrehozza a sémát, még akkor is, ha csak egy új mezőt, vagy egy új táblát hoztam létre.</p>
<p>Az openjpa viszont még az én igényeimet is kielégíti. Erre egyrészt ad egy <a href="http://openjpa.apache.org/builds/1.0.2/apache-openjpa-1.0.2/docs/manual/ref_guide_mapping.html#ref_guide_mapping_mappingtool">Java osztály</a>t, de van hozzá <a href="http://mojo.codehaus.org/openjpa-maven-plugin/">Maven plugin</a> is. Megnézi az entitásaimat és tud generálni belőle create DDL-t, illetve refresh-t is, azaz egy meglévő adatbázishoz képest a különbséget. Az adatbázis kapcsolatot a persistence.xml-ből veszi, vagy konzol paraméterből is megadható. Az SQL parancsokat kiírja fájlba, vagy rögtön frissíti/létrehozza az adatbázist is. Elvileg ugyanerre be lehet konfigurálni a Persistence Unitot is, de azt még nem próbáltam ki.</p>
<p>Az első próbák ígéretesek. Új oszlopot, táblát felvesz anélkül, hogy a többit törölné. Ha mezőt törlök, akkor persze nem törli a megfelelő mezőt, de ezt akár tervezési döntésnek is be tudhatjuk.</p>
<p>Nekünk volt erre egy sufni toolunk régen, ami felépítésében sokat ígérő volt, de persze a JPA-ból csak a triviális dolgokat implementáltuk, most viszont ez úgy tűnik el lehet dobni, mert az openjpa jó lesz minderre. Lehet hogy providerként is megpróbálkozom vele.</p>
<img src="http://feeds.feedburner.com/~r/jtechnics/~4/iorqkPB_7sI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jtechnics.anzix.net/2009/09/14/openjpasql/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://jtechnics.anzix.net/2009/09/14/openjpasql/</feedburner:origLink></item>
		<item>
		<title>Guice 2.0</title>
		<link>http://feedproxy.google.com/~r/jtechnics/~3/Py_XsBpacXQ/</link>
		<comments>http://jtechnics.anzix.net/2009/05/25/guice-20/#comments</comments>
		<pubDate>Mon, 25 May 2009 21:18:25 +0000</pubDate>
		<dc:creator>elek</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[guice]]></category>

		<guid isPermaLink="false">http://jtechnics.anzix.net/?p=349</guid>
		<description><![CDATA[Kijött a Guice 2.0. Sok egyébb mellett az én problémámra is megoldást nyújt. Azaz listener-ek segjtségével teljesen dinamikus bindingokat lehet létrehozni.
Eddig a @PersistenceContext injektálásokhoz előre meg kellett adni a a Module-ba a használni kívánt PU-kat. Most már lehet dinamikusan a classpathba keresni igény esetén, hogy létezik a megjelölt PU, és elég első injektáláskor betölteni. Tehát [...]]]></description>
			<content:encoded><![CDATA[<p>Kijött a <a href="http://code.google.com/docreader/#p=google-guice&amp;s=google-guice&amp;t=Guice20">Guice 2.0</a>. Sok egyébb mellett az <a href="http://code.google.com/p/guiceyfruit/">én problémámra </a>is megoldást nyújt. Azaz <a href="http://code.google.com/docreader/#p=google-guice&amp;s=google-guice&amp;t=CustomInjections">listener</a>-ek segjtségével teljesen dinamikus bindingokat lehet létrehozni.</p>
<p>Eddig a @PersistenceContext injektálásokhoz előre meg kellett adni a a Module-ba a használni kívánt PU-kat. Most már lehet dinamikusan a classpathba keresni igény esetén, hogy létezik a megjelölt PU, és elég első injektáláskor betölteni. Tehát most már lehetne vele EJB konténert emulálni rendesen integrációs tesztkörnyezetben. (Kristóf ajánlotta <a href="http://www.wideplay.com/guicewebextensions2">wrap-persist</a> mellett (emi elsősorban JPA barát) van egy <a href="http://code.google.com/p/guiceyfruit/">GuiceFruit</a> is, ami mintha részben tudná is ezt.(EJB barát is)).</p>
<p>Ez a Guice egyre jobban tetszik. Már több kissebb-nagyobb projektembe beszivárgott, és lassan kezdek függővé vállni.</p>
<p>ps: akinek volt commentje, ami moderácóra várt (ilyen eddig nem nagyon volt), az kérem írja újra, mert legalább 2000 spamet kaptam, és kénytelen voltam SQL-ből törölni.</p>
<img src="http://feeds.feedburner.com/~r/jtechnics/~4/Py_XsBpacXQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jtechnics.anzix.net/2009/05/25/guice-20/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://jtechnics.anzix.net/2009/05/25/guice-20/</feedburner:origLink></item>
		<item>
		<title>OSGi névsorolvasás</title>
		<link>http://feedproxy.google.com/~r/jtechnics/~3/OoaKHmJPOAM/</link>
		<comments>http://jtechnics.anzix.net/2009/05/10/osgi-nevsorolvasas/#comments</comments>
		<pubDate>Sun, 10 May 2009 20:33:04 +0000</pubDate>
		<dc:creator>elek</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://jtechnics.anzix.net/2009/05/10/osgi-nevsorolvasas/</guid>
		<description><![CDATA[pax-runner: Az ops4j-sek azok, ahol nem csak a forráskód a szabad, hanem a fejlesztés is, tehát odamész, és ha akarsz, commitolsz. Az ő legnépszerűbb projekt csokruk a pax, amik mind OSGi-al foglalkoznak. A pax-runner pl. OSGi konténert indít el. Bármilyet, csak paraméterezni kell. Azt is megmondhatod, hogy milyen alap szolgáltatások legyenek benne. Ha nincs meg [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://paxrunner.ops4j.org/space/Pax+Runner">pax-runner</a>: Az ops4j-sek azok, ahol nem csak a forráskód a szabad, hanem a fejlesztés is, tehát odamész, és ha akarsz, commitolsz. Az ő legnépszerűbb projekt csokruk a pax, amik mind OSGi-al foglalkoznak. A pax-runner pl. OSGi konténert indít el. Bármilyet, csak paraméterezni kell. Azt is megmondhatod, hogy milyen alap szolgáltatások legyenek benne. Ha nincs meg a konténer, amit szeretnél, akkor letölti. Nagyon jól lehet vele tesztelni bundle-t több konténerbe.</p>
<p><a href="http://code.google.com/p/modulefusion/">modulefusion</a>: (K.-tól tanultam.) A recept egyszerű: végy egy csomó OSGi bundle-t (ha nincs elég jó, csinálj), és az egészet rakd össze valami alkalmazás szerver jellegű dolognak, és nevezd el. Ezt csinálja a Spring Source is, és ilyen a modulfusion is. Van benne wicket, guice, hibernate mindezt pax-runner indítja el, jól összerakott szakmunka. Példák is vannak, hogy hogy csináljunk JPA+Wicket+guice varázslatot OSGi konzolon.</p>
<p><a href="http://www.eclipse.org/equinox/">equinox</a>: az Eclipse OSGI konténere. Az izgalom az benne, hogy van hozzá egy <a href="http://www.eclipse.org/equinox/server/">server bridge</a>. Ez egy war file, amit bedeployolsz bárhová, de közben OSGi konténer is. A servletre érkező kéréseket OSGi HttpService szolgáltatásként adja tovább. Valami ősöreg 3-as OSGi bundleok vannak benne.</p>
<p><a href="http://felix.apache.org/site/index.html">Felix</a>: Apache OSGi konténer. Kicsi, könnyű, beágyazható. Akik nem eclipse hívők (pl. Glassfish), azok általában ezt használják. Szerethető cucc, de nincs servlet bridge-hozzá. (még)</p>
<p>Http Service: OSGi kiegészítő specifikáció része. Kicsit buta, csak Servletet lehet regisztrálni. Azt is úgy, hogy lekéred a servicet, amin meg tudod hívni a regisztráló metódust. Mindenkinek szokott lenni implementációja, általában Jetty alapú.</p>
<p>Pax-web: egy másik pax. Olyan mint a Http Service (extend), csak van mellette még filter támogatás is, meg resource és jsp regisztráció, welcome file támogatás, stb. Servlet bridge nem tudja, mivel ez önmagában egy jettyre épülő bundle. Kicsit vendor lock-in, de szükség lehet rá (modulefusion a Wicketet servleten keresztül működteti, nem filteren, tehát megkerülhető).</p>
<p>Pax web extender, whiteboard: a http service-ek regisztrációját könyíti meg. Nem kell megkeresni a szolgáltatást, amin keresztül regisztrálni lehet a Servletet, hanem elég felírni a táblára, hogy én vagyok X Servlet az Y url-en, és már megy is. Meglepően okosan összerakott cucc: megy csak Http Service szolgáltatással, és pax-web-bel is. Megnézi milyen osztályok vannak, és azzal főz.<br />&nbsp;<br /><a href="http://felix.apache.org/site/apache-felix-file-install.html">Felix File Install</a>: egy okos bundle, ami sasol egy könyvtárat, és az ott feltünő bundle-okat hot deployolja.</p>
<p>modulefusion dir install: egy mégokosabb bundle, ami a modulfusion része, és nem csak a bundle-okat nyomja fel, de a config fájlokat is beolvassa.</p>
<p><b><i>Recept</i></b>: fogom a Felix-et, berakom egy szervletbe, és onnan indítom, tehát elértem azt, amit az equinox servlet bridge is. Az OSGi compendium libraryt kicsit megpatkolva, pár class-t az OSGi class loadernek kiajánlva, és a HttpRequest wrappolása után, a pax web whiteboardon keresztül, a felix dir installt mellőzve, hanem az eredeti modulefusion-osat használva, a modulefusionos wicket-es guice-os OSGi-s csoda tökéletesen fut szervlet konténerbe. peace.</p>
<div class="zemanta-pixie"><img class="zemanta-pixie-img" src="http://img.zemanta.com/pixy.gif?x-id=c640f7fe-0f98-8275-a44a-01ebbdbb9bae" /></div>
<img src="http://feeds.feedburner.com/~r/jtechnics/~4/OoaKHmJPOAM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jtechnics.anzix.net/2009/05/10/osgi-nevsorolvasas/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://jtechnics.anzix.net/2009/05/10/osgi-nevsorolvasas/</feedburner:origLink></item>
	</channel>
</rss>
