<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	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/"
	>

<channel>
	<title>GhoUl &#187; Post Tags &#187; java</title>
	<atom:link href="http://cubussapiens.hu/tag/java/feed/" rel="self" type="application/rss+xml" />
	<link>http://cubussapiens.hu</link>
	<description>A Cubus Sapiens oldal</description>
	<lastBuildDate>Thu, 19 Aug 2010 19:17:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Mi a hiba a kódban? #2</title>
		<link>http://cubussapiens.hu/2009/12/mi-a-hiba-a-kodban-2/</link>
		<comments>http://cubussapiens.hu/2009/12/mi-a-hiba-a-kodban-2/#comments</comments>
		<pubDate>Mon, 07 Dec 2009 21:38:46 +0000</pubDate>
		<dc:creator>Stampie</dc:creator>
				<category><![CDATA[Fejlesztés]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[programozás]]></category>

		<guid isPermaLink="false">http://cubussapiens.hu/?p=1314</guid>
		<description><![CDATA[A hatására Tompika küldött nekem egy hasonlóan izgalmas problémát. 1234while &#40;true&#41; &#123; Process p = Runtime.getRuntime&#40;&#41;.exec&#40;&#34;macska&#34;&#41;; p.waitFor&#40;&#41;; &#125; A kód eredeti, Tompika kedvenc állatait, a macskákat felemlegetve. A kód elméletben a következőt kellene, hogy csinálja: az első sor a p referenciával elérhető módon indít egy processzt; míg a második sor vár, amíg a processz fut. [...]]]></description>
			<content:encoded><![CDATA[<p>A <a href="http://cubussapiens.hu/2009/10/mi-a-hiba-a-kodban/">múltkori, nagy sikerű írásom</a> hatására Tompika küldött nekem egy hasonlóan izgalmas problémát.</p>
<div class="codecolorer-container java mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
<span style="color: #003399;">Process</span> p <span style="color: #339933;">=</span> <span style="color: #003399;">Runtime</span>.<span style="color: #006633;">getRuntime</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">exec</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;macska&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
p.<span style="color: #006633;">waitFor</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>A kód eredeti, Tompika kedvenc állatait, a macskákat felemlegetve. A kód elméletben a következőt kellene, hogy csinálja: az első sor a <code class="codecolorer java mac-classic"><span class="java">p</span></code> referenciával elérhető módon indít egy processzt; míg a második sor vár, amíg a processz fut.</p>
<p>Ha megnézzük a kapcsolódó JavaDoc kommenteket, ez így működőképes is lehet. Ezzel szemben futásidőben problémák léptek fel, amiket feltehetőleg a következő kódrészletre való kicserélés javított:</p>
<div class="codecolorer-container java mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
<span style="color: #003399;">Process</span> p <span style="color: #339933;">=</span> <span style="color: #003399;">Runtime</span>.<span style="color: #006633;">getRuntime</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">exec</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;macska&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
p.<span style="color: #006633;">waitFor</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
p.<span style="color: #006633;">getErrorStream</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
p.<span style="color: #006633;">getOutputStream</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
p.<span style="color: #006633;">getInputStream</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
p.<span style="color: #006633;">destroy</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>A kódrészlet utolsó sora vicces. Idézném a <a href="http://java.sun.com/javase/6/docs/api/java/lang/Process.html#destroy%28%29">Javadoc kommentet</a>:</p>
<blockquote><p><code class="codecolorer java mac-classic"><span class="java"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">abstract</span> <span style="color: #000066; font-weight: bold;">void</span> destroy<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span></span></code></p>
<p>Kills the subprocess. The subprocess represented by this   <code class="codecolorer java mac-classic"><span class="java"><span style="color: #003399;">Process</span></span></code> object is forcibly terminated.</p></blockquote>
<p>Amit én úgy értelmeznék, hogy a függvényt meghívva explicite lezárom a Processt. Viszont állítólag nem így történik. Valaki tudja a magyarázatot? Kíváncsi lennék rá.</p>
<p>PS.: ha valaki hozzájut hasonló gyöngyszemekhez, és eljuttatja hozzám, szívesen közzéteszem.</p>]]></content:encoded>
			<wfw:commentRss>http://cubussapiens.hu/2009/12/mi-a-hiba-a-kodban-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Eclipse GEF wtf</title>
		<link>http://cubussapiens.hu/2009/11/eclipse-gef-wtf/</link>
		<comments>http://cubussapiens.hu/2009/11/eclipse-gef-wtf/#comments</comments>
		<pubDate>Tue, 17 Nov 2009 19:25:56 +0000</pubDate>
		<dc:creator>Balage</dc:creator>
				<category><![CDATA[Fejlesztés]]></category>
		<category><![CDATA[eclipse fejlesztés]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[programozás]]></category>

		<guid isPermaLink="false">http://cubussapiens.hu/?p=1287</guid>
		<description><![CDATA[Az előző kitérő után most térjünk vissza egy kis kocka témához. A minap érdekes felfedezést tettem, miközben véletlenül a GEF belső kódjába tévedtem debug közben. Alapvetően egyébként meg vagyok elégedve a GEF és általában az eclipse platform minőségével, ritka az az eset, hogy a fejemet fogom egy-egy megoldás láttán. A következő kódrészlet ugyan működik és [...]]]></description>
			<content:encoded><![CDATA[<p>Az előző kitérő után most térjünk vissza egy kis kocka témához. A minap érdekes felfedezést tettem, miközben véletlenül a GEF belső kódjába tévedtem debug közben. Alapvetően egyébként meg vagyok elégedve a GEF és általában az eclipse platform minőségével, ritka az az eset, hogy a fejemet fogom egy-egy megoldás láttán. </p>
<p>A következő kódrészlet ugyan működik és mivel a publikus api elrejti, az átlag fejlesztő nem találkozik vele, mégis  érdemes rávetni egy pillantást. További szócséplés helyett következzék a kód, szerintem magáért beszél:</p>
<div class="codecolorer-container java mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666; font-style: italic;">//AbstractEditPart.class</span><br />
<br />
<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Object</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> policies<span style="color: #339933;">;</span><br />
<br />
<span style="color: #666666; font-style: italic;">//...</span><br />
<br />
<span style="color: #008000; font-style: italic; font-weight: bold;">/**<br />
&nbsp;* @see EditPart#installEditPolicy(Object, EditPolicy)<br />
&nbsp;*/</span><br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> installEditPolicy<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> key, EditPolicy editPolicy<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">Assert</span>.<span style="color: #006633;">isNotNull</span><span style="color: #009900;">&#40;</span>key, <span style="color: #0000ff;">&quot;Edit Policies must be installed with keys&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><span style="color: #666666; font-style: italic;">//$NON-NLS-1$</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>policies <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; policies <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Object</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; policies<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> key<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; policies<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> editPolicy<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">int</span> index <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">while</span> <span style="color: #009900;">&#40;</span>index <span style="color: #339933;">&lt;</span> policies.<span style="color: #006633;">length</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span>key.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span>policies<span style="color: #009900;">&#91;</span>index<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; index <span style="color: #339933;">+=</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>index <span style="color: #339933;">&lt;</span> policies.<span style="color: #006633;">length</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; index<span style="color: #339933;">++;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; EditPolicy old <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>EditPolicy<span style="color: #009900;">&#41;</span>policies<span style="color: #009900;">&#91;</span>index<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>old <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span> <span style="color: #339933;">&amp;&amp;</span> isActive<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; old.<span style="color: #006633;">deactivate</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; policies<span style="color: #009900;">&#91;</span>index<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> editPolicy<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003399;">Object</span> newPolicies<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Object</span><span style="color: #009900;">&#91;</span>policies.<span style="color: #006633;">length</span> <span style="color: #339933;">+</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003399;">System</span>.<span style="color: #006633;">arraycopy</span><span style="color: #009900;">&#40;</span>policies, <span style="color: #cc66cc;">0</span>, newPolicies, <span style="color: #cc66cc;">0</span>, policies.<span style="color: #006633;">length</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; policies <span style="color: #339933;">=</span> newPolicies<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; policies<span style="color: #009900;">&#91;</span>index<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> key<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; policies<span style="color: #009900;">&#91;</span>index <span style="color: #339933;">+</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> editPolicy<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>editPolicy <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; editPolicy.<span style="color: #006633;">setHost</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>isActive<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; editPolicy.<span style="color: #006633;">activate</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>Akinek nem világos elsőre, kifejteném a problémát: láthatóan egy tömböt használ a java-ban alapértelmezésként elérhető &#8220;Map&#8221; funkcionalitásának a kiváltására. A tömb páros (és nulladik) helyén szereplő elem tárolja a kulcsot, az utána lévő páratlan helyen lévő elem az érték. </p>
<p>Minden elem hozzáadásakor dinamikusan növeli a tömb méretét, törléskor meg egyszerűen null-ra állítja a tömb megfelelő elemét. Ehhez még társul egy custom iterátor is, ami a tömb nem null elemeit listázza.</p>
<p>Őszintén nem értem a tervezési döntést, ami a tömb-alapú Map-hez vezethetett. A memóriaigénye a HashMap-nek nem sokkal több, és mivel jellemzően kis elemszámú esetek fordulnak elő, ez nem számottevő. A sebessége a HashMap-nek jobb, a &#8220;get&#8221; és &#8220;put&#8221; metódusok általános esetben konstans, de mindenképpen kevesebb a tömb végigjárásánál. Mindennek a tetejébe a fenti kód Map alkalmazásával kb. 3 sorra cserélhető, nem beszélve az osztály egyéb kódjáról, ami a tömböt piszkálja.</p>
<p>Egyetlen érthető mentségként csak arra tudok gondolni, hogy esetleg a kód korábban íródott, minthogy a java collections API-ba belekerült volna a Map. Ez viszont az 1.2-es verzióban történt meg, tehát elég régen. Nem tudom mennyi idős a GEF, így ezt nem tudom eldönetni.. Mindenesetre ez a kód nálam megütötte a WTF szintet.</code></p>]]></content:encoded>
			<wfw:commentRss>http://cubussapiens.hu/2009/11/eclipse-gef-wtf/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Mi a hiba a kódban?</title>
		<link>http://cubussapiens.hu/2009/10/mi-a-hiba-a-kodban/</link>
		<comments>http://cubussapiens.hu/2009/10/mi-a-hiba-a-kodban/#comments</comments>
		<pubDate>Mon, 12 Oct 2009 20:14:16 +0000</pubDate>
		<dc:creator>Stampie</dc:creator>
				<category><![CDATA[Fejlesztés]]></category>
		<category><![CDATA[eclipse fejlesztés]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://cubussapiens.hu/?p=1249</guid>
		<description><![CDATA[Volt ma egy szép debug köröm. Nagyon nem értettem, miért nem működik egy kód &#8211; ami ráaásul régebben (július végén) szépen ment, és azóta nem nyúltam hozzá, és elvileg a kapcsolódó libekben sem volt lényegi változás azóta. Úgy gondolom, bemutatom a kódot, és felteszem a kérdést, látja-e más is a hibát benne. 123456789101112131415161718private ICoreNotificationObject notificationObject; [...]]]></description>
			<content:encoded><![CDATA[<p>Volt ma egy szép debug köröm. Nagyon nem értettem, miért nem működik egy kód &#8211; ami ráaásul régebben (július végén) szépen ment, és azóta nem nyúltam hozzá, és elvileg a kapcsolódó libekben sem volt lényegi változás azóta.</p>
<p>Úgy gondolom, bemutatom a kódot, és felteszem a kérdést, látja-e más is a hibát benne.</p>
<div class="codecolorer-container java mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">private</span> ICoreNotificationObject notificationObject<span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> actionPerformed<span style="color: #009900;">&#40;</span>ICoreNotificationObject notification<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">notificationObject</span> <span style="color: #339933;">=</span> notification<span style="color: #339933;">;</span><br />
&nbsp; Display.<span style="color: #006633;">getDefault</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">aSyncExec</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Runnable</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
<br />
&nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> run<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #003399;">String</span> action <span style="color: #339933;">=</span> notificationObject.<span style="color: #006633;">getActionType</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>isOneOf<span style="color: #009900;">&#40;</span>action, <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ICoreNotificationObject.<span style="color: #006633;">TA_TRANSACTION_END</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ICoreNotificationObject.<span style="color: #006633;">TA_UNDO_END</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ICoreNotificationObject.<span style="color: #006633;">TA_SUBTRANSACTION_END</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;updateGraph<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;transactions.<span style="color: #006633;">pop</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>isOneOf<span style="color: #009900;">&#40;</span>action, <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#123;</span>...<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #666666; font-style: italic;">//...</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>Még némi információ a kód működéséről: a kód egy eseményfigyelő osztály belsejében van, és a Runnable adatváltozásokat próbál követni, amely tranzakciókba van szervezve, ill. a tranzakciók során visszavonás események is érkezhetnek.</p>
<p>Na, kinek van tippje, mi lehet a hiba? Ha nincs tipp véges időn belül (előre nem specifikálnám), akkor majd megosztom a helyes megfejtést. Annyit mondok előre, hogy fejet falbaverős hiba <img src='http://cubussapiens.hu/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' />  .</p>
<p><strong>Update</strong>: először is helyesbítettem a kódot, mert sikeresen a javított változatot töltöttem fel.</p>
<p>A problémát az okozta, hogy az asyncExec() hívás indított egy új jobot, amit valamikor majd végrehajt. Csak közben visszaadja a vezérlést, és ezzel lehetővé teszi a rendszer számára, hogy felülírja a run() metóduson belül is használt notificationObject változót.</p>
<p>Az asyncExec() hívás syncExec()-re cserélése megoldotta a problémát, ugyanis az megvárja, hogy visszatérjen a meghívott thread.</p>
<p>Ez a hiba kifejezetten mocskos dolog, mert eredetileg működött, míg a környezet refactoringja előhozta a bugot&#8230;</p>]]></content:encoded>
			<wfw:commentRss>http://cubussapiens.hu/2009/10/mi-a-hiba-a-kodban/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Java konstruktor hívási sorrend</title>
		<link>http://cubussapiens.hu/2009/09/java-konstruktor-hivasi-sorrend/</link>
		<comments>http://cubussapiens.hu/2009/09/java-konstruktor-hivasi-sorrend/#comments</comments>
		<pubDate>Thu, 03 Sep 2009 21:05:12 +0000</pubDate>
		<dc:creator>Balage</dc:creator>
				<category><![CDATA[Fejlesztés]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[programozás]]></category>

		<guid isPermaLink="false">http://cubussapiens.hu/?p=1219</guid>
		<description><![CDATA[Rég írtam, valóban. Hogy újra rávezessem magam a kedvenc munkán kívüli elfoglaltságomhoz, most egy egyszerűbb témát vetek fel, ami mégis okozott pár kobak-koppanást az asztalon. Nevezetesen arról szándékozom írni, hogy a Java hogyan sorrendezi egy objektum inicializálásában résztvevő kódokat. Mert bizony több lehet, és nem egyértelmű a lefutási sorrend, ahogy azt a követkető kódrészlet szemlélteti: [...]]]></description>
			<content:encoded><![CDATA[<p>Rég írtam, valóban. Hogy újra rávezessem magam a kedvenc munkán kívüli elfoglaltságomhoz, most egy egyszerűbb témát vetek fel, ami mégis okozott pár kobak-koppanást az asztalon. Nevezetesen arról szándékozom írni, hogy a Java hogyan sorrendezi egy objektum inicializálásában résztvevő kódokat. Mert bizony több lehet, és nem egyértelmű a lefutási sorrend, ahogy azt a követkető kódrészlet szemlélteti:</p>
<div class="codecolorer-container java mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> AB<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">abstract</span> <span style="color: #000000; font-weight: bold;">class</span> A<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> A<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; doSomething<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">abstract</span> <span style="color: #000066; font-weight: bold;">void</span> doSomething<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">class</span> B <span style="color: #000000; font-weight: bold;">extends</span> A<span style="color: #009900;">&#123;</span> &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">String</span> s <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;1234&quot;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">Object</span> o <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;1234&quot;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> B<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; @Override<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">void</span> doSomething<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span>s.<span style="color: #006633;">getClass</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span>o.<span style="color: #006633;">getClass</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> main<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> args<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">new</span> B<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>A példát igyekeztem egyszerűnek tartani, de talán megérdemel egy rövid magyarázatot: Két osztályt definiáltam, az egyik leszármazottja a másiknak. Érdekesség még, hogy az ős konstruktora kódot hív meg a leszármazottból absztrakt metóduson keresztűl. Egy &#8220;B&#8221; típusú objektum létrehozásához láthatóan három helyről kell kódot hívni: Az &#8220;A&#8221; és a &#8220;B&#8221; konstruktora, továbbá a &#8220;B&#8221; osztályban lévő, konstruktoron kívüli inicializálás. A probléma ezen három kódrészlet lefutásának sorrendje.</p>
<p>Első ránézésre a kóddal semmi probléma nincs azon kívül, hogy teljesen haszontalan. Mindkét mező final, így gondolnánk a konstruktor elött inicializálódnak, tehát nem okozhat problémát. Azonban a kód futtatásakor egy csinos NullPointerException kacsint vissza ránk. A futás kimenete:</p>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">class java.lang.String<br />
Exception in thread &quot;main&quot; java.lang.NullPointerException<br />
&nbsp; &nbsp; at AB$B.doSomething(AB.java:22)<br />
&nbsp; &nbsp; at AB$A.&lt;init&gt;(AB.java:8)<br />
&nbsp; &nbsp; at AB$B.&lt;/init&gt;&lt;init&gt;(AB.java:17)<br />
&nbsp; &nbsp; at AB.main(AB.java:27)<br />
&lt;/init&gt;</div></td></tr></tbody></table></div>
<p>Láthatóan a B.doSomething() első sora lefut hiba nélkül, a probléma utána keletkezik. Tehát az &#8220;s&#8221; változó már létezik, az &#8220;o&#8221; viszont nem. A konstruktorok lefutásának sorrendje tehát: s=..,A(),o=..,B(). A két mező között csupán az a különbség, hogy az &#8220;s&#8221; mező típusa megegyezik a futásidejű értékének típusával. Ez meghatározza, hogy a mező a szülő osztály konstruktora előtt vagy után kap értéket. Érdemes kipróbálni, ha az &#8220;s&#8221; mező elöl kivesszük a final kulcsszót, az azt okozza, hogy az is a szülő konstruktor hívása után kap értéket. Vajon hogy határozódik meg a pontos sorrend, mitől függ, hogy hova ütemezi be a java a mezők értékadását? </p>
<p>Nyílván valahogy igyekszik meghatározni, hogy az adott értékadás kiértékelhető-e az osztály örökölt részének inicializálása nélkül vagy sem. Ennek tesztelésére tettem még egy kísérletet, kicsit módosítva a példát:</p>
<div class="codecolorer-container java mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> AB<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">abstract</span> <span style="color: #000000; font-weight: bold;">class</span> A<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #003399;">String</span> a<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> A<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; a <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;abc&quot;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; doSomething<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">abstract</span> <span style="color: #000066; font-weight: bold;">void</span> doSomething<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">class</span> B <span style="color: #000000; font-weight: bold;">extends</span> A<span style="color: #009900;">&#123;</span> &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">String</span> s <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;1234&quot;</span><span style="color: #339933;">+</span>a<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">Object</span> o <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;1234&quot;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> B<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; @Override<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">void</span> doSomething<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span>s.<span style="color: #006633;">getClass</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span>o.<span style="color: #006633;">getClass</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> main<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> args<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">new</span> B<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>Ez a kód is szépen elszáll, méghozzá a B.doSomething() első sorában! Azaz, az explicit hivatkozás egy szülő objektum-beli elemre azt eredményezi, hogy a mező értékadását a szülő konstruktor utánra ütemezi. Elég intelligensnek tűnik a dolog, de mégis beleütközik az ember, mert másra számít. </p>
<p>Persze elkerülhető a dolog ha a konstruktorból hívott absztrakt metódusokat anti-pattern-nek kiáltjuk ki, bár gyakran jól jön. Mégis pontosan mi határozza meg a sorrendet, és lehet-e befolyásolni valahogyan? Van valaki aki nálam sikeresebben guglizott?</p>]]></content:encoded>
			<wfw:commentRss>http://cubussapiens.hu/2009/09/java-konstruktor-hivasi-sorrend/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Java kimenet UTF-8 kódolásban &#8211; második felvonás</title>
		<link>http://cubussapiens.hu/2008/09/java-kimenet-utf-8-kodolasban-masodik-felvonas/</link>
		<comments>http://cubussapiens.hu/2008/09/java-kimenet-utf-8-kodolasban-masodik-felvonas/#comments</comments>
		<pubDate>Mon, 22 Sep 2008 18:30:52 +0000</pubDate>
		<dc:creator>Balage</dc:creator>
				<category><![CDATA[Fejlesztés]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[kompatibilitás]]></category>
		<category><![CDATA[utf8]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Ezt nem lehet megunni, újra és újra hasonló problémákba ütközök. Most kivételesen nem parancssorban kellett UTF-8 kimenetet generálnom, hanem a Java 6 beépített HTTP szerveréről a kliens felé adott generált válaszban merült fel ugyanez a probléma. A különös az volt, hogy működött, mindenféle konverzió nélkül, tehát teljesen nyugodt voltam, hogy ez a kódrészletet jól írtam meg. Órákba tellet rájönnöm, hogy ez a feltételezés hibás volt.
]]></description>
			<content:encoded><![CDATA[<p>Ezt nem lehet megunni, újra és újra hasonló problémákba ütközök. Most kivételesen nem parancssorban kellett UTF-8 kimenetet generálnom, hanem a Java 6 beépített HTTP szerveréről a kliens felé adott generált válaszban merült fel ugyanez a probléma. A különös az volt, hogy működött, mindenféle konverzió nélkül, tehát teljesen nyugodt voltam, hogy ez a kódrészletet jól írtam meg. Órákba tellet rájönnöm, hogy ez a feltételezés hibás volt.<br />
<!--break--><br />
A problémakör egyszerű, bár érdekes. Widget-alapú AJAX-os webalkalmazást fejlesztek az önálló laboromhoz, de erről később. A lényeg az, hogy amikor a felhasználó csatlakozik a szerverhez, az egy generált HTML oldallal válaszol, és minden további feladatra JavaScript kódot küld, amit a kliens lefuttat. A javascript kódban a szövegeket előrelátóan <a href="http://hu.wikipedia.org/wiki/Base64">Base64</a> kódolásban vittem át, így ezekkel probléma nem volt. Nem ez volt a helyzet azonban a generált HTML kóddal. Arra lettem figyelmes, hogy a webalkalmazást megváltoztatva a böngészőben nem jelenik meg semmi..</p>
<p>A helyzet felettébb furcsa volt, a generálás során nem merült fel hiba, sőt, a generált kimenet a szerver oldalon jó volt és az átvitel sem dobott kivételt. A kliens oldalon megérkeztek a fejléc sorai, de nem kapott kimenetet. Nem értettem a problémát, hiszen addig jó volt, és azon a részen nem változtattam. Hosszas próbálgatás és debugolás után rájöttem, hogy a hiba megjelenése erősen korrelál azzal a ténnyel, hogy a generált kimenetben szerepel-e ékezetes karakter. Ekkor merült fel bennem, hogy a probléma a kódolással van.</p>
<p>Tehát, a megoldás az, hogy előkeresem a <a href="http://cubussapiens.hu/2008/04/java-kimenet-utf-8-kodolasban/">korábbi cikkemet</a>, és az ott szereplő megoldást extrapolálom az én esetemre. Azaz, amikor a <a href="http://java.sun.com/javase/6/docs/jre/api/net/httpserver/spec/com/sun/net/httpserver/HttpExchange.html#getResponseBody()">HttpExchange kimeneti adatfolyamát</a> lekérem, egy egyszerű <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/io/PrintStream.html">PrintStream</a> helyett a következő módon wrappolom, és a böngészőt is értesítem róla, hogy milyen kódolásban kap adatot:</p>
<div class="codecolorer-container java mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003399;">PrintStream</span> out <span style="color: #339933;">=</span> &nbsp;<span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">PrintStream</span><span style="color: #009900;">&#40;</span>arg0.<span style="color: #006633;">getResponseBody</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>,<span style="color: #000066; font-weight: bold;">true</span>,<span style="color: #0000ff;">&quot;UTF-8&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
arg0.<span style="color: #006633;">getResponseHeaders</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Content-Type&quot;</span>,<span style="color: #0000ff;">&quot;text/html; charset=UTF-8&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>A nagyobbik fejtörést az okozta, hogy még így se működött, a hiba ugyanaz maradt, csak annyi változott, hogy a <a href="https://addons.mozilla.org/en-US/firefox/addon/60">Web dev toolbar</a> már kijelezte az újonann beadott header sort is. Ekkor megakadt a szemem a következő soron:</p>
<div class="codecolorer-container java mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">arg0.<span style="color: #006633;">sendResponseHeaders</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">200</span>, text.<span style="color: #006633;">toCharArray</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">length</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
out.<span style="color: #006633;">print</span><span style="color: #009900;">&#40;</span>text<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>Ezzel ugye elküldöm a kliensnek hibakódot (200 = OK), illetve a küldött tartalom hosszát. Ez automatikusan hozzáad egy &#8220;Content-Length&#8221; sort a header-ekhez. Amikor ezt írtam, jó ötletnek tünt. De! A java belső UCS kódolásában a karakterek száma nem egyezik meg a byte-ok számával a karakterlánc UTF-8 -beli kódolásában. A megoldás: a sendResponseHeaders() metódus második argumentuma legyen 0. Ez azt jelenti, hogy tetszőleges hosszúságú tartalmat küldhetünk el, a bytesorozat végét az jelzi, hogy bezárjuk a kapcsolatot.</p>
<p>Így tényleg működik. csak az érdekesség kedvéért egy rövid idézet a <a href="http://java.sun.com/javase/6/docs/jre/api/net/httpserver/spec/com/sun/net/httpserver/HttpExchange.html">HttpExchange dokumentációjából</a>:</p>
<pre>"If the call to sendResponseHeaders() specified a fixed response body length, then the exact number of bytes specified in that call must be written to this stream. If too many bytes are written, then write() will throw an IOException. If too few bytes are written then the stream close() will throw an IOException. In both cases, the exchange is aborted and the underlying TCP connection closed."</pre>
<p>Hogy mi ezzel a probléma? Csak az, hogy a dokumentáció szerint kivételt kellett volna kapnom, amikor úgy zárom le, hogy a küldött byte-ok száma nem egyezik az előre megadottal. Ez viszont nem történt meg, hanem egy furcsa, és visszakövethetetlen hibajelenségbe ütköztem. Talán gyorsabban megtalálom a hibát, ha kapok egy értelmes hibaüzenetet.</p>]]></content:encoded>
			<wfw:commentRss>http://cubussapiens.hu/2008/09/java-kimenet-utf-8-kodolasban-masodik-felvonas/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>2D adatszerkezet modellezése Javában</title>
		<link>http://cubussapiens.hu/2008/09/2d-adatszerkezet-modellezese-javaban/</link>
		<comments>http://cubussapiens.hu/2008/09/2d-adatszerkezet-modellezese-javaban/#comments</comments>
		<pubDate>Thu, 18 Sep 2008 21:00:49 +0000</pubDate>
		<dc:creator>thSoft</dc:creator>
				<category><![CDATA[Fejlesztés]]></category>
		<category><![CDATA[adatszerkezet]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[tervezés]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[&#8230;avagy hogyan lehet pozitív tulajdonság a gyengeség és a lustaság. Arról a gyakran előforduló modellről van szó, amikor sorok és oszlopok metszeteiben rácselemek csücsülnek, melyek automatikusan létrejönnek a nekik megfelelő sor-oszlop párra való hivatkozáskor, valamint automatikusan megszűnnek soruk vagy oszlopuk törlése esetén. A megvalósítás kézenfekvőnek tűnik: a sorokban/oszlopokban egy map-ben tároljuk az oszlopokkal/sorokkal indexelve a [...]]]></description>
			<content:encoded><![CDATA[<p>&#8230;avagy hogyan lehet pozitív tulajdonság a gyengeség és a lustaság. <img src='http://cubussapiens.hu/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Arról a gyakran előforduló modellről van szó, amikor sorok és oszlopok metszeteiben rácselemek csücsülnek, melyek automatikusan létrejönnek a nekik megfelelő sor-oszlop párra való hivatkozáskor, valamint automatikusan megszűnnek soruk vagy oszlopuk törlése esetén.<br />
A megvalósítás kézenfekvőnek tűnik: a sorokban/oszlopokban egy map-ben tároljuk az oszlopokkal/sorokkal indexelve a rácselemeket.<br />
<!--break--><br />
Valahogy így:</p>
<div class="codecolorer-container java mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Node <span style="color: #009900;">&#123;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Column <span style="color: #009900;">&#123;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Row <span style="color: #009900;">&#123;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">Map</span> nodes <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">HashMap</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Map</span> getNodes<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #000000; font-weight: bold;">return</span> nodes<span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>Mi a gond ezzel?</p>
<ul>
<li>Ha törlünk egy oszlopot, az összes sor map-jében még ott marad a rá mutató referencia, mint kulcs. Ez memory leakhez vezet: a szemétgyűjtő nem tudja eltakarítani a &#8220;zombi&#8221; oszlopokat és a hozzájuk tartozó, ugyancsak zombi rácselemeket. Ez ráadásul az adatstruktúra perzisztálásánál is problémát jelent.</li>
<li>Hogyan s mikor hozzuk létre a rácselemeket? Mindig, amikor létrehozunk egy oszlopot? Ezt jobban lehetne automatizálni, ráadásul ha nem minden rácspontba akarunk elemet tenni, fölöslegesen hozzuk létre ezeket.</li>
</ul>
<p>Több megoldás is lehetséges, gondolhatnánk elsőre:</p>
<ul>
<li>Gondolkodhatnánk egy címkézett gráfban, és a beépített kollekciók helyett alkalmazhatnánk valamiféle gráfkezelő könyvtárat, pl. a <a href="http://jgrapht.sourceforge.net">JGraphT</a>-t, mely gondoskodik csúcs törlésekor a hozzá tartozó élekről.</li>
<li>Kibővíthetnénk a lista adatszerkezetet eseménykezelőkkel, melyek elem hozzáadásakor és törlésekor végrehajtanak egy megadott kódot.</li>
</ul>
<p>Azonban a probléma megoldható a Java Collections Framework keretein belül, karöltve természetes kiegészítőjével, a <a href="http://larvalabs.com/collections">Collections Generic</a> API-val (a <a href="http://jakarta.apache.org/commons/collections">Commons Collections</a> generikus változata). Nehogy már egy ilyen általános jelenséget ne tudjunk a megannyi hasznos absztrakciót tartalmazó Java nyelv elemeivel modellezni! A kulcsfogalom a <em><a href="http://java.sun.com/javase/6/docs/api/java/lang/ref/WeakReference.html">gyenge referencia</a></em>, mellyel befolyásolhatjuk a garbage collector működését, ezzel rábízva az elárvult elemek törlését.</p>
<p>Javában az alapértelmezett referencia erős (strong), de ezenkívül még létezik a gyenge (weak), lágy (soft) és fantom (phantom) referencia. A weak reference lényege, hogy amennyiben egy objektumra csak ilyenek mutatnak, a szemétgyűjtő teljes lelki nyugalommal eltakarítja. Nekünk pont ez a viselkedés jön kapóra: a map-ben gyenge referenciákat fogunk csak tárolni az oszlopokra/sorokra. (A másik két típus most nem érdekes számunkra, pedig azok is hasznosnak bizonyulhatnak más esetekben.)</p>
<p>A Collections API tartalmazza a <a href="http://java.sun.com/javase/6/docs/api/java/util/WeakHashMap.html">WeakHashMap</a> osztályt, mely a <a href="http://java.sun.com/javase/6/docs/api/java/util/HashMap.html">HashMap</a>-hez hasonló, azonban kulcsai gyenge referenciák. A WeakHashMap ezeket átlátszóan kezeli, önmagától létrehozva és dereferálva nekünk őket. Így programunkban az automatikus törléshez csak két dolgot kell módosítanunk: HashMap helyett WeakHashMap-et használunk, és a kívánt pillanatban meghívjuk a garbage collectort.</p>
<p>A létrehozás pedig <em>lusta map</em> segítségével történik: a rácselemek példányosítása akkor és csak akkor történik, amikor először hivatkozunk az őket azonosító sor-oszlop párosra. Ehhez is kész eszközt kapunk a kezükbe a Collections Generic Libraryben: a <a href="http://collections.sourceforge.net/api/org/apache/commons/collections/map/LazyMap.html">LazyMap</a>-et és az <a href="http://collections.sourceforge.net/api/org/apache/commons/collections/functors/InstantiateFactory.html">InstantiateFactory</a>-t, melyek a Decorator és a Factory pattern alkalmazásával érik el céljukat.</p>
<p>Imhol a forráskód módosított része. Figyelemreméltó, hogy mennyi minden változott&#8230;</p>
<div class="codecolorer-container java mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Row <span style="color: #009900;">&#123;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">Map</span> nodes <span style="color: #339933;">=</span> LazyMap.<span style="color: #006633;">decorate</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">WeakHashMap</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, <span style="color: #000000; font-weight: bold;">new</span> InstantiateFactory<span style="color: #009900;">&#40;</span>Node.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// !</span><br />
<br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>És egy kis tesztosztály, a kiértékelés a kedves olvasó feladata:</p>
<div class="codecolorer-container java mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> GridTest <span style="color: #009900;">&#123;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> main<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> args<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; Grid grid <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Grid<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> i <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; grid.<span style="color: #006633;">getRows</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> Row<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; grid.<span style="color: #006633;">getColumns</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> Column<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>Row row <span style="color: #339933;">:</span> grid.<span style="color: #006633;">getRows</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>Column column <span style="color: #339933;">:</span> grid.<span style="color: #006633;">getColumns</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span>row.<span style="color: #006633;">getNodes</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span>column<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; grid.<span style="color: #006633;">getColumns</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">remove</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #003399;">System</span>.<span style="color: #006633;">gc</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// !</span><br />
&nbsp; <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>Row row <span style="color: #339933;">:</span> grid.<span style="color: #006633;">getRows</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>Column column <span style="color: #339933;">:</span> row.<span style="color: #006633;">getNodes</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">keySet</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span>row.<span style="color: #006633;">getNodes</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span>column<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>Hát ilyen power a Collections Framework, amint már Stampie is <a href="http://cubussapiens.hu/2008/08/java-rendezes-avagy-hogyan-ne-tegyuk/">rámutatott</a>, ami pedig esetleg hiányzik belőle, azt a Collections Generic pótolja. Mi a tanulság? Használjuk ki a nyelvi lehetőségeket, amelyek rendelkezésünkre állnak!</p>]]></content:encoded>
			<wfw:commentRss>http://cubussapiens.hu/2008/09/2d-adatszerkezet-modellezese-javaban/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Platformfüggő fejlesztés Java-ban</title>
		<link>http://cubussapiens.hu/2008/08/platformfuggo-fejlesztes-java-ban/</link>
		<comments>http://cubussapiens.hu/2008/08/platformfuggo-fejlesztes-java-ban/#comments</comments>
		<pubDate>Sat, 30 Aug 2008 17:06:42 +0000</pubDate>
		<dc:creator>Stampie</dc:creator>
				<category><![CDATA[Fejlesztés]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[probléma]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Ritka eset, hogy szükségünk van rá, de velem megesett. Szükségem volt a java-t futtató rendszer típusára és architektúrájára. Ráadásul futásidőben. Az ok egyszerű. SWT alkalmazást fejlesztek, és nem akarok minden platformra külön kiadást csinálni, ne a felhasználó találja ki, hogy milyen rendszert futtat. De ez mellékes, a probléma adott, futásidőben kell meghatározni, melyik platformfüggő csomagot töltsem be?
]]></description>
			<content:encoded><![CDATA[<p>Ritka eset, hogy szükségünk van rá, de velem megesett. Szükségem volt a java-t futtató rendszer típusára és architektúrájára. Ráadásul futásidőben. Az ok egyszerű. SWT alkalmazást fejlesztek, és nem akarok minden platformra külön kiadást csinálni, ne a felhasználó találja ki, hogy milyen rendszert futtat. De ez mellékes, a probléma adott, futásidőben kell meghatározni, melyik platformfüggő csomagot töltsem be?<br />
<!--break--><br />
Egyszerű a megoldás &#8211; írják a lelkes és segítőkész, ám nem teljesen tájékozott fórumozók &#8211; A</p>
<div class="codecolorer-container java mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003399;">System</span>.<span style="color: #006633;">getProperty</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span></div></td></tr></tbody></table></div>
<p>paranccsal le lehet kérni a szabványosított, így minden JVM-ben létező &#8220;os.name&#8221;, &#8220;os.version&#8221; és &#8220;os.arch&#8221; tulajdonságokat, amikkel egyszerű beazonosítani a futtató rendszert. A szabvány valóban rögziti, hogy milyen tulajdonságmezőknek kell lenniük, azonban ezeknek a lehetséges értékeit nem. Most jön csak a szenvedés.</p>
<p>A kisebb problémát az &#8220;os.name&#8221; mező jelenti, ami többé-kevésbé konzisztens értékeket ad vissza a Sun és az alternatív<fn>Ezen a ponton megjegyezném, hogy csak abból az egyszerű tényből kifolyólag hívom a nem a Sun által készített JVM-eket alternatívoknak, mert a Java nyelv szabványát a Sun saját szabványügyi hivatala adja ki. Az igazsághoz hozzátartozik, hogy az említett hivatal úgy jött létre, hogy az ISO visszadobta a Java szabványt, és a Sun ezt a megoldást találta ki a nyelv szabványosítására.</fn> JVM-eknél is. Ezek közül egyetlen kakukktojás a Windows (mi más), aminek minden verziójához tartozik egy saját &#8220;os.name&#8221; érték, és ezen felül az &#8220;os.version&#8221; is tartalmazza a rendszer ritkábban látott verziószámát. Hogy ezzel mi a gond? Csupán az, hogy az 1.5-ös JVM a Vista-t &#8220;Windows NT (Unknown)&#8221;-nak hívja, míg az 1.6-os rendesen &#8220;Windows Vista&#8221;-nak. Értelmesebb lett volna, ha a &#8220;Mac OS&#8221; / &#8220;Mac OS X&#8221;-hez hasonlóan külön jelzik a rendszer két fő ágát, és a verziószám ad bővebb információt a rendszer mibenlétéről. Más rendszerek (pl. Linux) esetén a helyzet jobb, ott tényleg nincs eltérés a verziók között. Íme egy rövid felsorolás az &#8220;os.name&#8221; lehetséges értékeiről: [[http://mindprod.com/jgloss/properties.html#OSNAME]]</p>
<p>Ennél sokkal komolyabb fejtörést okoz a rendszer architektúrájának meghatározása. Ennél rendkívül változatos értékeket tapasztaltam különböző gépeken, rendszertől függetlenül. Még a Sun JVM-ek se konzisztensek ebben. Az még nem túlzottan meglepő, hogy a 64 bites, intel-alapú rendszeremet &#8220;amd64&#8243;-nek hívja, hiszen a disztróm hivatalosan amd64-re van fordítva. Más gépeken viszont szinte véletlenszerűen kerül elő a fent említett megnevezés mellett &#8220;x86_64&#8243;, illetve &#8220;x64&#8243; is. További érdekesség, hogy mivel &#8220;Mac OS X&#8221;-en még nincs 64 bites 1.6os Java, így azt &#8220;i386&#8243;-osnak jelzi. Ebből látszik, hogy a kérdéses mező nem a rendszer, hanem a JVM tulajdonságát adja vissza. Ennél a pontnál elérkeztünk a régebbi, 32 bites rendszerekhez, ami lehet &#8220;x86&#8243;, &#8220;i386&#8243;, &#8220;i686&#8243;, és hasonszőrű társai bármelyike. Utolsóként megemlíteném a Power PC architektúrát, ami lehet &#8220;ppc&#8221;, vagy &#8220;PowerPC&#8221; elnevezésű is.</p>
<p>A fenti mezők értékeire vonatkozólag láthatóan a Sun berkein belül sincs megegyezés, különböző rendszereken, vagy akár csak különböző verziók más-más értéket adhatnak. A legnagyobb probléma mégis az, hogy ez nincs sehol dokumentálva! A néhány kicsit használható gyűjteményt lelkes felhasználók hozták össze, de ezek hiányosak, és/vagy régen frissültek. Íme az általam talált legjobb, ami határozottan kevés: [[http://lopica.sourceforge.net/os.html]].</p>
<p>Végső megoldás lehet kitaposott úton járni, azaz felhasználni egy már létező megoldást, ami talán megmondja, mégis milyen rendszeren vagyok. Hasonló megoldásokban szinte kizátólagosan az [[http://lopica.sourceforge.net/os.html|Ant]] projekt kerül szóba, ami tartalmaz egy osztályt, mely egy szimpla enumerált értéket állít elő a létező operációs rendszereknek megfelelően. Az &#8220;os.arch&#8221; változót pedig csak nemes egyszerűséggel kivezeti a felhasználó számára az összes JVM tulajdonsággal egyetemben. Továbbá az Ant csak fordítás-idejű megoldást kínál, ezzel én nem lettem okosabb.</p>
<p>Végső elkeseredésemben azon kezdtem agyalni, hogy a program első futásakor végigpróbálgatom az összes rendelkezésre álló SWT lib-et, és amelyik nem dob kivételt, az működik. Ha ehhez hozzávesszük, hogy felismerhetünk pár &#8220;os.name&#8221;, &#8220;os.arch&#8221; értéket, akkor nem is olyan elvetemült ötlet.</p>
<h3>(Update) A megoldás</h3>
<p>[[http://cubussapiens.hu/user/30|Happy]] [[http://cubussapiens.hu/node/593#comment-117|hozzászólása]] alapján a zseniálisan egyszerű megoldás:</p>
<div class="codecolorer-container java mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">proba</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.eclipse.core.runtime.internal.adaptor.EclipseEnvironmentInfo</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> EnvInfo <span style="color: #009900;">&#123;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #008000; font-style: italic; font-weight: bold;">/**<br />
&nbsp; &nbsp; &nbsp;* @param args<br />
&nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> main<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> args<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// TODO Auto-generated method stub</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; EclipseEnvironmentInfo eei <span style="color: #339933;">=</span> EclipseEnvironmentInfo.<span style="color: #006633;">getDefault</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span>eei.<span style="color: #006633;">getWS</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">+</span><span style="color: #0000ff;">&quot;.&quot;</span><span style="color: #339933;">+</span>eei.<span style="color: #006633;">getOS</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">+</span><span style="color: #0000ff;">&quot;.&quot;</span><span style="color: #339933;">+</span>eei.<span style="color: #006633;">getOSArch</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span>eei.<span style="color: #006633;">getNL</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>, ami nálam a következő kimenetet adja:</p>
<div class="codecolorer-container text mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">linux.gtk.x86_64<br />
hu_HU</div></td></tr></tbody></table></div>
<p>Stampie jól gondolta, ezt a problémát már megoldották az Eclipse-ben, csak akkor én ezt nem találtam meg. Az [[http://mobius.inria.fr/eclipse-doc/org/eclipse/core/runtime/internal/adaptor/EclipseEnvironmentInfo.html|EclipseEnvironmentInfo]] osztály a org.eclipse.osgi_3.4.0.v20080605-1900.jar csomagban található meg, és ez az swt csomagok elnevezésével kompatiblis jelölésekkel adja meg a rendszer jellemzőit.</p>]]></content:encoded>
			<wfw:commentRss>http://cubussapiens.hu/2008/08/platformfuggo-fejlesztes-java-ban/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Miért is utálom a PHP-t?</title>
		<link>http://cubussapiens.hu/2008/08/miert-is-utalom-a-php-t/</link>
		<comments>http://cubussapiens.hu/2008/08/miert-is-utalom-a-php-t/#comments</comments>
		<pubDate>Mon, 18 Aug 2008 16:45:24 +0000</pubDate>
		<dc:creator>Stampie</dc:creator>
				<category><![CDATA[Fejlesztés]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[programozás]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Utálom a PHP-t. Ez legutóbb akkor jött elő, amikor a nagyobb terveimet próbáltam meg megvalósítani a Drupal kapcsán. Jellemző, hogy a Joomla-t úgy hagytam ott, hogy egy pontnál betelt nálam a pohár a megoldásaival, és kerestem egy másik CMS-t. De most a Drupalnál látom, hogy valahogy ez sem az igazi - API-szinten is el van rontva pár dolog benne szerintem. És ezeket szinte esélytelen, hogy kijavítsák, mert az nem fér bele, hogy minden modult inkompatibilissé tegyenek... Így is kapnak hideget-meleget azért, hogy nem sokat törődnek az API-kompatibilitással.
]]></description>
			<content:encoded><![CDATA[<p>Utálom a PHP-t. Ez legutóbb akkor jött elő, amikor a nagyobb terveimet próbáltam meg megvalósítani a Drupal kapcsán. Jellemző, hogy a Joomla-t úgy hagytam ott, hogy egy pontnál betelt nálam a pohár a megoldásaival, és kerestem egy másik CMS-t. De most a Drupalnál látom, hogy valahogy ez sem az igazi &#8211; API-szinten is el van rontva pár dolog benne szerintem. És ezeket szinte esélytelen, hogy kijavítsák, mert az nem fér bele, hogy minden modult inkompatibilissé tegyenek&#8230; Így is kapnak hideget-meleget azért, hogy nem sokat törődnek az API-kompatibilitással.</p>
<p>De inkább visszatérek az eredeti témához. Hogy miért is utálom a PHP-t? Ez sajnálatos módon több okra vezethető vissza. Ezek közé tartozik az, hogy nagyon sokszor a gányoláson kívül nem találok jobb szót a megoldásaira. Valószínűleg persze a véleményem kialakításában az is szerepet játszott, hogy én nem nagyon írtam programokat benne, csak meglevőket módosítgattam egy kicsit, így csak azt láttam, hogy mások hogyan használják.</p>
<p>Valamint az biztos segített, hogy amikor hajlandó lettem volna megtanulni, méghozzá annyira, hogy könyvet is vásároljak hozzá, sikerült egy tanulási célra használhatatlan könyvet beszerezni &#8211; nem most, valamikor tavaly történt az eset. Emberek: ha a boltokban a PHP &#8211; Fekete könyv című kiadványt látjátok, kerüljétek el messzire. Az még hagyján, hogy a PHP 4-ről, meg annak újdonságairól beszél (ez mondjuk 2007-ben sem igen volt korszerűnek tekinthető), de ahogy beszél róla, az aztán kritikán aluli.</p>
<p>A könyv szerkezete úgy nézett ki, hogy a fejezet elején beszél egy kicsit az elméletről, és utána mutat példákat. Ami viszont kicsit erősnek tűnt, az az, hogy a példáknál nem veszi figyelembe, hogy miről beszélt már, így az első (vagy második) fejezet végén levő példáknál már simán csatlakozott MySQL adatbázishoz, pedig arról csak jóval később írt. És ez csak egy kiragadott példa volt. A példák minőségét nincs módom megítélni, azok a maguk korában akár még jók is lehettek (eltekintve a generált HTML kimenettől, amik az én szememben gányolásnak tűntek&#8230;).</p>
<p>Na jó, térjünk vissza a konkrétabb dolgokra. Ne a mocskos, imperialista, kapitalista kiadókat szidjuk (akik fóliába csomagolva rakták ki az egyetlen példányt a könyvből, hogy nehogy belelapozzak, és rájöjjek, hogy ez a kötet nem nekem való&#8230;), hanem inkább térjünk át a sokkal naprakészebb problémákra.</p>
<p>Ezek közé tartozik a nyelv utasításkönyvtára. Ez gyakorlatilag nem más, mint egy hatalmas, kategorizálatlan felsorolása egy csomó függvénynek. Rengetegnek. Jó, a kategorizálatlan túlzás, de a prefixes megoldás azért annyira nem nevezhető a szervezés csúcsának. Ok, a felépítésében megvan a logika, de ennek ellenére nagyon nehezen tanulható, illetve főleg átlátható.</p>
<p>Erre rájönnek a stringkezelési nehézségek, hiszen minden string bájtfolyam, méghozzá egy karakter egy bájt &#8211; hajrá, UTF-8, így könnyű elszúrni az adatbázist (nekem sikerült még az e107-es időkben &#8211; eltartott egy darabig, amíg találtam rá megoldást, hogyan kellene kicsit automatizáltan rendbe rakni), kivéve, ha megadott prefixű stringkezelőfüggvényeket használunk. És még sorolhatnám.</p>
<p>Ezután már meg sem kellene lepődni, hogy helyenként olyan függvények vannak, amik típusos nyelveken nevelkedett agyamnak iszonyú hackelésnek tűnnek: van rá lehetőség, hogy függvények neveit egy (string)tömbbe belepakolva az összes függvényt meghívjuk egy adott paraméterezéssel (<em>call_user_func_array</em>, <em>call_user_method_array</em> és társairól van szó). Ezt kivételes csak onnan tudom, hogy a Dokuwiki parserét megpróbáltam átlátni, hogyan működik. Na, ezeket nagyon nehéz aggyal felfogni &#8211; pláne, ha a kódban egyszerre két helyen van karbantartva a függvények listája, stb.</p>
<p>Az objektum-orientált rendszerén meg látszik, hogy utólag lett belerakva a rendszerbe, nem pedig előre odatervezték. Amikor próbálkoztam vele, viszonylag gyakran beleütköztem egyes hiányosságaiba &#8211; jó, tény, én Java után próbálkoztam vele, így más hozzáállással jöttem. Megpróbáltam volna kihasználni az OO dolgait. De láttam, hogy mit raktak össze az Enterprise Java-ra (igaz, csak a felszínt kapargattuk, de azután PHP-t írni elég gányolás)&#8230;</p>
<p>Ezután mondjuk fel lehetne róni egyfelől nekem, másfelől a világnak, hogy miért nem javítunk a helyzeten: akár azzal, hogy nem PHP alapú scripteket futtatunk szerte a neten, akár azzal, hogy egyszerűen kijavítjuk a PHP-t. A válasz meg sajnálatos módon az, hogy a PHP-ból valami viszonylag friss kimutatás szerint többnyire a 4-es változat van telepítve, amikor már évek(!) óta van 5-ös, és szintén évek óta készül a 6-os&#8230; És még ez is számít. Az 5-ös PHP még mindig jobb, mint a 4-es volt&#8230;</p>
<p>A más nyelvekkel meg más problémák vannak: Java-alapon kis oldalt nem éri meg üzemeltetni, túl nagy az infrastruktúra igénye, éppen ezért kevesen foglalkoznak vele a felhasználók számára is elérhető módon. Érdekes módon viszont nagy rendszerek esetére jól skálázódik (sokkal jobban, mint az alternatívák)- látszik, hogy erre tervezték. Lehetne jönni a Ruby-val (tipikusan on Rails), ez nagyon erőforrásigényes játék, lehetne még kismillió egyéb scriptnyelvet választani, de mindegyikkel az a gond, hogy a PHP-t használja a nagy többség, ezért váltani nagy költség, ugyanis teljesen más logikába kell beletanulni az üzemeltetésnél, mások a tipikus problémák, hibaüzenetek, más filozófiára van szükség a fejlesztéshez (jó, ahogy mondják, FORTRAN-t minden nyelven lehet írni, de ennél azért jobbak is lehetnénk). Szóval váltani drága, de hosszú távon maradni is&#8230;</p>
<p>Mindent a maga idejében&#8230; Reménykedjünk, hogy a lepény-hal meg utoljára&#8230;</p>]]></content:encoded>
			<wfw:commentRss>http://cubussapiens.hu/2008/08/miert-is-utalom-a-php-t/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Java rendezés &#8211; avagy hogyan ne tegyük</title>
		<link>http://cubussapiens.hu/2008/08/java-rendezes-avagy-hogyan-ne-tegyuk/</link>
		<comments>http://cubussapiens.hu/2008/08/java-rendezes-avagy-hogyan-ne-tegyuk/#comments</comments>
		<pubDate>Thu, 14 Aug 2008 16:15:30 +0000</pubDate>
		<dc:creator>Stampie</dc:creator>
				<category><![CDATA[Fejlesztés]]></category>
		<category><![CDATA[adatszerkezet]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[A Java Collection könyvtára remek munka - könnyen használható, mégis sokoldalú API-t biztosít. Megfelelő listákhoz, gráfreprezentációkhoz és feltételezem, hogy még sok minden egyébhez.

Ehhez képest nem (sokkal) bonyolultabb kezelni, mint egy tömböt. Sőt, a C nyelv tömbkezeléséhez képest sokkal egyszerűbb is... :-)

Ami nekem különösen tetszik, az a beépített rendezési lehetőségek: a <em>Collections.sort</em> statikus metódus használatával saját <em>Comparator</em> segítségével lehet rendezéseket definiálni.
]]></description>
			<content:encoded><![CDATA[<p>A Java Collection könyvtára remek munka &#8211; könnyen használható, mégis sokoldalú API-t biztosít. Megfelelő listákhoz, gráfreprezentációkhoz és feltételezem, hogy még sok minden egyébhez.</p>
<p>Ehhez képest nem (sokkal) bonyolultabb kezelni, mint egy tömböt. Sőt, a C nyelv tömbkezeléséhez képest sokkal egyszerűbb is&#8230; <img src='http://cubussapiens.hu/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Ami nekem különösen tetszik, az a beépített rendezési lehetőségek: a <em>Collections.sort</em> statikus metódus használatával saját <em>Comparator</em> segítségével lehet rendezéseket definiálni.</p>
<p>Ezután szinte magától adódott már, hogy amikor nekem egy objektumhierarchia reprezentálására van szükségem, akkor ahhoz ezt a beépített könyvtári osztályokat használjam. Az általam használt algoritmus (most ezt nem részletezném a szükséges tömörség miatt) feltételezte, hogy a hierarchia elemeit felülről lefelé adom be (azaz mindig előbb az őst adom be, és csak utána a leszármazottakat). Miután ezt a bemenetemről nem tudtam feltételezni, ezért adódott a dolog, írjunk rá egy rendezést, saját komparátorral.</p>
<div class="codecolorer-container java5 mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="java5 codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #006600; font-weight: bold;">int</span> compare<span style="color: #009900;">&#40;</span>IEntity i1, IEntity i2<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; &nbsp;font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>i1.<span style="color: #006633;">isSubtypeOf</span><span style="color: #009900;">&#40;</span>i2<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">return</span> -<span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; &nbsp;font-weight: bold;">else</span> <span style="color: #000000; &nbsp;font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>i2.<span style="color: #006633;">isSubtypeOf</span><span style="color: #009900;">&#40;</span>i1<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; &nbsp;font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">return</span> i1.<span style="color: #006633;">getFullyQualifiedName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">compareTo</span><span style="color: #009900;">&#40;</span>i2.<span style="color: #006633;">getFullyQualifiedName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>Szép, olvasható kód, és pontosan azt írja le, amit szeretnék. Igaz? Hisz itt látszik, hogy szépen az öröklési hierarchia szerint rendezi a mezőket. Amikor ezt a kódot úgy nagyjából egy hónapja megírtam, akkor működött is &#8211; igaz, csak erőteljesen korlátozott tesztelés volt, mert ez csak egy nagyon parányi része volt a dolognak, amit csináltam, és utána pedig egy kicsit ezt a részt jegeltem.</p>
<p>Ehhez képest most jött a feketeleves, hogy amikor egy kicsit változott a környezet, amiben az új funkciót teszteltem, kaptam egy hatalmas nullpointer exception-t. Remek&#8230;</p>
<p>Némi játék után (ugyanis a futási környezet lenyelte a kivételt, és csak az üzetenet jelenítette meg, ami nullpointer exception-nél mindig &#8220;&#8221;, azaz nem látszik), kiderítettem, hogy a gondot az okozza, hogy egy objektum kapcsán próbálok hivatkozni az ősére egy saját adatszerkezetben, de ebbe az adatszerkezetbe nem került bele. Ez pedig csak úgy lehetséges, ha az eredeti rendezésnél valami miatt a leszármazott előbbre kerül, mint az őse (általában nem, de az én programomban igen).</p>
<p>Kíváncsi vagyok, hogy hány ember látja, hogy hol is van a probléma a fenti komparátorral, hogyan jöhet össze, hogy a beépített Java sort algoritmus is ezt a rossz eredményt adja ki&#8230;</p>
<p>Tökéletes magyarázatom nincs a problémára, de a hiba oka nagyjából két dolog lehet. Egyfelől a definiált komparátor csak egy részben rendezéshez ad megfelelő támpontot, másrészt a Java feltehetőleg a qsort algoritmust használja, ami nem végzi el az összehasonlítást az összes párra, így tipikusan nem hasonlít össze minden egyes elemet minden másik elemmel.</p>
<p>Van még egy tényező, ami a rendezési eljárást még kevésbé  egyértelművé teszi, ez pedig az egymástól akár teljesen független ágak a hierarchiában. Az eredeti példáimban ezekből kevés volt, míg a példa, amin kiakadt a program, viszonylag sok, egymástól független ágat tartalmazott, ezzel jócskán megnehezítve az algoritmus munkáját.</p>
<p>Ötletem nem volt, hogyan kellene működővé varázsolni a rendezést egy átírt komparátorral, ezért más, korábbi tanulmányokhoz nyúltam vissza: a bsz-en/algoritmuselméleten bemutatott topologikus rendezéshez nyúltam vissza. Ugyan az jóval erősebb rendezési feltétel, mint amire nekem konkrétan szükségem volna, de ezért cserébe viszonylag kevés munkával lekódolható, és nem is túlságosan lassú (jó, ez persze relatív).</p>
<p>Persze ennek a kódolásakor is segítségemre volt a Java Collections API, még így is kevesebb, mint 20 sor volt a teljes rendezési eljárás, amit még zárásnak beszúrok az írás végé elé.</p>
<div class="codecolorer-container java5 mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br /></div></td><td><div class="java5 codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; <span style="color: #008000; font-style: italic; font-weight: bold;">/**<br />
&nbsp; &nbsp; &nbsp;* Creates a topological ordering on the modelelements<br />
&nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">private</span> List<span style="color: #339933;">&lt;</span>IEntity<span style="color: #339933;">&gt;</span> orderModelElements<span style="color: #009900;">&#40;</span>List<span style="color: #339933;">&lt;</span>IEntity<span style="color: #339933;">&gt;</span> elementsToOrdered<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; List<span style="color: #339933;">&lt;</span>IEntity<span style="color: #339933;">&gt;</span> orderedElements = <span style="color: #000000; font-weight: bold;">new</span> ArrayList<span style="color: #339933;">&lt;</span>IEntity<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; &nbsp;font-weight: bold;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>elementsToOrdered.<span style="color: #006633;">isEmpty</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//The currentLevel is needed in order to remove all the elements that</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//do not have any ancestors, not only the first one</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//If we delete the elements straight from the elementsToOrdered list,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//the iterator in the for cycle will not work.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; List<span style="color: #339933;">&lt;</span>IEntity<span style="color: #339933;">&gt;</span> currentLevel = <span style="color: #000000; font-weight: bold;">new</span> ArrayList<span style="color: #339933;">&lt;</span>IEntity<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; &nbsp;font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>IEntity element : elementsToOrdered<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Collection<span style="color: #339933;">&lt;</span>IModelElement<span style="color: #339933;">&gt;</span> ancestors = <span style="color: #000000; font-weight: bold;">new</span> ArrayList<span style="color: #339933;">&lt;</span>IModelElement<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ancestors.<span style="color: #006633;">addAll</span><span style="color: #009900;">&#40;</span>element.<span style="color: #006633;">getSupertypes</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ancestors.<span style="color: #006633;">retainAll</span><span style="color: #009900;">&#40;</span>entities<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><span style="color: #666666; font-style: italic;">//remove all non-entities</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; &nbsp;font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>ancestors<span style="color: #339933;">!</span>=<span style="color: #006600; font-weight: bold;">null</span> <span style="color: #339933;">&amp;&amp;</span> orderedElements.<span style="color: #006633;">containsAll</span><span style="color: #009900;">&#40;</span>ancestors<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; currentLevel.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>element<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; orderedElements.<span style="color: #006633;">addAll</span><span style="color: #009900;">&#40;</span>currentLevel<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; elementsToOrdered.<span style="color: #006633;">removeAll</span><span style="color: #009900;">&#40;</span>currentLevel<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">return</span> orderedElements<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>És hogy miért is írtam ezt így ide meg? Ennek két oka is van: egyrészt egy nagyon önző, magamat szem előtt tartó indok: ha valaki el tudja esetleg mondani nekem, hogyan kellene a komparátort kijavítani, esetleg részletesebben elmagyarázza csak, hogy miért is hasal el az a komparátor a quick sorton (ha quick sort), nagy örömmel veszem akármilyen formában a reakcióját. Másfelől pedig okulásnak is akart menni mások számára, hogy esetleg nekik ne kelljen órákat bogarászniuk egy pár ezer soros kódbázisban, hogy pontosan hogyan is adódhat az a nullpointerexception.</p>]]></content:encoded>
			<wfw:commentRss>http://cubussapiens.hu/2008/08/java-rendezes-avagy-hogyan-ne-tegyuk/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Java osztályok tárolása MySQL adatbázisban</title>
		<link>http://cubussapiens.hu/2008/06/java-osztalyok-tarolasa-mysql-adatbazisban/</link>
		<comments>http://cubussapiens.hu/2008/06/java-osztalyok-tarolasa-mysql-adatbazisban/#comments</comments>
		<pubDate>Sun, 22 Jun 2008 08:27:25 +0000</pubDate>
		<dc:creator>Balage</dc:creator>
				<category><![CDATA[Fejlesztés]]></category>
		<category><![CDATA[hogyancsináld]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[A cím talán megtévesztő lehet, most nem arról van szó, hogy hogyan lehet szérializált osztálypéldányokat tárolni adatbázisban. Ehelyett magukat a Java osztályokat (típusokat) tárolom ilyen módon. Ez megtehető, hiszen a Java futásidőben tölti be az osztályokat, egészen pontosan az osztály első aktív használata elött. A továbbiakban a cikk feltételezi a Java és a MySQL alapszintű ismeretét, és a [[http://java.sun.com/javase/technologies/database/&#124;JDBC]] használatát se fogom részletezni. Kezdetnek essen pár szó a Java osztálybetöltő mechanizmusáról.
]]></description>
			<content:encoded><![CDATA[<p>A cím talán megtévesztő lehet, most nem arról van szó, hogy hogyan lehet szérializált osztálypéldányokat tárolni adatbázisban. Ehelyett magukat a Java osztályokat (típusokat) tárolom ilyen módon. Ez megtehető, hiszen a Java futásidőben tölti be az osztályokat, egészen pontosan az osztály első aktív használata elött. A továbbiakban a cikk feltételezi a Java és a MySQL alapszintű ismeretét, és a [[http://java.sun.com/javase/technologies/database/|JDBC]] használatát se fogom részletezni. Kezdetnek essen pár szó a Java osztálybetöltő mechanizmusáról.<br />
<!--break--><br />
A Java ClassLoader osztály használható arra, hogy egy keresett osztályt betöltsön a memóriába. Minden JVM indulásakor létrejön egy alapértelmezett rendszer ClassLoader, és ha nem teszünk semmit ez marad végig az egyetlen ilyen jellegű objektum a JVM-ben. A ClassLoader-ek működésének megértéséhez meg kell ismernünk néhány metódusát:</p>
<ul>
<li>A konstruktor:
<div class="codecolorer-container java mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003399;">ClassLoader</span><span style="color: #009900;">&#40;</span><span style="color: #003399;">ClassLoader</span> parent<span style="color: #009900;">&#41;</span></div></td></tr></tbody></table></div>
<p>: Minden ClassLoader-nek létezik pontosan egy szűlője (kivéve az alapértelmezett ClassLoader-t), ugyanis mielött az adott ClassLoader megpróbálná betölteni a keresett osztályt, megkérdezi a szülőt, hogy ő be tudja-e tölteni, és csak akkor próbálkozik meg, ha a még nincs betöltve, és a szülő sem tudja betölteni.</li>
<li>
<div class="codecolorer-container java mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">Class</span> loadClass<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> name<span style="color: #009900;">&#41;</span></div></td></tr></tbody></table></div>
<p>:ez hívódik meg, amikor felmerül az igény egy osztály betöltésére. Ez a metódus elöször meghívja a szülő ClassLoader hasonló metódusát, és ha az ClassNotFoundException-t dob, akkor meghívja ezen osztály findClass metódusát.</li>
<li>
<div class="codecolorer-container java mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">Class</span> findClass<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> name<span style="color: #009900;">&#41;</span></div></td></tr></tbody></table></div>
<p>:a fentiekből látszik, hogy ez a metódus hívódik meg akkor, ha már ránk hárult az osztály betöltésének a feladata. Ha új ClassLoader-t írunk, rendszerint ezt a függvényt akarjuk felülírni.</li>
<li>
<div class="codecolorer-container java mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">Class</span> defineClass<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> name, <span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> b, <span style="color: #000066; font-weight: bold;">int</span> off, <span style="color: #000066; font-weight: bold;">int</span> len<span style="color: #009900;">&#41;</span></div></td></tr></tbody></table></div>
<p>:ez a lényeg. Ez a függvény hozza létre az osztályt a memóriában a beolvasott bytecode-ból, aminek meg kell egyeznie egy &#8220;.class&#8221; fájl tartalmával.</li>
</ul>
<p>Már látszik a turpisság: a fentiek alapján lehet írni egy ClassLoader-t, ami nem fájlból, hanem adatbázisból olvassa be a megfelelő bytesorozatot. Első lépésként írjuk meg az adatbázis réteget, ami a kérdéses bytecode-ot tudja menteni/kiolvasni az adatbázisból (az adatbázisba a bytecode-ot Base64 kódolásban mentem, amit egy segédosztály végez. Lásd: lent. Ugyanúgy nem térek ki a File beolvasására, annak a megoldásában is a Google segített):</p>
<div class="codecolorer-container java mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">mysqlclasses</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.io.File</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.io.FileInputStream</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.io.IOException</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.io.InputStream</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.sql.Connection</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.sql.ResultSet</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.sql.Statement</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> ClassSaver <span style="color: #009900;">&#123;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> getBytesFromFile<span style="color: #009900;">&#40;</span><span style="color: #003399;">File</span> file<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">IOException</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; .....<br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> saveToDB<span style="color: #009900;">&#40;</span><span style="color: #003399;">Connection</span> con, <span style="color: #003399;">String</span> name, <span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> data<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">try</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003399;">Statement</span> s <span style="color: #339933;">=</span> con.<span style="color: #006633;">createStatement</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; s.<span style="color: #006633;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;CREATE TABLE IF NOT EXISTS classes (name VARCHAR(120) NOT NULL,bytecode TEXT)&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003399;">String</span> bytecode <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">String</span><span style="color: #009900;">&#40;</span>Base64Coder.<span style="color: #006633;">encode</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003399;">ResultSet</span> rs <span style="color: #339933;">=</span> s.<span style="color: #006633;">executeQuery</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SELECT * FROM classes WHERE name = '&quot;</span><span style="color: #339933;">+</span>name<span style="color: #339933;">+</span><span style="color: #0000ff;">&quot;'&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>rs.<span style="color: #006633;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//update</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; s.<span style="color: #006633;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;UPDATE classes SET bytecode = '&quot;</span><span style="color: #339933;">+</span>bytecode<span style="color: #339933;">+</span><span style="color: #0000ff;">&quot;' WHERE name = '&quot;</span><span style="color: #339933;">+</span>name<span style="color: #339933;">+</span><span style="color: #0000ff;">&quot;'&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #000000; font-weight: bold;">else</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//insert</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; s.<span style="color: #006633;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;INSERT INTO classes SET name = '&quot;</span><span style="color: #339933;">+</span>name<span style="color: #339933;">+</span><span style="color: #0000ff;">&quot;', bytecode = '&quot;</span><span style="color: #339933;">+</span>bytecode<span style="color: #339933;">+</span><span style="color: #0000ff;">&quot;'&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #000000; font-weight: bold;">catch</span><span style="color: #009900;">&#40;</span><span style="color: #003399;">Exception</span> e<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003399;">System</span>.<span style="color: #006633;">err</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span>e.<span style="color: #006633;">getMessage</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> loadFromDB<span style="color: #009900;">&#40;</span><span style="color: #003399;">Connection</span> con, <span style="color: #003399;">String</span> name<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">try</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003399;">Statement</span> s <span style="color: #339933;">=</span> con.<span style="color: #006633;">createStatement</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003399;">ResultSet</span> rs <span style="color: #339933;">=</span> s.<span style="color: #006633;">executeQuery</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SELECT * FROM classes WHERE name = '&quot;</span><span style="color: #339933;">+</span>name<span style="color: #339933;">+</span><span style="color: #0000ff;">&quot;'&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>rs.<span style="color: #006633;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">return</span> Base64Coder.<span style="color: #006633;">decode</span><span style="color: #009900;">&#40;</span>rs.<span style="color: #006633;">getString</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;bytecode&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #000000; font-weight: bold;">else</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #000000; font-weight: bold;">catch</span><span style="color: #009900;">&#40;</span><span style="color: #003399;">Exception</span> e<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003399;">System</span>.<span style="color: #006633;">err</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span>e.<span style="color: #006633;">getMessage</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>Ezek után következzék a MySQLClassLoader:</p>
<div class="codecolorer-container java mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">mysqlclasses</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.sql.Connection</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #008000; font-style: italic; font-weight: bold;">/**<br />
&nbsp;* @author balage<br />
&nbsp;*<br />
&nbsp;*/</span><br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> MySQLClassLoader <span style="color: #000000; font-weight: bold;">extends</span> <span style="color: #003399;">ClassLoader</span> <span style="color: #009900;">&#123;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #003399;">Connection</span> con<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> MySQLClassLoader<span style="color: #009900;">&#40;</span><span style="color: #003399;">Connection</span> sqlcon<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; con <span style="color: #339933;">=</span> sqlcon<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> MySQLClassLoader<span style="color: #009900;">&#40;</span><span style="color: #003399;">Connection</span> sqlcon,<span style="color: #003399;">ClassLoader</span> arg0<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span>arg0<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; con <span style="color: #339933;">=</span> sqlcon<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; @Override<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">protected</span> Class<span style="color: #339933;">&lt;</span> <span style="color: #339933;">?&gt;</span> findClass<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> name<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">ClassNotFoundException</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Searching for class: &quot;</span><span style="color: #339933;">+</span>name<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> data <span style="color: #339933;">=</span> ClassSaver.<span style="color: #006633;">loadFromDB</span><span style="color: #009900;">&#40;</span>con, name<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>data <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">return</span> defineClass<span style="color: #009900;">&#40;</span>name, data, <span style="color: #cc66cc;">0</span>, data.<span style="color: #006633;">length</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #000000; font-weight: bold;">else</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">ClassNotFoundException</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>Meglepően egyszerű, nemde? A kipróbálásához létrhozunk pár egyszerű osztályt:</p>
<div class="codecolorer-container java mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">test</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">interface</span> Test <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> some<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<div class="codecolorer-container java mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">test</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> TestA <span style="color: #000000; font-weight: bold;">implements</span> Test <span style="color: #009900;">&#123;</span><br />
<br />
&nbsp; &nbsp; @Override<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> some<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;I'm an A instance.&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<div class="codecolorer-container java mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">test</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> TestB <span style="color: #000000; font-weight: bold;">implements</span> Test <span style="color: #009900;">&#123;</span><br />
<br />
&nbsp; &nbsp; @Override<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> some<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;I'm a B instance.&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>Az egyszerűbb tesztelés érdekében hoztam létre egy Interface-t is, ami fordítás időben ismert, így egyszerűen meghívható a some() metódus. A létrehozott osztályokkat most le kell fordítani, és be lehet írni az adatbázisba:</p>
<div class="codecolorer-container java mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">Class</span>.<span style="color: #006633;">forName</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;com.mysql.jdbc.Driver&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
<span style="color: #003399;">Connection</span> con <span style="color: #339933;">=</span> <span style="color: #003399;">DriverManager</span>.<span style="color: #006633;">getConnection</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;jdbc:mysql://localhost:3306/test&quot;</span>, <span style="color: #0000ff;">&quot;balage&quot;</span>, <span style="color: #0000ff;">&quot;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
Test a <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> TestA<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
a.<span style="color: #006633;">some</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
Test b <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> TestB<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
b.<span style="color: #006633;">some</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
ClassSaver.<span style="color: #006633;">saveToDB</span><span style="color: #009900;">&#40;</span>con, a.<span style="color: #006633;">getClass</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, ClassSaver.<span style="color: #006633;">getBytesFromFile</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">File</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;bin/test/TestA.class&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
ClassSaver.<span style="color: #006633;">saveToDB</span><span style="color: #009900;">&#40;</span>con, b.<span style="color: #006633;">getClass</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, ClassSaver.<span style="color: #006633;">getBytesFromFile</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">File</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;bin/test/TestB.class&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>Ezen a ponton érdemes ellenőrizni az adatbázis tartalmát, ahol jól láthatóan szerepel egy &#8220;classes&#8221; tábla, benne a két osztály bytecode-jával. Ezek után lehet kiovasni onnan őket a következő kóddal (<b>Arra vigyázzunk, hogy a kiolvasandó osztályok NE legyenek elérhetőek a classpath-ban, különben az adatbázis helyett az alapértelmezett ClassLoader fogja őket betölteni!</b>):</p>
<div class="codecolorer-container java mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">Class</span>.<span style="color: #006633;">forName</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;com.mysql.jdbc.Driver&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
<span style="color: #003399;">Connection</span> con <span style="color: #339933;">=</span> <span style="color: #003399;">DriverManager</span>.<span style="color: #006633;">getConnection</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;jdbc:mysql://localhost:3306/test&quot;</span>, <span style="color: #0000ff;">&quot;balage&quot;</span>, <span style="color: #0000ff;">&quot;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
MySQLClassLoader loader <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> MySQLClassLoader<span style="color: #009900;">&#40;</span>con<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
Class<span style="color: #339933;">&lt;</span> <span style="color: #339933;">?&gt;</span> clsa <span style="color: #339933;">=</span> loader.<span style="color: #006633;">loadClass</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;test.TestA&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
Test a <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>Test<span style="color: #009900;">&#41;</span>clsa.<span style="color: #006633;">newInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
a.<span style="color: #006633;">some</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>Ha mindent jól csinálunk, a kimeneten a TestA osztály üdvözlőüzenete elött látni fogjuk a MySQLClassLoader-ben elrejtett kiírást is, ami egyértelműen jelzi, hogy valóban ő olvasta be az osztályt. Siker. Mielött még kikiáltanám a cikk végét, had tegyek pár megjegyzést, ami szükséges lehet a módszer komolyabb használatához:</p>
<p>Jól láthatóan szövegként hivatkozunk a betölteni kívánt test.TestA osztályra. Ekkor felmerül a kérdés, mi van azokkal az osztályokkal, amikre a betöltött test.TestA osztály hivatkozik? Például létrehoz egy test.TestB osztályt, ami ugyancsak az adatbázisból érhető el, és nem szerepel a megadott classpath-ban. A válasz egyszerű. Azokat akkor próbálja betölteni, amikor aktívan használni próbáljuk. Akkor az osztály nevét átadja az alapértelmezett ClassLoader-nek, ami megkeresi a classpath-ban és.. ClassNotFoundException. A probléma ott van, hogy arra már nem a mi MySQLClassLoader-ünket használja. A teendő tehát: alapértelmezetté kell tenni a létrehozott MySQLClassLoader-t, amit megtehetünk az aktuális Thread ismeretében:</p>
<div class="codecolorer-container java mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">MySQLClassLoader loader <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> MySQLClassLoader<span style="color: #009900;">&#40;</span>con<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #003399;">Thread</span>.<span style="color: #006633;">currentThread</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">setContextClassLoader</span><span style="color: #009900;">&#40;</span>loader<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>Ezen sor után a futásidőben felmerült osztályhivatkozásokat már az általunk megadott ClassLoader-rel fogja betölteni. Kiemelném, hogy ekkor is létezik a MySQLClassLoader szűlője, ami prioritást élvez, azaz mindig az próbálja meg betölteni a keresett osztályt elsőként (persze csak akkor, ha nincs még betöltve).</p>
<p>Még egy probléma: az általunk létrehozot ClassLoader-t csak futásidőben tudjuk használni, a javac fordításkor csak a beépített ClassLoader-t tudja használni, azaz fordításkor minden hivatkozott osztálynak kéznél kell lennie, csak fordítás után lehet az egyes osztályokat bepakolni az adatbázisba. Ami után viszont az adatbázisból hivatkozott .class fájlok törölhetőek a classpath-ból. A programunkat indító osztálynak, és a MySQLClassLoader-nek viszont minden esetben elérhetőnek kell lennie a classpath-ban, ugyanis a java indulásakor csak az alapértelmezett ClassLoader áll rendelkezésünkre.</p>
<p>Végezetül pár hasznos link:</p>
<ul>
<li>[[http://java.sun.com/docs/books/tutorial/ext/basics/load.html]] Egy részletesebb leírás a Java ClassLoader-ek működéséről</li>
<li>[[http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Class.html]] A Class metaosztály javadoc-ja</li>
<li>[[http://java.sun.com/j2se/1.4.2/docs/api/java/lang/ClassLoader.html]] A ClassLoader osztály javadoc-ja</li>
<li>[[http://www.source-code.biz/snippets/java/2.htm]] A Base64 kódolást végző osztály</li>
<li>[[http://www.java-tips.org/java-se-tips/java.io/reading-a-file-into-a-byte-array.html]] Egy függvény, ami egy fájlból beolvassa a byte-okat tömbbe</li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://cubussapiens.hu/2008/06/java-osztalyok-tarolasa-mysql-adatbazisban/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
