<?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>Kevin&#039;s Life</title>
	<atom:link href="http://blog.lckymn.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.lckymn.com</link>
	<description>IT, Java, Ubuntu, Linux</description>
	<lastBuildDate>Thu, 11 Mar 2010 07:26:04 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Code Bubbles &#8211; Cool Java IDE</title>
		<link>http://blog.lckymn.com/2010/03/11/code-bubbles-cool-java-ide/</link>
		<comments>http://blog.lckymn.com/2010/03/11/code-bubbles-cool-java-ide/#comments</comments>
		<pubDate>Thu, 11 Mar 2010 07:26:04 +0000</pubDate>
		<dc:creator>Kevin</dc:creator>
				<category><![CDATA[Development Tools]]></category>
		<category><![CDATA[IT]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Code Bubbles]]></category>
		<category><![CDATA[IDE]]></category>

		<guid isPermaLink="false">http://blog.lckymn.com/?p=490</guid>
		<description><![CDATA[<div id="attachment_493" class="wp-caption alignnone" style="width: 970px"><a href="http://blog.lckymn.com/wp-content/uploads/2010/03/CodeBubbles.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2010/03/CodeBubbles.jpg" alt="Code Bubbles - Cool Java IDE" title="Code Bubbles - Cool Java IDE" width="960" height="720" class="size-full wp-image-493" /></a><p class="wp-caption-text">Code Bubbles - Cool Java IDE</p></div>
<p>Seeing is believing so just visit <a href="http://www.cs.brown.edu/people/acb/codebubbles_site.htm" target="_blank">http://www.cs.brown.edu/people/acb/codebubbles_site.htm</a> and watch the video.
What an awesome IDE!!!</p>
]]></description>
			<content:encoded><![CDATA[<div id="attachment_493" class="wp-caption alignnone" style="width: 970px"><a href="http://blog.lckymn.com/wp-content/uploads/2010/03/CodeBubbles.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2010/03/CodeBubbles.jpg" alt="Code Bubbles - Cool Java IDE" title="Code Bubbles - Cool Java IDE" width="960" height="720" class="size-full wp-image-493" /></a><p class="wp-caption-text">Code Bubbles - Cool Java IDE</p></div>
<p>Seeing is believing so just visit <a href="http://www.cs.brown.edu/people/acb/codebubbles_site.htm" target="_blank">http://www.cs.brown.edu/people/acb/codebubbles_site.htm</a> and watch the video.<br />
What an awesome IDE!!!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lckymn.com/2010/03/11/code-bubbles-cool-java-ide/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google Collections Library 1.0 &#8211; FINAL</title>
		<link>http://blog.lckymn.com/2009/12/31/google-collections-library-1-0-final/</link>
		<comments>http://blog.lckymn.com/2009/12/31/google-collections-library-1-0-final/#comments</comments>
		<pubDate>Thu, 31 Dec 2009 09:29:13 +0000</pubDate>
		<dc:creator>Kevin</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Google Collections Library]]></category>

		<guid isPermaLink="false">http://blog.lckymn.com/?p=479</guid>
		<description><![CDATA[<p>Google has eventually released <a href="http://code.google.com/p/google-collections/" target="_blank">Google Collections Library</a> 1.0 Final version. <img src='http://blog.lckymn.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Now I can use it for my project. I was actually more looking forward to its release than the release of Spring Framework 3.0. </p>
<p>Download Page: <a href="http://code.google.com/p/google-collections/downloads/detail?name=google-collect-1.0.zip" target="_blank">Google Collections Library 1.0 &#8211; FINAL</a></p>
<p>Maven users can simply add the following dependency info to use Google Collections Library 1.0 &#8211; FINAL.</p>

&#60;dependency&#62;
	&#60;groupId&#62;com.google.collections&#60;/groupId&#62;
	&#60;artifactId&#62;google-collections&#60;/artifactId&#62;
	&#60;version&#62;1.0&#60;/version&#62;
	&#60;type&#62;jar&#60;/type&#62;
	&#60;scope&#62;compile&#60;/scope&#62;
&#60;/dependency&#62;

]]></description>
			<content:encoded><![CDATA[<p>Google has eventually released <a href="http://code.google.com/p/google-collections/" target="_blank">Google Collections Library</a> 1.0 Final version. <img src='http://blog.lckymn.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Now I can use it for my project. I was actually more looking forward to its release than the release of Spring Framework 3.0. </p>
<p>Download Page: <a href="http://code.google.com/p/google-collections/downloads/detail?name=google-collect-1.0.zip" target="_blank">Google Collections Library 1.0 &#8211; FINAL</a></p>
<p>Maven users can simply add the following dependency info to use Google Collections Library 1.0 &#8211; FINAL.</p>
<pre class="brush: xml; gutter: false;">
&lt;dependency&gt;
	&lt;groupId&gt;com.google.collections&lt;/groupId&gt;
	&lt;artifactId&gt;google-collections&lt;/artifactId&gt;
	&lt;version&gt;1.0&lt;/version&gt;
	&lt;type&gt;jar&lt;/type&gt;
	&lt;scope&gt;compile&lt;/scope&gt;
&lt;/dependency&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.lckymn.com/2009/12/31/google-collections-library-1-0-final/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Re: Java Challenge: Dropping Balloons in Java</title>
		<link>http://blog.lckymn.com/2009/11/20/java-challenge-dropping-balloons-in-java/</link>
		<comments>http://blog.lckymn.com/2009/11/20/java-challenge-dropping-balloons-in-java/#comments</comments>
		<pubDate>Fri, 20 Nov 2009 10:54:21 +0000</pubDate>
		<dc:creator>Kevin</dc:creator>
				<category><![CDATA[Fundamental]]></category>
		<category><![CDATA[IT]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[balloon]]></category>
		<category><![CDATA[building]]></category>
		<category><![CDATA[egg]]></category>
		<category><![CDATA[floor]]></category>
		<category><![CDATA[puzzle]]></category>
		<category><![CDATA[quiz]]></category>

		<guid isPermaLink="false">http://blog.lckymn.com/?p=455</guid>
		<description><![CDATA[<p>About a few days ago, I read <a href="http://united-coders.com/nico-heid/java-challenge-dropping-balloons-in-java" target="_blank">this post, Java Challenge: Dropping Balloons in Java</a> having an interesting question.</p>
<p>It&#8217;s a question to find an algorithm that gives the highest floor where you can drop a water balloon without breaking it at a 100 story building.  You have only two balloons.  I had actually seen this problem before and solved it already.  It was not balloons but eggs.  The solution is simple. Since if you <p style="border: 3px solid rgb(243, 197, 52); padding: 5px; background-color: rgb(254, 254, 184); width: 600px; text-align: center;">[...Continue reading <a href="http://blog.lckymn.com/2009/11/20/java-challenge-dropping-balloons-in-java/">Re: Java Challenge: Dropping Balloons in Java</a>...]</p>]]></description>
			<content:encoded><![CDATA[<p>About a few days ago, I read <a href="http://united-coders.com/nico-heid/java-challenge-dropping-balloons-in-java" target="_blank">this post, Java Challenge: Dropping Balloons in Java</a> having an interesting question.</p>
<p>It&#8217;s a question to find an algorithm that gives <span style="font-weight: bolder;">the highest floor where you can drop a water balloon without breaking it at a 100 story building</span>.  You have <span style="font-weight: bolder;">only two balloons</span>.  I had actually seen this problem before and solved it already.  It was not balloons but eggs.  The solution is simple. Since if you miss two chances then have no balloons available, you need to try from the lowest safe level which means throw it from the first floor then if it does not pop, pick it up and go up to the level 2 and repeat it until the balloon pops.  When you get the level from which the balloon bursts after dropping it, one level below this level is the highest safe level. (e.g. If the balloon first breaks on the 20th floor, the highest safe floor is the 19th).</p>
<p>It&#8217;s easy isn&#8217;t it? Yet the post above has one more condition to make it a little bit more difficult which is that <span style="font-weight: bolder;">you can try only 15 times</span>. This means if I try the solution I&#8217;ve just described, I can test up to only the 15th floor. If the breaking point is the 40th floor or even the 16th floor, I&#8217;ll never know it.  When I first saw it, I tried to solve it for about five minutes yet couldn&#8217;t solve it.  That time, I was too busy to think about it further thus couldn&#8217;t be bothered to do it.  So I saved the URI of the post and forgot about it.  Last night, no actually today morning, at approximately 6 am, I went to bed (yeah, am I a vampire or what? <img src='http://blog.lckymn.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ).  Although I didn&#8217;t even try to think about the problem yet all of sudden I came up with the answer of that question.  It was just like the &#8216;<a href="http://en.wikipedia.org/wiki/Eureka_(word)" target="_blank">Eureka</a>&#8216; story of <a href="http://en.wikipedia.org/wiki/Archimedes" target="_blank">Archimedes</a>.  Just like he figured out how to assess the purity of a golden crown when he stepped into a bath.  OK, stop flattering myself <img src='http://blog.lckymn.com/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' />  I figured it out as the question was easy to solve.</p>
<p>Well, an important point here is that I in fact often find solutions to some difficult problems when I am not struggling to solve it yet am doing something irrelevant to the problem such as working out at the gym, washing dishes after a meal, lying on the bed to sleep or even when I&#8217;m dreaming. <img src='http://blog.lckymn.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  So if you can&#8217;t solve some problem then why don&#8217;t you try something else rather than thinking about the solution all the time.  Your brain may need to relax or when you use the other parts of the brain by doing something else, it might figure it out.</p>
<p>Anyway, here is what my brain told me that time.</p>
<p>Since I have only two balloons, if I choose a wrong floor twice, I lose all the chances.  Then what if I check every second level as I have two balloons. So first, if I drop it from the second level and it breaks then I still have one more balloon so that I can try it from the first level and I can find if the highest safe level is the first or there is no safe level. If the balloon is fine after dropping it from the second level then I can pick it up and try it from the fourth level and so on. However, with this solution I can check at most until the 30th floor which is better than checking up to the 15th one but still not enough to check the 100 stories.  This means that it is not sufficient to check ever second level in order to find the floor and I should focus on not only the two balloons but also the 15 times of attempts.  From the first solution above, I know that I can definitely have 15 times if I try from the lowest safe floor and move up.  It means if the number of floors between the already known highest safe level and the breaking point level found is the same as or fewer than the number of attempts I still have, I can find the very first level where the balloon bursts after dropping it (In order to reduce the number of attempts, of course, I have to make it the same as the number of attempts still left).  Therefore I can tell the highest safe level that is one level below the breaking point level found.  This should be easier to understand with an example.</p>
<p>Let&#8217;s assume that the breaking point is the 17th floor.</p>
<p>At first, I have 15 tries to drop one balloon from the 15th floor.<br />
The balloon&#8217;s still OK and I now have 14 times of attempts. Since the number of attempts I still have is 14 time, I can&#8217;t try it from the 30th floor which is 15 + 15 yet I have to try it from the 29th floor (15 + 14). Because the breaking point is the 17th floor, the balloon breaks on the 29th floor.  Now I have 13 times of attempts and 1 balloon left.  From the first try, I know the 14th floor is fine so I try from the next floor that is floor 15 to see if floor 14 is the highest safe floor.  It turns out the 15th one is fine and now I have 12 times left.  16th -> OK / 11 times left, 17th -> it breaks! / 10 times left<br />
So I can tell the 16th floor is the highest safe floor and I didn&#8217;t even use all the 15 times of attempts.</p>
<p><a href="http://united-coders.com/nico-heid/java-challenge-dropping-balloons-in-java" target="_blank">The post that has the question</a> specifies the floor starts from 0 so let&#8217;s make the first floor is floor 0 and see have it works. I made a table which shows the number of attempts required to find the highest safe floor.</p>
<pre class="brush: plain; gutter: false;">
====================================================
 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15   tries
====================================================
 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14	- 1
15 16 17 18 19 20 21 22 23 24 25 26 27 28		- 2
29 30 31 32 33 34 35 36 37 38 39 40 41			- 3
42 43 44 45 46 47 48 49 50 51 52 53				- 4
54 55 56 57 58 59 60 61 62 63 64				- 5
65 66 67 68 69 70 71 72 73 74					- 6
75 76 77 78 79 80 81 82 83						- 7
84 85 86 87 88 89 90 91							- 8
92 93 94 95 96 97 98							- 9
99												- 10
</pre>
<p>So if the highest safe floor is 73. The first balloon breaks on the floor 74 after 6 times of attempts. After that try from the floor 65 (attempts: 7) through 66 (8), 67 (9), 68 (10), 69 (11), 70 (12), 71 (13), 72 (14) to 73 (15) and the second balloon hasn&#8217;t broken so I can tell the highest safe floor is the floor 73.</p>
<pre class="brush: plain; gutter: false;">
====================================================
 1  2  3  4  5  6  7  8[ 9]10 11 12 13 14 15
====================================================
65 66 67 68 69 70 71 72[73]74					-[6]
</pre>
<p>attempts: 6 times to get the floor 74 + 9 times to check until the floor 73 = 15 times.</p>
<p>Once I found the solution writing code is a piece of cake.<br />
I roughly wrote the main part of the code like this.</p>
<pre class="brush: java; gutter: false; tab-size: 4; toolbar: true;">
private static final int MAX_ATTEMPTS = 15;

private int theFloor = (int) (Math.random() * 100);
private int numberOfBalloons = 2;
private int numberOfAttempts = 0;

// ...

public void findHighestSafeFloor()
{
	int previousFloorIndex = -1;
	int floorIndex = MAX_ATTEMPTS - 1;
	int highestSafeFloor = 0;

	while (MAX_ATTEMPTS &gt; numberOfAttempts)
	{
		numberOfAttempts++;
		if (theFloor &lt;= floorIndex)
		{
			numberOfBalloons--;
			highestSafeFloor = findHighestSafeFloor(previousFloorIndex + 1, floorIndex);
			break;
		}
		previousFloorIndex = floorIndex;
		floorIndex += (MAX_ATTEMPTS - numberOfAttempts);
		if (99 &lt; floorIndex)
		{
			floorIndex = 99;
		}
	}

	/* print the result. */
}

private int findHighestSafeFloor(final int start, final int end)
{
	for (int i = start; i &lt; end; i++)
	{
		numberOfAttempts++;
		if (theFloor == i)
		{
			numberOfBalloons--;
			return (i - 1);
		}
	}
	return (end - 1);
}
</pre>
<p>I am sure that the <code>findHighestSafeFloor()</code> method above works but I decided to make it recursion. Why? No special reasons. I just like recursion <img src='http://blog.lckymn.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  as I haven&#8217;t used it for approximately four years since I last programmed in a functional programming language like <a href="http://haskell.org/" target="_blank">Haskell</a> in my math class thus miss it. <img src='http://blog.lckymn.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>Although the code can be very simple as the following code with recursion, it has to increase the number of attempts and to decrease the number of balloons left, so it would be a bit more verbose as the second code.</p>
<pre class="brush: java; gutter: false; tab-size: 4; toolbar: true;">
private int findHighestSafeFloor(final int start, final int end)
{
	return (start &lt; end ? (theFloor == start ? (start - 1) : findHighestSafeFloor((start + 1), end)) : (end - 1));
}
</pre>
<pre class="brush: java; gutter: false; tab-size: 4; toolbar: true;">
private int findHighestSafeFloor(final int start, final int end)
{
	if (start &lt; end)
	{
		numberOfAttempts++;
		if (theFloor == start)
		{
			numberOfBalloons--;
			return (start - 1);
		}
		else
		{
			return findHighestSafeFloor((start + 1), end);
		}
	}
	else
	{
		return (end - 1);
	}
}
</pre>
<p>Now it&#8217;s time to code the complete programme and test it.  Well, since it&#8217;s a very small programme, I didn&#8217;t do object-oriented programming. <img src='http://blog.lckymn.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<pre class="brush: java; tab-size: 4; toolbar: true;">
package com.lckymn.kevin.findingfloor;

public final class HighestSafeFloorFinder
{
	private static final int TOP_LEVEL = 99;
	private static final int MAX_ATTEMPTS = 15;

	private int theBreakingPointFloor;
	private int numberOfBalloons;
	private int numberOfAttemptsMade;

	public void init(final int theBreakingPointFloor)
	{
		this.theBreakingPointFloor = theBreakingPointFloor;
		System.out.println(&quot;The breaking point: &quot; + theBreakingPointFloor);
		numberOfBalloons = 2;
		numberOfAttemptsMade = 0;
	}

	public void findHighestSafeFloor()
	{
		int previousFloorIndex = -1;
		int floorIndex = MAX_ATTEMPTS - 1;
		int highestSafeFloor = 0;

		while (MAX_ATTEMPTS &gt; numberOfAttemptsMade)
		{
			dropBalloon();
			if (theBreakingPointFloor &lt;= floorIndex)
			{
				breakBalloon();
				highestSafeFloor = findHighestSafeFloor(previousFloorIndex + 1, floorIndex);
				break;
			}
			previousFloorIndex = floorIndex;
			floorIndex += (MAX_ATTEMPTS - numberOfAttemptsMade);
			if (TOP_LEVEL &lt; floorIndex)
			{
				floorIndex = TOP_LEVEL;
			}
		}

		if (0 &gt; highestSafeFloor)
		{
			System.out.println(&quot;There is no floor that you can drop a balloon without breaking it. Even the first floor (floor 0) is not safe.&quot;);
		}
		else
		{
			System.out.println(&quot;The highest safe floor: &quot; + highestSafeFloor);
		}

		System.out.println(&quot;The number of attempts made: &quot; + numberOfAttemptsMade);
	}

	private int findHighestSafeFloor(final int start, final int end)
	{
		if (start &lt; end)
		{
			dropBalloon();
			if (theBreakingPointFloor == start)
			{
				breakBalloon();
				return (start - 1);
			}
			else
			{
				return findHighestSafeFloor((start + 1), end);
			}
		}
		else
		{
			return (end - 1);
		}
	}

	private void dropBalloon()
	{
		if (MAX_ATTEMPTS == numberOfAttemptsMade)
		{
			throw new IllegalStateException(&quot;You've already tried 15 times.&quot;);
		}
		numberOfAttemptsMade++;
	}

	private void breakBalloon()
	{
		if (0 == numberOfBalloons)
		{
			throw new IllegalStateException(&quot;You've already broken all the balloons available.&quot;);
		}
		numberOfBalloons--;
	}

	public static void main(String[] args)
	{
		HighestSafeFloorFinder highestSafeFloorFinder = new HighestSafeFloorFinder();
		for (int i = 0; i &lt; 100; i++)
		{
			System.out.println(&quot;[Test Number: &quot; + i + &quot;]&quot;);
			highestSafeFloorFinder.init(i);
			highestSafeFloorFinder.findHighestSafeFloor();
			System.out.println(&quot;=======================================&quot;);
		}
		System.exit(0);
	}
}
</pre>
<p>Well, the code looks a bit ugly but in my defence, I&#8217;d just like to see the result and am busy so had no stomach for making it pretty. <img src='http://blog.lckymn.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' />  (Oh! such a poor excuse / but really busy <img src='http://blog.lckymn.com/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> )</p>
<p>The <code>dropBalloon()</code> and the <code>breakBalloon()</code> are added to increase the number of attempts made and to decrease the number of balloons left respectively.  The <code>dropBalloon()</code> method also checks if the number of attempts already made is 15 and it tries to make another one than throws an exception telling that all the chances have been used.  Similarly the <code>breakBalloon()</code> method checks if all the available balloons have broken if so, it also throws an exception saying there are no available balloons left.  Thus I can see if the programme can find the highest safe floor with 15 times or fewer times of attempts and only two water balloons.  If it cannot, it immediately throws an exception and stop the programme so I can see my programme fails to prove my algorithm.</p>
<p>The <code>init()</code> method is to initialise all the variables so that I can test it many times. It checks all the floors from the first one (floor 0) to the last one (floor 99) so if the programme works fine without any exception thrown then it might prove my answer is correct.</p>
<p>Let&#8217;s check out the result!</p>
<pre class="brush: plain; gutter: false;">
[Test Number: 0]
The breaking point: 0
There is no floor that you can drop a balloon without breaking it. Even the first floor (floor 0) is not safe.
The number of attempts made: 2
=======================================
[Test Number: 1]
The breaking point: 1
The highest safe floor: 0
The number of attempts made: 3
=======================================
[Test Number: 2]
The breaking point: 2
The highest safe floor: 1
The number of attempts made: 4
=======================================
[Test Number: 3]
The breaking point: 3
The highest safe floor: 2
The number of attempts made: 5
=======================================
[Test Number: 4]
The breaking point: 4
The highest safe floor: 3
The number of attempts made: 6
=======================================
[Test Number: 5]
The breaking point: 5
The highest safe floor: 4
The number of attempts made: 7
=======================================
[Test Number: 6]
The breaking point: 6
The highest safe floor: 5
The number of attempts made: 8
=======================================
[Test Number: 7]
The breaking point: 7
The highest safe floor: 6
The number of attempts made: 9
=======================================
[Test Number: 8]
The breaking point: 8
The highest safe floor: 7
The number of attempts made: 10
=======================================
[Test Number: 9]
The breaking point: 9
The highest safe floor: 8
The number of attempts made: 11
=======================================
[Test Number: 10]
The breaking point: 10
The highest safe floor: 9
The number of attempts made: 12
=======================================
[Test Number: 11]
The breaking point: 11
The highest safe floor: 10
The number of attempts made: 13
=======================================
[Test Number: 12]
The breaking point: 12
The highest safe floor: 11
The number of attempts made: 14
=======================================
[Test Number: 13]
The breaking point: 13
The highest safe floor: 12
The number of attempts made: 15
=======================================
[Test Number: 14]
The breaking point: 14
The highest safe floor: 13
The number of attempts made: 15
=======================================
[Test Number: 15]
The breaking point: 15
The highest safe floor: 14
The number of attempts made: 3
=======================================
[Test Number: 16]
The breaking point: 16
The highest safe floor: 15
The number of attempts made: 4
=======================================
[Test Number: 17]
The breaking point: 17
The highest safe floor: 16
The number of attempts made: 5
=======================================
[Test Number: 18]
The breaking point: 18
The highest safe floor: 17
The number of attempts made: 6
=======================================
[Test Number: 19]
The breaking point: 19
The highest safe floor: 18
The number of attempts made: 7
=======================================
[Test Number: 20]
The breaking point: 20
The highest safe floor: 19
The number of attempts made: 8
=======================================
[Test Number: 21]
The breaking point: 21
The highest safe floor: 20
The number of attempts made: 9
=======================================
[Test Number: 22]
The breaking point: 22
The highest safe floor: 21
The number of attempts made: 10
=======================================
[Test Number: 23]
The breaking point: 23
The highest safe floor: 22
The number of attempts made: 11
=======================================
[Test Number: 24]
The breaking point: 24
The highest safe floor: 23
The number of attempts made: 12
=======================================
[Test Number: 25]
The breaking point: 25
The highest safe floor: 24
The number of attempts made: 13
=======================================
[Test Number: 26]
The breaking point: 26
The highest safe floor: 25
The number of attempts made: 14
=======================================
[Test Number: 27]
The breaking point: 27
The highest safe floor: 26
The number of attempts made: 15
=======================================
[Test Number: 28]
The breaking point: 28
The highest safe floor: 27
The number of attempts made: 15
=======================================
[Test Number: 29]
The breaking point: 29
The highest safe floor: 28
The number of attempts made: 4
=======================================
[Test Number: 30]
The breaking point: 30
The highest safe floor: 29
The number of attempts made: 5
=======================================
[Test Number: 31]
The breaking point: 31
The highest safe floor: 30
The number of attempts made: 6
=======================================
[Test Number: 32]
The breaking point: 32
The highest safe floor: 31
The number of attempts made: 7
=======================================
[Test Number: 33]
The breaking point: 33
The highest safe floor: 32
The number of attempts made: 8
=======================================
[Test Number: 34]
The breaking point: 34
The highest safe floor: 33
The number of attempts made: 9
=======================================
[Test Number: 35]
The breaking point: 35
The highest safe floor: 34
The number of attempts made: 10
=======================================
[Test Number: 36]
The breaking point: 36
The highest safe floor: 35
The number of attempts made: 11
=======================================
[Test Number: 37]
The breaking point: 37
The highest safe floor: 36
The number of attempts made: 12
=======================================
[Test Number: 38]
The breaking point: 38
The highest safe floor: 37
The number of attempts made: 13
=======================================
[Test Number: 39]
The breaking point: 39
The highest safe floor: 38
The number of attempts made: 14
=======================================
[Test Number: 40]
The breaking point: 40
The highest safe floor: 39
The number of attempts made: 15
=======================================
[Test Number: 41]
The breaking point: 41
The highest safe floor: 40
The number of attempts made: 15
=======================================
[Test Number: 42]
The breaking point: 42
The highest safe floor: 41
The number of attempts made: 5
=======================================
[Test Number: 43]
The breaking point: 43
The highest safe floor: 42
The number of attempts made: 6
=======================================
[Test Number: 44]
The breaking point: 44
The highest safe floor: 43
The number of attempts made: 7
=======================================
[Test Number: 45]
The breaking point: 45
The highest safe floor: 44
The number of attempts made: 8
=======================================
[Test Number: 46]
The breaking point: 46
The highest safe floor: 45
The number of attempts made: 9
=======================================
[Test Number: 47]
The breaking point: 47
The highest safe floor: 46
The number of attempts made: 10
=======================================
[Test Number: 48]
The breaking point: 48
The highest safe floor: 47
The number of attempts made: 11
=======================================
[Test Number: 49]
The breaking point: 49
The highest safe floor: 48
The number of attempts made: 12
=======================================
[Test Number: 50]
The breaking point: 50
The highest safe floor: 49
The number of attempts made: 13
=======================================
[Test Number: 51]
The breaking point: 51
The highest safe floor: 50
The number of attempts made: 14
=======================================
[Test Number: 52]
The breaking point: 52
The highest safe floor: 51
The number of attempts made: 15
=======================================
[Test Number: 53]
The breaking point: 53
The highest safe floor: 52
The number of attempts made: 15
=======================================
[Test Number: 54]
The breaking point: 54
The highest safe floor: 53
The number of attempts made: 6
=======================================
[Test Number: 55]
The breaking point: 55
The highest safe floor: 54
The number of attempts made: 7
=======================================
[Test Number: 56]
The breaking point: 56
The highest safe floor: 55
The number of attempts made: 8
=======================================
[Test Number: 57]
The breaking point: 57
The highest safe floor: 56
The number of attempts made: 9
=======================================
[Test Number: 58]
The breaking point: 58
The highest safe floor: 57
The number of attempts made: 10
=======================================
[Test Number: 59]
The breaking point: 59
The highest safe floor: 58
The number of attempts made: 11
=======================================
[Test Number: 60]
The breaking point: 60
The highest safe floor: 59
The number of attempts made: 12
=======================================
[Test Number: 61]
The breaking point: 61
The highest safe floor: 60
The number of attempts made: 13
=======================================
[Test Number: 62]
The breaking point: 62
The highest safe floor: 61
The number of attempts made: 14
=======================================
[Test Number: 63]
The breaking point: 63
The highest safe floor: 62
The number of attempts made: 15
=======================================
[Test Number: 64]
The breaking point: 64
The highest safe floor: 63
The number of attempts made: 15
=======================================
[Test Number: 65]
The breaking point: 65
The highest safe floor: 64
The number of attempts made: 7
=======================================
[Test Number: 66]
The breaking point: 66
The highest safe floor: 65
The number of attempts made: 8
=======================================
[Test Number: 67]
The breaking point: 67
The highest safe floor: 66
The number of attempts made: 9
=======================================
[Test Number: 68]
The breaking point: 68
The highest safe floor: 67
The number of attempts made: 10
=======================================
[Test Number: 69]
The breaking point: 69
The highest safe floor: 68
The number of attempts made: 11
=======================================
[Test Number: 70]
The breaking point: 70
The highest safe floor: 69
The number of attempts made: 12
=======================================
[Test Number: 71]
The breaking point: 71
The highest safe floor: 70
The number of attempts made: 13
=======================================
[Test Number: 72]
The breaking point: 72
The highest safe floor: 71
The number of attempts made: 14
=======================================
[Test Number: 73]
The breaking point: 73
The highest safe floor: 72
The number of attempts made: 15
=======================================
[Test Number: 74]
The breaking point: 74
The highest safe floor: 73
The number of attempts made: 15
=======================================
[Test Number: 75]
The breaking point: 75
The highest safe floor: 74
The number of attempts made: 8
=======================================
[Test Number: 76]
The breaking point: 76
The highest safe floor: 75
The number of attempts made: 9
=======================================
[Test Number: 77]
The breaking point: 77
The highest safe floor: 76
The number of attempts made: 10
=======================================
[Test Number: 78]
The breaking point: 78
The highest safe floor: 77
The number of attempts made: 11
=======================================
[Test Number: 79]
The breaking point: 79
The highest safe floor: 78
The number of attempts made: 12
=======================================
[Test Number: 80]
The breaking point: 80
The highest safe floor: 79
The number of attempts made: 13
=======================================
[Test Number: 81]
The breaking point: 81
The highest safe floor: 80
The number of attempts made: 14
=======================================
[Test Number: 82]
The breaking point: 82
The highest safe floor: 81
The number of attempts made: 15
=======================================
[Test Number: 83]
The breaking point: 83
The highest safe floor: 82
The number of attempts made: 15
=======================================
[Test Number: 84]
The breaking point: 84
The highest safe floor: 83
The number of attempts made: 9
=======================================
[Test Number: 85]
The breaking point: 85
The highest safe floor: 84
The number of attempts made: 10
=======================================
[Test Number: 86]
The breaking point: 86
The highest safe floor: 85
The number of attempts made: 11
=======================================
[Test Number: 87]
The breaking point: 87
The highest safe floor: 86
The number of attempts made: 12
=======================================
[Test Number: 88]
The breaking point: 88
The highest safe floor: 87
The number of attempts made: 13
=======================================
[Test Number: 89]
The breaking point: 89
The highest safe floor: 88
The number of attempts made: 14
=======================================
[Test Number: 90]
The breaking point: 90
The highest safe floor: 89
The number of attempts made: 15
=======================================
[Test Number: 91]
The breaking point: 91
The highest safe floor: 90
The number of attempts made: 15
=======================================
[Test Number: 92]
The breaking point: 92
The highest safe floor: 91
The number of attempts made: 10
=======================================
[Test Number: 93]
The breaking point: 93
The highest safe floor: 92
The number of attempts made: 11
=======================================
[Test Number: 94]
The breaking point: 94
The highest safe floor: 93
The number of attempts made: 12
=======================================
[Test Number: 95]
The breaking point: 95
The highest safe floor: 94
The number of attempts made: 13
=======================================
[Test Number: 96]
The breaking point: 96
The highest safe floor: 95
The number of attempts made: 14
=======================================
[Test Number: 97]
The breaking point: 97
The highest safe floor: 96
The number of attempts made: 15
=======================================
[Test Number: 98]
The breaking point: 98
The highest safe floor: 97
The number of attempts made: 15
=======================================
[Test Number: 99]
The breaking point: 99
The highest safe floor: 98
The number of attempts made: 10
=======================================
</pre>
<p>It works! <img src='http://blog.lckymn.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lckymn.com/2009/11/20/java-challenge-dropping-balloons-in-java/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Web Service Development using Tomcat and OpenEJB</title>
		<link>http://blog.lckymn.com/2009/11/01/web-service-development-using-tomcat-and-openejb/</link>
		<comments>http://blog.lckymn.com/2009/11/01/web-service-development-using-tomcat-and-openejb/#comments</comments>
		<pubDate>Sun, 01 Nov 2009 05:42:30 +0000</pubDate>
		<dc:creator>Kevin</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Java Web Application Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[@WebService]]></category>
		<category><![CDATA[Apache Tomcat]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Eclipse Ganymede]]></category>
		<category><![CDATA[Eclipse JEE]]></category>
		<category><![CDATA[EJB]]></category>
		<category><![CDATA[EJB3]]></category>
		<category><![CDATA[Java EE]]></category>
		<category><![CDATA[Java EE 5]]></category>
		<category><![CDATA[JPA]]></category>
		<category><![CDATA[OpenEJB]]></category>
		<category><![CDATA[OpenJPA]]></category>
		<category><![CDATA[Tomcat]]></category>
		<category><![CDATA[Web Service]]></category>
		<category><![CDATA[Web Service Client]]></category>
		<category><![CDATA[Web Service Development]]></category>

		<guid isPermaLink="false">http://blog.lckymn.com/?p=432</guid>
		<description><![CDATA[<p>In addition to the previous post, <a href="http://blog.lckymn.com/2009/10/17/java-ee-application-development-using-tomcat-openejb-and-hibernate/" target="_blank">Java EE Application Development using Tomcat, OpenEJB and Hibernate</a>, this post will demonstrate how to create a web service using Tomcat and OpenEJB.  The web service in this blog entry uses the code from <a href="http://blog.lckymn.com/2009/10/17/java-ee-application-development-using-tomcat-openejb-and-hibernate/" target="_blank">the previous post</a>, so if you haven&#8217;t read <a href="http://blog.lckymn.com/2009/10/17/java-ee-application-development-using-tomcat-openejb-and-hibernate/" target="_blank">it</a> yet, better read <a href="http://blog.lckymn.com/2009/10/17/java-ee-application-development-using-tomcat-openejb-and-hibernate/" target="_blank">it</a> first.</p>
<p>Firstly, create a web service interface then put the <a href="http://java.sun.com/javase/6/docs/api/javax/jws/WebService.html" target="_blank">@WebService</a> annotation.</p>

package com.lckymn.kevin.test.openejb.webservice;

import javax.jws.WebService;

import com.lckymn.kevin.test.openejb.domain.User;

@WebService
public interface TestWebService
{
	User <p style="border: 3px solid rgb(243, 197, 52); padding: 5px; background-color: rgb(254, 254, 184); width: 600px; text-align: center;">[...Continue reading <a href="http://blog.lckymn.com/2009/11/01/web-service-development-using-tomcat-and-openejb/">Web Service Development using Tomcat and OpenEJB</a>...]</p>]]></description>
			<content:encoded><![CDATA[<p>In addition to the previous post, <a href="http://blog.lckymn.com/2009/10/17/java-ee-application-development-using-tomcat-openejb-and-hibernate/" target="_blank">Java EE Application Development using Tomcat, OpenEJB and Hibernate</a>, this post will demonstrate how to create a web service using Tomcat and OpenEJB.  The web service in this blog entry uses the code from <a href="http://blog.lckymn.com/2009/10/17/java-ee-application-development-using-tomcat-openejb-and-hibernate/" target="_blank">the previous post</a>, so if you haven&#8217;t read <a href="http://blog.lckymn.com/2009/10/17/java-ee-application-development-using-tomcat-openejb-and-hibernate/" target="_blank">it</a> yet, better read <a href="http://blog.lckymn.com/2009/10/17/java-ee-application-development-using-tomcat-openejb-and-hibernate/" target="_blank">it</a> first.</p>
<p>Firstly, create a web service interface then put the <a href="http://java.sun.com/javase/6/docs/api/javax/jws/WebService.html" target="_blank">@WebService</a> annotation.</p>
<pre class="brush: java; tab-size: 4; toolbar: true;">
package com.lckymn.kevin.test.openejb.webservice;

import javax.jws.WebService;

import com.lckymn.kevin.test.openejb.domain.User;

@WebService
public interface TestWebService
{
	User getUser(Long id);
}
</pre>
<p>Secondly, create a class implmenting the web service interface with also the <a href="http://java.sun.com/javase/6/docs/api/javax/jws/WebService.html" target="_blank">@WebService</a> annotation then specify the <code>targetNamespace</code> and the <code>serviceName</code> as you wish. In my case, these are<br />
<code><br />
targetNamespace: "http://webservice.webhibernate.test"<br />
serviceName: "testWebService"<br />
</code><br />
To use the UserService EJB, injected by OpenEJB, make the web service class session EJB with the @Stateless annotation.</p>
<pre class="brush: java; tab-size: 4; toolbar: true;">
package com.lckymn.kevin.test.openejb.webservice;

import javax.ejb.EJB;
import javax.ejb.Local;
import javax.ejb.Stateless;
import javax.jws.WebService;

import com.lckymn.kevin.test.openejb.domain.User;
import com.lckymn.kevin.test.openejb.service.UserService;

@Local
@Stateless
@WebService(targetNamespace = &quot;http://webservice.webhibernate.test&quot;, serviceName = &quot;testWebService&quot;)
public class TestWebServiceImpl implements TestWebService
{
	@EJB
	private UserService userService;

	@Override
	public User getUser(Long id)
	{
		return userService.getUser(id);
	}
}
</pre>
<p>The class above simply returns a User entity object acquired from the <code>UserService</code> EJB, made in the previous post.</p>
<p>That&#8217;s it. You have just made your web service. When the server starts and the application is deployed, the EJB container (OpenEJB) registers the above EJB as a web service.</p>
<p>Now, let&#8217;s make a web service client. To make a very simple example client, I&#8217;m going to create a servlet in the same web application to which the web service belongs, yet it can of course be another web application, Java desktop application, Java console application and so on.</p>
<p>Here is a simple servlet which gets the user ID from the client-side then accesses the web service to get the User. After that it passes the User entity object through the <code>HttpSession</code> to the JSP page to display.</p>
<pre class="brush: java; tab-size: 4; toolbar: true;">
package com.lckymn.kevin.test.openejb.web;

import java.io.IOException;
import java.net.URL;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;

import com.lckymn.kevin.test.openejb.domain.User;
import com.lckymn.kevin.test.openejb.webservice.TestWebService;

public class TestWebServiceClientServlet extends HttpServlet
{
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{
		doPost(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{
		Service service = Service.create(new URL(&quot;http://localhost:8080/TestWebServiceImpl?wsdl&quot;), new QName(
				&quot;http://webservice.webhibernate.test&quot;, &quot;testWebService&quot;));
		TestWebService testWebService = service.getPort(TestWebService.class);

		String userIdParam = request.getParameter(&quot;userId&quot;);

		HttpSession session = request.getSession();
		if (null == userIdParam || 0 == userIdParam.length())
		{
			session.removeAttribute(&quot;userFound&quot;);
		}
		else
		{
			Long userId = Long.parseLong(userIdParam);
			User user = testWebService.getUser(userId);
			session.setAttribute(&quot;userFound&quot;, user);
		}
		getServletContext().getRequestDispatcher(&quot;/WEB-INF/jsp/webServiceClient.jsp&quot;)
				.forward(request, response);
	}
}
</pre>
<p>This is just a simple example thus I omitted validation (e.g. checking whether the userId is &#8216;long&#8217; type or not) and exception handling. </p>
<p>The WSDL location is the server URI + &#8220;/&#8221; + web service class name + &#8220;?wsdl&#8221;.<br />
<code>http://localhost:8080/TestWebServiceImpl?wsdl</code><br />
The parameters of the <a href="http://java.sun.com/javase/6/docs/api/javax/xml/namespace/QName.html" target="_blank">QName</a> constructor are <code>namespaceURI</code> and <code>localPart</code>, and these are defined in the web service. If you look at the web service code again, these can easily be found from the <a href="http://java.sun.com/javase/6/docs/api/javax/jws/WebService.html" target="_blank">@WebService</a> annotation.</p>
<pre class="brush: java; gutter: false; highlight: [1];">
@WebService(targetNamespace = &quot;http://webservice.webhibernate.test&quot;, serviceName = &quot;testWebService&quot;)
public class TestWebServiceImpl implements TestWebService
{
	...
}
</pre>
<p>The value of the <code>targetNamespace</code> element is the <code>namespaceURI</code> of the <code>QName</code> constructor, and the value of the <code>serviceNmae</code> element is the <code>localPart</code>.</p>
<p>This is web.xml. The information of the new servlet, the web service client just created, is added to the web.xml, made in the previous post.</p>
<pre class="brush: xml; highlight: [14,15,16,17,18,19,20,21,22,23]; tab-size: 4; toolbar: true;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;web-app xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xmlns=&quot;http://java.sun.com/xml/ns/javaee&quot; xmlns:web=&quot;http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&quot; xsi:schemaLocation=&quot;http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&quot; id=&quot;WebApp_ID&quot; version=&quot;2.5&quot;&gt;
  &lt;display-name&gt;test-web-hibernate&lt;/display-name&gt;
  &lt;servlet&gt;
    &lt;description&gt;&lt;/description&gt;
    &lt;display-name&gt;TestServlet&lt;/display-name&gt;
    &lt;servlet-name&gt;TestServlet&lt;/servlet-name&gt;
    &lt;servlet-class&gt;com.lckymn.kevin.test.openejb.web.TestServlet&lt;/servlet-class&gt;
  &lt;/servlet&gt;
  &lt;servlet-mapping&gt;
    &lt;servlet-name&gt;TestServlet&lt;/servlet-name&gt;
    &lt;url-pattern&gt;/Test&lt;/url-pattern&gt;
  &lt;/servlet-mapping&gt;
  &lt;servlet&gt;
    &lt;description&gt;&lt;/description&gt;
    &lt;display-name&gt;TestWebServiceClientServlet&lt;/display-name&gt;
    &lt;servlet-name&gt;TestWebServiceClientServlet&lt;/servlet-name&gt;
    &lt;servlet-class&gt;com.lckymn.kevin.test.openejb.web.TestWebServiceClientServlet&lt;/servlet-class&gt;
  &lt;/servlet&gt;
  &lt;servlet-mapping&gt;
    &lt;servlet-name&gt;TestWebServiceClientServlet&lt;/servlet-name&gt;
    &lt;url-pattern&gt;/TestWebServiceClient&lt;/url-pattern&gt;
  &lt;/servlet-mapping&gt;
  &lt;welcome-file-list&gt;
    &lt;welcome-file&gt;index.jsp&lt;/welcome-file&gt;
  &lt;/welcome-file-list&gt;
&lt;/web-app&gt;
</pre>
<p>Finally, add a JSP file to enter the userId to search a user and to display the user info.<br />
In my case, I added the file to the <code>application/WebContent/WEB-INF/jsp</code> directory which is the same location that I set in the <code>TestWebServiceClientServlet</code> (look at the TestWebServiceClientServlet code above).<br />
<code>test-web-hibernate/WebContent/WEB-INF/jsp/webServiceClient.jsp</code></p>
<pre class="brush: xml; tab-size: 4; toolbar: true;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?&gt;
&lt;%@ page language=&quot;java&quot; contentType=&quot;text/html; charset=UTF-8&quot;
    pageEncoding=&quot;UTF-8&quot;%&gt;
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
&lt;head&gt;
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot; /&gt;
&lt;title&gt;Insert title here&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div&gt;
&lt;form name=&quot;userForm&quot; action=&quot;TestWebServiceClient&quot; method=&quot;post&quot; &gt;
	&lt;input type=&quot;text&quot; name=&quot;userId&quot; value=&quot;&quot; /&gt; &lt;input type=&quot;submit&quot; name=&quot;userIdSubmit&quot; value=&quot;Search&quot; /&gt;
&lt;/form&gt;
&lt;/div&gt;
&lt;div&gt;
	&lt;table&gt;
		&lt;tr&gt;
			&lt;td&gt;User ID: &lt;/td&gt;&lt;td&gt;${userFound.id }&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;Username: &lt;/td&gt;&lt;td&gt;${userFound.username }&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;Surname: &lt;/td&gt;&lt;td&gt;${userFound.surname }&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;Given name: &lt;/td&gt;&lt;td&gt;${userFound.givenName }&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;Email: &lt;/td&gt;&lt;td&gt;${userFound.email }&lt;/td&gt;
		&lt;/tr&gt;
	&lt;/table&gt;
&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>To test it, open the browser and enter the following URI.</p>
<pre class="brush: plain; gutter: false;">
http://localhost:8080/test-web-hibernate/TestWebServiceClient
</pre>
<p>It displays the screen like below<br />
<div id="attachment_436" class="wp-caption alignnone" style="width: 712px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/11/01_web_service_client_test01.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/11/01_web_service_client_test01.jpg" alt="Enter userId and click the &#039;Search&#039; button" title="Web Service Client Test 01" width="702" height="268" class="size-full wp-image-436" /></a><p class="wp-caption-text">Enter userId and click the 'Search' button</p></div><br />
-Enter a userId to search then click the &#8216;Search&#8217; button.</p>
<p>It displays the result yet there is one problem. It doesn&#8217;t display the userId.<br />
<div id="attachment_437" class="wp-caption alignnone" style="width: 712px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/11/01_web_service_client_test02.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/11/01_web_service_client_test02.jpg" alt="The Search Result: userId is not displayed" title="Web Service Client Test 02" width="702" height="268" class="size-full wp-image-437" /></a><p class="wp-caption-text">The Search Result: userId is not displayed</p></div><br />
This is because the id field of the User entity class that I created in the previous blog entry does not have the mutator that is the setId() method so when the entity object is passed through the web service, the id field is not included.</p>
<p>There are two simple ways to solve this problem. Either way works so choose whichever you like.</p>
<p>1. Add the setter method. If there is setId() method, the id field is included when the object is passed through the web service. The reason why I did not write the setter method is that the id is supposed to be set by Hibernate and to avoid any problems caused by setting it manually, I did not write it. However, it is required in order to include the field when passing object through the web service. So adding setter can solve this problem. If you do not like this solution as you do not like to put the setter method due to the reason I explained, you can try the second solution.</p>
<pre class="brush: java; highlight: [19,20,21,22]; tab-size: 4; toolbar: true;">
@Entity
@Table(name = &quot;users&quot;)
public class User implements Serializable
{
	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(name = &quot;user_id&quot;)
	private Long id;

	...

	public Long getId()
	{
		return id;
	}

	public void setId(Long id)
	{
		this.id = id;
	}

	...
}
</pre>
<p>OR</p>
<p>2. If you add the <a href="http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlElement.html" target="_blank">@XmlElement</a> annotation to the id field and set the value of the <code>required</code> element to <code>true</code>, the id field is included even without the setter method.</p>
<pre class="brush: java; highlight: [15]; tab-size: 4; toolbar: true;">
...

import javax.xml.bind.annotation.XmlElement;

...
@Entity
@Table(name = &quot;users&quot;)
public class User implements Serializable
{
	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(name = &quot;user_id&quot;)
	@XmlElement(required = true)
	private Long id;

	...

	public Long getId()
	{
		return id;
	}

	// No setId() required

	...
}
</pre>
<p>Now, test if it works.<br />
<div id="attachment_436" class="wp-caption alignnone" style="width: 712px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/11/01_web_service_client_test01.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/11/01_web_service_client_test01.jpg" alt="Enter userId and click the &#039;Search&#039; button" title="Web Service Client Test 01" width="702" height="268" class="size-full wp-image-436" /></a><p class="wp-caption-text">Enter userId and click the 'Search' button</p></div></p>
<p>It works!<br />
<div id="attachment_438" class="wp-caption alignnone" style="width: 712px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/11/01_web_service_client_test03.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/11/01_web_service_client_test03.jpg" alt="The Search Result: userId is displayed correctly" title="Web Service Client Test 03" width="702" height="268" class="size-full wp-image-438" /></a><p class="wp-caption-text">The Search Result: userId is displayed correctly</p></div></p>
<p>There are also other ways and tools to create a web service in Java. I used to use <a href="http://ws.apache.org/axis/" target="_blank">Apache Axis</a> then later moved to <a href="http://xfire.codehaus.org/" target="_blank">XFire</a>. Now, I use <a href="http://cxf.apache.org/" target="_blank">Apache CXF</a> which is considered as XFire 2.0.  It is, as explained here, very easy to create a web service client, yet it can be even easier with <a href="http://ws.apache.org/axis/java/user-guide.html#WSDL2JavaBuildingStubsSkeletonsAndDataTypesFromWSDL" target="_blank">WSDL2Java</a> from <a href="http://ws.apache.org/axis/" target="_blank">Apache Axis</a> or <a href="http://ws.apache.org/axis2/1_3/userguide-creatingclients.html" target="_blank">WSDL2Java</a> from <a href="http://ws.apache.org/axis2/" target="_blank">Apache Axis2</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lckymn.com/2009/11/01/web-service-development-using-tomcat-and-openejb/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Java EE Application Development using Tomcat, OpenEJB and Hibernate</title>
		<link>http://blog.lckymn.com/2009/10/17/java-ee-application-development-using-tomcat-openejb-and-hibernate/</link>
		<comments>http://blog.lckymn.com/2009/10/17/java-ee-application-development-using-tomcat-openejb-and-hibernate/#comments</comments>
		<pubDate>Fri, 16 Oct 2009 17:06:59 +0000</pubDate>
		<dc:creator>Kevin</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Java Web Application Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Apache Tomcat]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Eclipse Ganymede]]></category>
		<category><![CDATA[Eclipse JEE]]></category>
		<category><![CDATA[EJB]]></category>
		<category><![CDATA[EJB3]]></category>
		<category><![CDATA[Generic DAO]]></category>
		<category><![CDATA[Hibernate]]></category>
		<category><![CDATA[Java EE]]></category>
		<category><![CDATA[Java EE 5]]></category>
		<category><![CDATA[JPA]]></category>
		<category><![CDATA[OpenEJB]]></category>
		<category><![CDATA[OpenJPA]]></category>
		<category><![CDATA[Software Development Environment]]></category>
		<category><![CDATA[Tomcat]]></category>
		<category><![CDATA[Web Application Development]]></category>

		<guid isPermaLink="false">http://blog.lckymn.com/?p=380</guid>
		<description><![CDATA[<p>Java EE Application Development using Tomcat, OpenEJB and Hibernate</p>
<p>Before I start writing this blog entry, I&#8217;d better point out a few things.</p>

This blog entry is not about how to make a good <a href="http://en.wikipedia.org/wiki/Java_Platform,_Enterprise_Edition" target="_blank">Java EE</a> application yet is about how to use <a href="http://openejb.apache.org/" target="_blank">OpenEJB</a> on <a href="http://tomcat.apache.org/" target="_blank">Apache Tomcat server</a> with <a href="https://www.hibernate.org/" target="_blank">Hibernate</a> as an implementation of the <a href="http://en.wikipedia.org/wiki/Java_Persistence_API" target="_blank">JPA</a>.  If you are looking for better Java EE development or similar, this one is not <p style="border: 3px solid rgb(243, 197, 52); padding: 5px; background-color: rgb(254, 254, 184); width: 600px; text-align: center;">[...Continue reading <a href="http://blog.lckymn.com/2009/10/17/java-ee-application-development-using-tomcat-openejb-and-hibernate/">Java EE Application Development using Tomcat, OpenEJB and Hibernate</a>...]</p>]]></description>
			<content:encoded><![CDATA[<p>Java EE Application Development using Tomcat, OpenEJB and Hibernate</p>
<p>Before I start writing this blog entry, I&#8217;d better point out a few things.</p>
<ul>
<li>This blog entry is not about how to make a good <a href="http://en.wikipedia.org/wiki/Java_Platform,_Enterprise_Edition" target="_blank">Java EE</a> application yet is about how to use <a href="http://openejb.apache.org/" target="_blank">OpenEJB</a> on <a href="http://tomcat.apache.org/" target="_blank">Apache Tomcat server</a> with <a href="https://www.hibernate.org/" target="_blank">Hibernate</a> as an implementation of the <a href="http://en.wikipedia.org/wiki/Java_Persistence_API" target="_blank">JPA</a>.  If you are looking for better Java EE development or similar, this one is not for you. <img src='http://blog.lckymn.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
<li> I don&#8217;t have enough time to explain all the details of how to install JDK, Eclipse, Tomcat and so on. So this post doesn&#8217;t have that level of details. I simply assume that you&#8217;ve already known how to install JDK, Eclipse and Tomcat. Well, anyway, installing Eclipse and Tomcat are as easy as extracting a zip or gzip file and JDK installation is also not difficult at all.</li>
<li>This post does not cover how to use those tools and frameworks in the production environment. In other words, it is only for the development. Setting up the environment for development and for the production use have some differences. It is, however not that hard to figure out once you know how to use those in your development environment.</li>
</ul>
<h2>1. Development Environment</h2>
<p>First of all, I&#8217;m going to list the development environment and tools I have for this introductory tutorial post.<br />
(Click each name and it will take you to the download page).</p>
<p>OS: <a href="http://www.ubuntu.com" target="_blank">Ubuntu Linux</a> <a href="http://releases.ubuntu.com/9.04/" target="_blank">Jaunty Jackalope 9.04 Desktop 64bit</a><br />
Java: <a href="http://java.sun.com/javase/downloads" target="_blank">Sun JDK 1.6.0_16 (64 bit)</a> (it&#8217;s from the Ubuntu repository).<br />
Database: <a href="http://dev.mysql.com/downloads/mysql/5.0.html" target="_blank">MySQL Community Server 5.0</a> (it&#8217;s from the Ubuntu repository).<br />
JDBC Driver: <a href="http://dev.mysql.com/downloads/connector/j/5.1.html" target="_blank">MySQL Connector/J 5.1.10</a><br />
Eclipse: <a href="http://eclipse.org/downloads/packages/release/ganymede/sr2" target="_blank">Eclipse IDE for Java EE Developer Ganymede SR2 (Eclipse 3.4.2)</a><br />
Tomcat: <a href="http://tomcat.apache.org/download-60.cgi" target="_blank">Tomcat 6.0.20</a><br />
OpenEJB: <a href="http://openejb.apache.org/download.html" target="_blank">OpenEJB 3.1.1 (openejb.war)</a><br />
Hibernate: <a href="http://sourceforge.net/projects/hibernate/files/" target="_blank">Hibernate 3.2.1GA</a> (including hibernate-3.2.1.ga, hibernate-annotations-3.2.1.ga, hibernate-entitymanager-3.2.1.ga)</p>
<h2>2. Installing OpenEJB</h2>
<p>Java EE server normally means a Java application server which consists of a <a href="http://en.wikipedia.org/wiki/Java_Servlet" target="_blank">Servlet</a> container and an <a href="http://en.wikipedia.org/wiki/EJB_container" target="_blank">EJB</a> container. Apache Tomcat is a servlet container but not an EJB container so you need to have an EJB container like OpenEJB or use a Java EE server instead of Tomcat in order to use EJB unless you&#8217;re using the frameworks supporting EJB such as Spring framework. &#8220;So if I use Tomcat server and Spring framework, do I not need OpenEJB or other Java EE servers to use EJB?&#8221; No, you don&#8217;t.</p>
<p>Since this post is, as already mentioned, about using using EJB on Tomcat with OpenEJB and Hibernate, I will first show you how to install OpenEJB.</p>
<p>Before installing OpenEJB, don&#8217;t forget to copy JDBC driver that is, in this post, MySQL Connector/J to the $TOMCAT/lib directory.<br />
-Copy the Connector/J jar file to the Tomcat&#8217;s library directory ($TOMCAT_HOME/lib)<br />
<div id="attachment_381" class="wp-caption alignnone" style="width: 727px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/10/00_copy_connector-j01.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/10/00_copy_connector-j01.jpg" alt="Select Connector/J and Extract to the $TOMCAT/lib directory." title="Extract Connector/J" width="717" height="493" class="size-full wp-image-381" /></a><p class="wp-caption-text">Select Connector/J and Extract to the $TOMCAT/lib directory.</p></div></p>
<div id="attachment_382" class="wp-caption alignnone" style="width: 432px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/10/00_copy_connector-j02.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/10/00_copy_connector-j02.jpg" alt="Make sure the Connector/J jar file is in the $TOMCAT/lib directory." title="Check Connector/J is in the $TOMCAT/lib directory" width="422" height="395" class="size-full wp-image-382" /></a><p class="wp-caption-text">Make sure the Connector/J jar file is in the $TOMCAT/lib directory.</p></div>
<p>-Run Eclipse and add Tomcat server: Menu &#8211; Window -> Preferences -> Server -> Runtime Environments -> Add</p>
<p>-Download the openejb.war, OpenEJB for Tomcat, and import the file from Eclipse.<br />
-Right click on the project explorer -> Import -> WAR file<br />
<div id="attachment_383" class="wp-caption alignnone" style="width: 698px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/10/02_import_openejb01.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/10/02_import_openejb01.jpg" alt="Right Click on the project explorer -&gt; Import -&gt; WAR File" title="Import OpenEJB 01" width="688" height="509" class="size-full wp-image-383" /></a><p class="wp-caption-text">Right Click on the project explorer -> Import -> WAR File</p></div></p>
<p>-Click the &#8216;Browse&#8217; button and select the openejb.war file -> Select your Tomcat 6.0 as the target runtime. -> Click the &#8216;Finish&#8217; button.<br />
<div id="attachment_384" class="wp-caption alignnone" style="width: 623px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/10/02_import_openejb02.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/10/02_import_openejb02.jpg" alt="Click the &#039;Browse&#039; button and select the openejb.war file -&gt; Select your Tomcat 6.0 as the target runtime. -&gt; Click the &#039;Finish&#039; button." title="Import OpenEJB 02" width="613" height="408" class="size-full wp-image-384" /></a><p class="wp-caption-text">Click the 'Browse' button and select the openejb.war file -> Select your Tomcat 6.0 as the target runtime. -> Click the 'Finish' button.</p></div></p>
<h2>3. Add OpenEJB project to the Server to deploy</h2>
<p>-Right click on the server name in the &#8216;Server&#8217; view -> Select the &#8216;Add and Remove Projects&#8230;&#8217;<br />
<div id="attachment_385" class="wp-caption alignnone" style="width: 698px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/10/03_add_to_server01.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/10/03_add_to_server01.jpg" alt="Right click on the server name in the &#039;Server&#039; view -&gt; Select the &#039;Add and Remove Projects...&#039;" title="03 Add to the Server 01" width="688" height="509" class="size-full wp-image-385" /></a><p class="wp-caption-text">Right click on the server name in the 'Server' view -> Select the 'Add and Remove Projects...'</p></div></p>
<p>-Select openejb -> Click the &#8216;Add&#8217; button -> Click the &#8216;Finish&#8217; button<br />
<div id="attachment_386" class="wp-caption alignnone" style="width: 623px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/10/03_add_to_server02.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/10/03_add_to_server02.jpg" alt="Select openejb -&gt; Click the &#039;Add&#039; button -&gt; Click the &#039;Finish&#039; button" title="03 Add_to the Server 02" width="613" height="546" class="size-full wp-image-386" /></a><p class="wp-caption-text">Select openejb -> Click the 'Add' button -> Click the 'Finish' button</p></div></p>
<p>-openejb is ready to be deployed.<br />
<div id="attachment_387" class="wp-caption alignnone" style="width: 698px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/10/03_add_to_server03.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/10/03_add_to_server03.jpg" alt="openejb is deployed." title="07 Add to the Server 03" width="688" height="509" class="size-full wp-image-387" /></a><p class="wp-caption-text">openejb is deployed.</p></div></p>
<p>-Now run the server to deploy openejb.<br />
<div id="attachment_388" class="wp-caption alignnone" style="width: 698px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/10/04_run_server01.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/10/04_run_server01.jpg" alt="Run the server to deploy openejb" title="08 Run the Server 01" width="688" height="509" class="size-full wp-image-388" /></a><p class="wp-caption-text">Run the server to deploy openejb</p></div></p>
<p>-openejb is successfully deployed.<br />
<div id="attachment_389" class="wp-caption alignnone" style="width: 698px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/10/04_run_server02.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/10/04_run_server02.jpg" alt="the openejb is successfully deployed." title="09 Run the Server 02" width="688" height="509" class="size-full wp-image-389" /></a><p class="wp-caption-text">the openejb is successfully deployed.</p></div></p>
<h2>4. Set up DataSource</h2>
<p>-openejb.xml has to be copied to the Tomcat configuration folder of the Eclipse workspace.<br />
<div id="attachment_390" class="wp-caption alignnone" style="width: 698px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/10/05_copy_openejb_xml_file01.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/10/05_copy_openejb_xml_file01.jpg" alt="openejb.xml has to be copied to the Tomcat configuration folder of the Eclipse workspace." title="10 Copy openejb.xml file 01" width="688" height="509" class="size-full wp-image-390" /></a><p class="wp-caption-text">openejb.xml has to be copied to the Tomcat configuration folder of the Eclipse workspace.</p></div></p>
<p>If you are using Tomcat without OpenEJB and want to create a DataSource, you might do by putting the DataSource info to Tomcat&#8217;s server.xml file or your application&#8217;s context configuration file (your_app/META-INF/context.xml).  Yet to create the DataSource for JPA, you need to do through <code>openejb.xml</code> file. It is created in the Tomcat folder in the <code>.metadata</code> folder of your Eclipse workspace when the openejb project is deployed. However, it is not copied automatically to the configuration folder of your Eclipse workspace, you should copy the openejb.xml file to the Server configuration folder manually. If the location of the workspace is &#8216;/home/username/workspace&#8217;, the Tomcat is in &#8216;/home/username/test-workspace/.metadata/.plugins/org.eclipse.wst.server.core&#8217; and the openejb.xml file can be found in the &#8216;/home/username/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/conf&#8217; directory.</p>
<p>-Find the openejb.xml file and copy to the Tomcat configuration folder of the Eclipse workspace.<br />
<div id="attachment_391" class="wp-caption alignnone" style="width: 625px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/10/05_copy_openejb_xml_file02.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/10/05_copy_openejb_xml_file02.jpg" alt="Find the openejb.xml file and copy to the Tomcat configuration folder of the Eclipse workspace." title="11 Copy openejb.xml file 02" width="615" height="309" class="size-full wp-image-391" /></a><p class="wp-caption-text">Find the openejb.xml file and copy to the Tomcat configuration folder of the Eclipse workspace.</p></div><br />
<div id="attachment_392" class="wp-caption alignnone" style="width: 698px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/10/05_copy_openejb_xml_file03.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/10/05_copy_openejb_xml_file03.jpg" alt="Paste the file to the Tomcat configuration folder of the Eclipse workspace." title="12 Copy openejb.xml file 03" width="688" height="509" class="size-full wp-image-392" /></a><p class="wp-caption-text">Paste the file to the Tomcat configuration folder of the Eclipse workspace.</p></div></p>
<p>-Open the &#8216;openejb.xml&#8217; file then you can find the default DataSources.<br />
<div id="attachment_395" class="wp-caption alignnone" style="width: 698px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/10/06_set_up_datasource01.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/10/06_set_up_datasource01.jpg" alt="Open the &#039;openejb.xml&#039; file then you can find the default DataSources" title="13 Set up the datasource 01" width="688" height="509" class="size-full wp-image-395" /></a><p class="wp-caption-text">Open the 'openejb.xml' file then you can find the default DataSources</p></div><br />
One is JTA managed while the other is not. Both use <a href="http://hsqldb.org" title="HSQLDB" target="_blank">HSQLDB</a> which is a Java database. If you don&#8217;t have any database installed on you computer or if you want, you can use it.  As mentioned early, I am going to use MySQL so a new data source set up for MySQL is required.</p>
<p>-Add the following lines and modify for your own database.</p>
<pre class="brush: xml; gutter: false;">
&lt;Resource id=&quot;mysqlDataSource&quot; type=&quot;javax.sql.DataSource&quot;&gt;
	JdbcDriver      	com.mysql.jdbc.Driver
	JdbcUrl         	jdbc:mysql://localhost:3306/test_db
	UserName        	test_user
	Password        	1234
	JtaManaged      	true
	DefaultAutoCommit 	true
	InitialSize     	3
	MaxActive       	20
	MinIdle         	20
	MaxIdle         	0
	MaxWait         	50000
	ValidationQuery 	SELECT 1
	TestOnBorrow    	true
	TestOnReturn    	false
	TestWhileIdle   	false
&lt;/Resource&gt;
</pre>
<div id="attachment_396" class="wp-caption alignnone" style="width: 698px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/10/06_set_up_datasource02.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/10/06_set_up_datasource02.jpg" alt="DataSource to access the MySQL database." title="14 Set up the datasource 02" width="688" height="624" class="size-full wp-image-396" /></a><p class="wp-caption-text">DataSource to access the MySQL database.</p></div>
<p>If you want to use OpenJPA as an implmentation of the JPA, you can do now. However, to use Hibernate there is one more step to do.</p>
<h2>5. Install Hibernate</h2>
<p>If you just have the Hibernate jar files in your application directory (e.g. your_app/WEB-INF/lib), the EJB container that is OpenEJB cannot find the hibernate classes as it is the container, it tries to find the hibernate class from the server&#8217;s lib directory. Thus just like you need to copy the JDBC driver, in this post it&#8217;s &#8216;Connector/J&#8217;, to the tomcat&#8217;s lib directory, the hibernate jar files should be placed in the Tomcat&#8217;s lib directory.</p>
<p>Otherwise, you will get an error like this.</p>
<pre class="brush: plain; gutter: false;">
ERROR - Unable to deploy collapsed ear in war /test-web-hibernate: Exception: Creating application failed: /home/username/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/test-web-hibernate: java.lang.ClassNotFoundException: org.hibernate.ejb.HibernatePersistence: org.hibernate.ejb.HibernatePersistence
org.apache.openejb.OpenEJBException: Creating application failed: /home/username/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/test-web-hibernate: java.lang.ClassNotFoundException: org.hibernate.ejb.HibernatePersistence: org.hibernate.ejb.HibernatePersistence
	at org.apache.openejb.assembler.classic.Assembler.createApplication(Assembler.java:658)
	at org.apache.openejb.assembler.classic.Assembler.createApplication(Assembler.java:442)
	at org.apache.openejb.tomcat.catalina.TomcatWebAppBuilder.start(TomcatWebAppBuilder.java:249)
	at org.apache.openejb.tomcat.catalina.GlobalListenerSupport.lifecycleEvent(GlobalListenerSupport.java:58)
	at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:119)
	at org.apache.catalina.core.StandardContext.start(StandardContext.java:4339)
	at org.apache.catalina.core.StandardContext.reload(StandardContext.java:3190)
	at org.apache.catalina.loader.WebappLoader.backgroundProcess(WebappLoader.java:404)
	at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1309)
	at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1601)
	at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1610)
	at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1610)
	at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1590)
	at java.lang.Thread.run(Thread.java:619)
Caused by: org.apache.openejb.OpenEJBException: java.lang.ClassNotFoundException: org.hibernate.ejb.HibernatePersistence: org.hibernate.ejb.HibernatePersistence
	at org.apache.openejb.assembler.classic.Assembler.createApplication(Assembler.java:487)
	... 13 more
Caused by: java.lang.ClassNotFoundException: org.hibernate.ejb.HibernatePersistence
	at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1387)
	at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1233)
	at org.apache.openejb.assembler.classic.PersistenceBuilder.createEntityManagerFactory(PersistenceBuilder.java:177)
	at org.apache.openejb.assembler.classic.Assembler.createApplication(Assembler.java:482)
	... 13 more
</pre>
<div class="txc-textbox" style="border: 3px solid rgb(243, 197, 52); padding: 10px; background-color: rgb(254, 254, 184);">
So you have to copy the hibernate to the Tomcat&#8217;s lib directory. Unfortunately, the latest version of Hibernate (3.4.0GA) does not work on OpenEJB 3.1.1 yet I found the 3.2.1GA version works. However, there is another problem. When you try to use Tomcat, OpenEJB and Hibernate, it may not work well with the dependency libraries required by Hibernate 3.2.1GA so you should carefully choose the dependency files.  This means you need to test and find which ones are working well with OpenEJB and which are not.  Fortunately, here is a good news.  I tested and found the files working well with Tomcat 6 and OpenEJB and zipped the files. Thus you can simply download this file and extract it to the $TOMCAT/lib directory.</p>
<p><a href="http://blog.lckymn.com/wp-content/uploads/2009/10/hibernate-jpa-3.2.1ga.tar.gz">Click Here to Download the File!</a></p>
<p>After downloading, extract all the files inside to the Tomcat&#8217;s lib directory (<code>$TOMCAT/lib</code>) just like what you did to install JDBC driver, Connector/J.
</div>
<h2>6. Adding logger configuration (Optional)</h2>
<p>By default, OpenEJB creates a log file in the Eclipse&#8217;s $TOMCAT/logs directory. It is very inconvenient as you have to open the file when you want to get information from the log.  However, it is very easy to change this to make it displayed on the Console view of Eclipse.</p>
<p>-Right click on the Tomcat configuration folder -> Select &#8216;New&#8217; -> Select &#8216;File&#8217; -> crated a file with the name &#8216;logging.properties&#8217;.<br />
<div id="attachment_398" class="wp-caption alignnone" style="width: 698px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/10/07_add_logger_config01.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/10/07_add_logger_config01.jpg" alt="Right click on the Tomcat configuration folder -&gt; Select &#039;New&#039; -&gt; Select &#039;File&#039; -&gt; crated a file with the name &#039;logging.properties&#039;." title="15 Add the logger config 01" width="688" height="543" class="size-full wp-image-398" /></a><p class="wp-caption-text">Right click on the Tomcat configuration folder -> Select 'New' -> Select 'File' -> crated a file with the name 'logging.properties'.</p></div></p>
<p>-Open the file and put the following lines</p>
<pre class="brush: plain; gutter: false;">
log4j.rootLogger                   = fatal,C
log4j.category.OpenEJB             = warn
log4j.category.OpenEJB.options     = info
log4j.category.OpenEJB.server      = info
log4j.category.OpenEJB.startup     = info
log4j.category.OpenEJB.startup.service = warn
log4j.category.OpenEJB.startup.config = info
log4j.category.OpenEJB.hsql        = info
log4j.category.CORBA-Adapter       = info
log4j.category.Transaction         = warn
log4j.category.org.apache.activemq = error
log4j.category.org.apache.geronimo = error
log4j.category.openjpa             = error

log4j.appender.C                   = org.apache.log4j.ConsoleAppender
log4j.appender.C.layout            = org.apache.log4j.SimpleLayout
</pre>
<div id="attachment_399" class="wp-caption alignnone" style="width: 698px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/10/07_add_logger_config02.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/10/07_add_logger_config02.jpg" alt="Put the logger config details" title="16 Add the logger config 02" width="688" height="543" class="size-full wp-image-399" /></a><p class="wp-caption-text">Put the logger config details</p></div>
<h2>7. Create Web Application Project</h2>
<p>Now, you can develop a web application using EJB3 and Hibernate as the implementation of the JPA.</p>
<p>-Right click on the project explorer -> Select &#8216;New&#8217; -> Select &#8216;Dynamic Web Project&#8217;<br />
<div id="attachment_400" class="wp-caption alignnone" style="width: 698px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/10/08_create_project01.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/10/08_create_project01.jpg" alt="Right click on the project explorer -&gt; Select &#039;New&#039; -&gt; Select &#039;Dynamic Web Project&#039;" title="17 Create Project 01" width="688" height="543" class="size-full wp-image-400" /></a><p class="wp-caption-text">Right click on the project explorer -> Select 'New' -> Select 'Dynamic Web Project'</p></div></p>
<p>-Put the name you like -> Select the &#8216;Apache Tomcat v6.0&#8242; as the target runtime -> Select &#8216;2.5&#8242; as the version of &#8216;Dynamic Web Module&#8217; -> Select the default Tomcat configuration or your own one -> Click the &#8216;Next&#8217; button.<br />
<div id="attachment_401" class="wp-caption alignnone" style="width: 715px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/10/08_create_project02.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/10/08_create_project02.jpg" alt="Put the name you like -&gt; Select the &#039;Apache Tomcat v6.0&#039; as the target runtime -&gt; Select &#039;2.5&#039; as the version of &#039;Dynamic Web Module&#039; -&gt; Select the default Tomcat configuration or your own one -&gt; Click the &#039;Next&#039; button." title="18 Create Project 02" width="705" height="640" class="size-full wp-image-401" /></a><p class="wp-caption-text">Put the name you like -> Select the 'Apache Tomcat v6.0' as the target runtime -> Select '2.5' as the version of 'Dynamic Web Module' -> Select the default Tomcat configuration or your own one -> Click the 'Next' button.</p></div></p>
<p>-Change the project context root and directory names if you like -> Click the &#8216;Finish&#8217; button.<br />
<div id="attachment_402" class="wp-caption alignnone" style="width: 715px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/10/08_create_project03.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/10/08_create_project03.jpg" alt="Change the project context root and directory names if you like -&gt; Click the &#039;Finish&#039; button." title="19 Create Project 03" width="705" height="640" class="size-full wp-image-402" /></a><p class="wp-caption-text">Change the project context root and directory names if you like -> Click the 'Finish' button.</p></div></p>
<p>-Right click on the Server to add the project -> Select the &#8216;Add and Remove Projects&#8230;&#8217;.<br />
<div id="attachment_403" class="wp-caption alignnone" style="width: 698px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/10/08_create_project04.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/10/08_create_project04.jpg" alt="Right click on the Server to add the project -&gt; Select the &#039;Add and Remove Projects...&#039;." title="20 Create Project 04" width="688" height="543" class="size-full wp-image-403" /></a><p class="wp-caption-text">Right click on the Server to add the project -> Select the 'Add and Remove Projects...'.</p></div></p>
<p>-Select the project you created -> Click the &#8216;Add&#8217; button -> Click the &#8216;Finish&#8217; button.<br />
<div id="attachment_404" class="wp-caption alignnone" style="width: 623px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/10/08_create_project05.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/10/08_create_project05.jpg" alt="Select the project you created -&gt; Click the &#039;Add&#039; button -&gt; Click the &#039;Finish&#039; button." title="21 Create Project 05" width="613" height="546" class="size-full wp-image-404" /></a><p class="wp-caption-text">Select the project you created -> Click the 'Add' button -> Click the 'Finish' button.</p></div></p>
<p>-Both openejb and your project are added.<br />
<div id="attachment_405" class="wp-caption alignnone" style="width: 698px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/10/08_create_project06.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/10/08_create_project06.jpg" alt="Both openejb and your project are added." title="22 Create Project 06" width="688" height="543" class="size-full wp-image-405" /></a><p class="wp-caption-text">Both openejb and your project are added.</p></div></p>
<h2>8. Make JPA Project</h2>
<p>To use the JPA support feature of Eclipse, you need to change the project facet configuration.</p>
<p>-Right click on your project -> Select the &#8216;Properties&#8217;.<br />
<div id="attachment_406" class="wp-caption alignnone" style="width: 702px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/10/09_make_jpa_project01.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/10/09_make_jpa_project01.jpg" alt="Right click on your project -&gt; Select the &#039;Properties&#039;." title="23 Make JPA Project 01" width="692" height="525" class="size-full wp-image-406" /></a><p class="wp-caption-text">Right click on your project -> Select the 'Properties'.</p></div></p>
<p>-Select the &#8216;Project Facets&#8217; -> Check &#8216;Java Persistence 1.0&#8242; -> Click the &#8216;Further configuration available&#8230;&#8217; link.<br />
<div id="attachment_407" class="wp-caption alignnone" style="width: 666px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/10/09_make_jpa_project02.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/10/09_make_jpa_project02.jpg" alt="Select the &#039;Project Facets&#039; -&gt; Check &#039;Java Persistence 1.0&#039; -&gt; Click the &#039;Further configuration available...&#039; link." title="24 Make JPA Project 02" width="656" height="574" class="size-full wp-image-407" /></a><p class="wp-caption-text">Select the 'Project Facets' -> Check 'Java Persistence 1.0' -> Click the 'Further configuration available...' link.</p></div></p>
<p>-Select &#8216;Generic&#8217; -> Select &#8216;None&#8217; or your own connection or add a new connection if you wish -> Select &#8216;Use implementation provided by server runtime&#8217; -> Select &#8216;Discover annotated classes automatically&#8217; -> Uncheck &#8216;Create orm.xml&#8217; option -> Click the &#8216;OK&#8217; button.<br />
<div id="attachment_408" class="wp-caption alignnone" style="width: 623px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/10/09_make_jpa_project03.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/10/09_make_jpa_project03.jpg" alt="Select &#039;Generic&#039; -&gt; Select &#039;None&#039; or your own connection or add a new connection if you wish -&gt; Select &#039;Use implementation provided by server runtime&#039; -&gt; Select &#039;Discover annotated classes automatically&#039; -&gt; Uncheck &#039;Create orm.xml&#039; option -&gt; Click the &#039;OK&#039; button." title="25 Make JPA Project 03" width="613" height="660" class="size-full wp-image-408" /></a><p class="wp-caption-text">Select 'Generic' -> Select 'None' or your own connection or add a new connection if you wish -> Select 'Use implementation provided by server runtime' -> Select 'Discover annotated classes automatically' -> Uncheck 'Create orm.xml' option -> Click the 'OK' button.</p></div><br />
(I do usually not set up the connection yet if you want to generate entity classes from the existing tables, you&#8217;d better set it up).</p>
<h2>9. Add Java EE 5 API library file</h2>
<p>You also need to add the Java EE 5 API library file so you can use all the necessary annotations required for EJB3 and JPA.</p>
<p>-Select &#8216;Java Build Path on the left-hand side menu -> Select the &#8216;Libraries&#8217; tab -> Click the &#8216;Add JARs&#8230;&#8217; button.<br />
<div id="attachment_409" class="wp-caption alignnone" style="width: 914px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/10/10_add_javaee-api02.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/10/10_add_javaee-api02.jpg" alt="Select &#039;Java Build Path on the left-hand side menu -&gt; Select the &#039;Libraries&#039; tab -&gt; Click the &#039;Add JARs...&#039; button." title="26 Add JavaEE API 02" width="904" height="584" class="size-full wp-image-409" /></a><p class="wp-caption-text">Select 'Java Build Path on the left-hand side menu -> Select the 'Libraries' tab -> Click the 'Add JARs...' button.</p></div></p>
<p>-Select &#8216;javaee-api-5.0-2.jar in the openejb/WebContent/lib directory -> Click the &#8216;OK&#8217; button.<br />
<div id="attachment_410" class="wp-caption alignnone" style="width: 480px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/10/10_add_javaee-api03.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/10/10_add_javaee-api03.jpg" alt="Select &#039;javaee-api-5.0-2.jar in the openejb/WebContent/lib directory -&gt; Click the &#039;OK&#039; button." title="27 Add JavaEE 5 API 03" width="470" height="761" class="size-full wp-image-410" /></a><p class="wp-caption-text">Select 'javaee-api-5.0-2.jar in the openejb/WebContent/lib directory -> Click the 'OK' button.</p></div></p>
<p>-Click the &#8216;OK&#8217; button.<br />
<div id="attachment_411" class="wp-caption alignnone" style="width: 914px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/10/10_add_javaee-api04.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/10/10_add_javaee-api04.jpg" alt="Click the &#039;OK&#039; button." title="28 Add JavaEE 5 API 04" width="904" height="584" class="size-full wp-image-411" /></a><p class="wp-caption-text">Click the 'OK' button.</p></div><br />
-JPA configuration file (persistence.xml) is added.<br />
<div id="attachment_412" class="wp-caption alignnone" style="width: 698px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/10/12_config_persistence_xml01.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/10/12_config_persistence_xml01.jpg" alt="JPA configuration file (persistence.xml) is added" title="29 Config persistence_xml 01" width="688" height="525" class="size-full wp-image-412" /></a><p class="wp-caption-text">JPA configuration file (persistence.xml) is added</p></div></p>
<h2>10. Configure persistence.xml file</h2>
<p>It&#8217;s the last step before starting to programme the actual application.</p>
<p>-Open the persistence.xml file -> Type &#8216;org.hibernate.ejb.HibernatePersistence&#8217; to the &#8216;Persistence Provider&#8217;.</p>
<pre class="brush: plain; gutter: false;">
org.hibernate.ejb.HibernatePersistence
</pre>
<div id="attachment_413" class="wp-caption alignnone" style="width: 698px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/10/12_config_persistence_xml02.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/10/12_config_persistence_xml02.jpg" alt="Open the persistence.xml file -&gt; put &#039;org.hibernate.ejb.HibernatePersistence&#039; to the &#039;Persistence Provider&#039;." title="30 Config persistence_xml 02" width="688" height="543" class="size-full wp-image-413" /></a><p class="wp-caption-text">Open the persistence.xml file -> put 'org.hibernate.ejb.HibernatePersistence' to the 'Persistence Provider'.</p></div>
<p>-Click the &#8216;Connection&#8217; tab -> Select the &#8216;JTA&#8217; as the &#8216;Transaction Type&#8217; -> Type &#8216;mysqlDataSource&#8217; or your datasource name added in the previous steps. -> Press &#8216;Ctrl + S&#8217; keys to save the file.<br />
<div id="attachment_414" class="wp-caption alignnone" style="width: 698px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/10/12_config_persistence_xml03.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/10/12_config_persistence_xml03.jpg" alt="Click the &#039;Connection&#039; tab -&gt; Select the &#039;JTA&#039; as the &#039;Transaction Type&#039; -&gt; Type &#039;mysqlDataSource&#039; or your datasource name added in the previous steps. -&gt; Press &#039;Ctrl + S&#039; keys to save the file." title="31 Config persistence.xml 03" width="688" height="543" class="size-full wp-image-414" /></a><p class="wp-caption-text">Click the 'Connection' tab -> Select the 'JTA' as the 'Transaction Type' -> Type 'mysqlDataSource' or your datasource name added in the previous steps. -> Press 'Ctrl + S' keys to save the file.</p></div></p>
<p>-If you select the &#8216;Source&#8217; tab, you should see the XML like this.<br />
<div id="attachment_415" class="wp-caption alignnone" style="width: 740px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/10/12_config_persistence_xml04.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/10/12_config_persistence_xml04.jpg" alt="If you select the &#039;Source&#039; tab, you should see the XML like above." title="32 Config persistence.xml 04" width="730" height="537" class="size-full wp-image-415" /></a><p class="wp-caption-text">If you select the 'Source' tab, you should see the XML like above.</p></div></p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;persistence version=&quot;1.0&quot;
	xmlns=&quot;http://java.sun.com/xml/ns/persistence&quot;
	xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xsi:schemaLocation=&quot;http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd&quot;&gt;
	&lt;persistence-unit name=&quot;test-web-hibernate&quot; transaction-type=&quot;JTA&quot;&gt;
		&lt;provider&gt;org.hibernate.ejb.HibernatePersistence&lt;/provider&gt;
		&lt;jta-data-source&gt;mysqlDataSource&lt;/jta-data-source&gt;
	&lt;/persistence-unit&gt;
&lt;/persistence&gt;
</pre>
<p>-If you want Hibernate to automatically create the database tables based on your entity classes every time the server is restarted (in other words, the application is re-deployed), You can add Hibernate specific properties.</p>
<pre class="brush: xml; highlight: [9,10,11];">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;persistence version=&quot;1.0&quot;
	xmlns=&quot;http://java.sun.com/xml/ns/persistence&quot;
	xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xsi:schemaLocation=&quot;http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd&quot;&gt;
	&lt;persistence-unit name=&quot;test-web-hibernate&quot; transaction-type=&quot;JTA&quot;&gt;
		&lt;provider&gt;org.hibernate.ejb.HibernatePersistence&lt;/provider&gt;
		&lt;jta-data-source&gt;mysqlDataSource&lt;/jta-data-source&gt;
		&lt;properties&gt;
			&lt;property name=&quot;hibernate.hbm2ddl.auto&quot; value=&quot;create&quot; /&gt;
		&lt;/properties&gt;
	&lt;/persistence-unit&gt;
&lt;/persistence&gt;
</pre>
<h2>11. Test</h2>
<p>Finally, we have the development environment ready. To test, if I can use EJB3 and JPA with Hibernate on Tomcat, I made a very simple application.  The way I design it is not my usual way yet I used Generic DAO pattern which I usually use.</p>
<h3>11.1. Entity classes</h3>
<p>Here is my only entity class in this test.</p>
<pre class="brush: java;">
package com.lckymn.kevin.test.openejb.domain;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = &quot;users&quot;)
public class User implements Serializable
{
	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(name = &quot;user_id&quot;)
	private Long id;

	@Column(name = &quot;username&quot;, nullable = false, length = 30)
	private String username;

	@Column(name = &quot;surname&quot;, nullable = false, length = 50)
	private String surname;

	@Column(name = &quot;given_name&quot;, nullable = false, length = 50)
	private String givenName;

	@Column(name = &quot;email&quot;, nullable = true, length = 255)
	private String email;

	public Long getId()
	{
		return id;
	}

	public String getUsername()
	{
		return username;
	}

	public void setUsername(String username)
	{
		this.username = username;
	}

	public String getSurname()
	{
		return surname;
	}

	public void setSurname(String surname)
	{
		this.surname = surname;
	}

	public String getGivenName()
	{
		return givenName;
	}

	public void setGivenName(String givenName)
	{
		this.givenName = givenName;
	}

	public String getEmail()
	{
		return email;
	}

	public void setEmail(String email)
	{
		this.email = email;
	}

	@Override
	public boolean equals(Object obj)
	{
		if (this == obj)
		{
			return true;
		}

		if (!(obj instanceof User))
		{
			return false;
		}
		User that = (User) obj;
		return (username == that.getUsername() || (null != username &amp;&amp; username.equals(that.getUsername())));
	}

	@Override
	public int hashCode()
	{
		return (null == username ? 0 : username.hashCode());
	}
}
</pre>
<h3>11.2. Generic DAOs</h3>
<pre class="brush: java;">
package com.lckymn.kevin.test.openejb.dao;

public interface GenericDao&lt;E, K&gt;
{
	E find(K id);

	void persist(E e);

	void remove(E e);
}
</pre>
<pre class="brush: java;">
package com.lckymn.kevin.test.openejb.dao;

import java.lang.reflect.ParameterizedType;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

public abstract class AbstractGenericDao&lt;E, K&gt; implements GenericDao&lt;E, K&gt;
{
	private Class&lt;E&gt; classType;

	@PersistenceContext(unitName = &quot;test-web-hibernate&quot;)
	private EntityManager entityManager;

	@SuppressWarnings(&quot;unchecked&quot;)
	public AbstractGenericDao()
	{
		ParameterizedType parameterizedType = (ParameterizedType) getClass().getGenericSuperclass();
		classType = (Class&lt;E&gt;) parameterizedType.getActualTypeArguments()[0];
	}

	protected final EntityManager getEntityManager()
	{
		if (null == entityManager)
		{
			throw new IllegalStateException(&quot;EntityManager is not injected.&quot;);
		}
		return entityManager;
	}

	@Override
	public E find(K id)
	{
		return getEntityManager().find(classType, id);
	}

	@Override
	public void persist(E e)
	{
		getEntityManager().persist(e);
	}

	@Override
	public void remove(E e)
	{
		getEntityManager().remove(e);
	}
}
</pre>
<pre class="brush: java;">
package com.lckymn.kevin.test.openejb.dao;

import java.util.List;

import javax.ejb.Local;

import com.lckymn.kevin.test.openejb.domain.User;

@Local
public interface UserDao extends GenericDao&lt;User, Long&gt;
{
	List&lt;User&gt; getUsersByGivenName(String givenName);
}
</pre>
<pre class="brush: java;">
package com.lckymn.kevin.test.openejb.dao;

import java.util.List;

import javax.ejb.Stateless;

import com.lckymn.kevin.test.openejb.domain.User;

@Stateless
public class UserDaoImpl extends AbstractGenericDao&lt;User, Long&gt; implements UserDao
{
	@SuppressWarnings(&quot;unchecked&quot;)
	@Override
	public List&lt;User&gt; getUsersByGivenName(String givenName)
	{
		return getEntityManager().createQuery(&quot;from User where givenName = ?&quot;)
				.setParameter(1, givenName)
				.getResultList();
	}
}
</pre>
<h3>11.3. Services</h3>
<pre class="brush: java;">
package com.lckymn.kevin.test.openejb.service;

import java.util.List;

import javax.ejb.Local;

import com.lckymn.kevin.test.openejb.domain.User;

@Local
public interface UserService
{
	User getUser(long id);

	void AddUser(User user);

	List&lt;User&gt; getUserByGivenName(String givenName);
}
</pre>
<pre class="brush: java;">
package com.lckymn.kevin.test.openejb.service;

import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Stateless;

import com.lckymn.kevin.test.openejb.dao.UserDao;
import com.lckymn.kevin.test.openejb.domain.User;

@Stateless
public class UserServiceBean implements UserService
{
	@EJB
	private UserDao userDao;

	@Override
	public User getUser(long id)
	{
		return userDao.find(id);
	}

	@Override
	public void AddUser(User user)
	{
		userDao.persist(user);
	}

	@Override
	public List&lt;User&gt; getUserByGivenName(String givenName)
	{
		return userDao.getUsersByGivenName(givenName);
	}

}
</pre>
<h3>11. 4. Servlets</h3>
<pre class="brush: java;">
package com.lckymn.kevin.test.openejb.web;

import java.io.IOException;

import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.lckymn.kevin.test.openejb.domain.User;
import com.lckymn.kevin.test.openejb.service.UserService;

public class TestServlet extends HttpServlet
{
	private static final long serialVersionUID = 1L;

	@EJB
	private UserService userService;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{
		doPost(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{
		User user = new User();
		user.setUsername(&quot;kevinlee&quot;);
		user.setSurname(&quot;Lee&quot;);
		user.setGivenName(&quot;Kevin&quot;);
		user.setEmail(&quot;test@test.test&quot;);

		userService.AddUser(user);

		HttpSession session = request.getSession();
		session.setAttribute(&quot;user&quot;, user);

		getServletContext().getRequestDispatcher(&quot;/index.jsp&quot;)
				.forward(request, response);
	}

}
</pre>
<h3>11.5. Deployment Descriptor (web.xml)</h3>
<pre class="brush: java;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;web-app xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xmlns=&quot;http://java.sun.com/xml/ns/javaee&quot; xmlns:web=&quot;http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&quot;
	xsi:schemaLocation=&quot;http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&quot;
	id=&quot;WebApp_ID&quot; version=&quot;2.5&quot;&gt;
	&lt;display-name&gt;test-web-hibernate&lt;/display-name&gt;
	&lt;servlet&gt;
		&lt;description&gt;&lt;/description&gt;
		&lt;display-name&gt;TestServlet&lt;/display-name&gt;
		&lt;servlet-name&gt;TestServlet&lt;/servlet-name&gt;
		&lt;servlet-class&gt;com.lckymn.kevin.test.openejb.web.TestServlet&lt;/servlet-class&gt;
	&lt;/servlet&gt;
	&lt;servlet-mapping&gt;
		&lt;servlet-name&gt;TestServlet&lt;/servlet-name&gt;
		&lt;url-pattern&gt;/Test&lt;/url-pattern&gt;
	&lt;/servlet-mapping&gt;
	&lt;welcome-file-list&gt;
		&lt;welcome-file&gt;index.jsp&lt;/welcome-file&gt;
	&lt;/welcome-file-list&gt;
&lt;/web-app&gt;
</pre>
<h3>11. 6. index.jsp</h3>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?&gt;
&lt;%@ page language=&quot;java&quot; contentType=&quot;text/html; charset=UTF-8&quot;
    pageEncoding=&quot;UTF-8&quot;%&gt;
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
&lt;head&gt;
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot; /&gt;
&lt;title&gt;Insert title here&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div&gt;
	&lt;table&gt;
		&lt;tr&gt;
			&lt;td&gt;User ID: &lt;/td&gt;&lt;td&gt;${user.id }&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;Username: &lt;/td&gt;&lt;td&gt;${user.username }&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;Surname: &lt;/td&gt;&lt;td&gt;${user.surname }&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;Given name: &lt;/td&gt;&lt;td&gt;${user.givenName }&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;Email: &lt;/td&gt;&lt;td&gt;${user.email }&lt;/td&gt;
		&lt;/tr&gt;
	&lt;/table&gt;
&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<h2>12. Run the test application</h2>
<p>Access the application URI</p>
<pre class="brush: plain; gutter: false;">
http://localhost:8080/test-web-hibernate/Test
</pre>
<p>It gives me this result.</p>
<pre class="brush: plain; gutter: false;">
User ID: 	1
Username: 	kevinlee
Surname: 	Lee
Given name: 	Kevin
Email: 	test@test.test
</pre>
<div class="txc-textbox" style="border: 3px solid rgb(243, 197, 52); padding: 10px; background-color: rgb(254, 254, 184);">
*** Important ***<br />
Note: Whenever you make changes in your application, Tomcat restarts the application context so that you don&#8217;t need to restart the server to apply the changes you made.  However, as mentioned several times, you are now using the EJB container so restarting application context is not enough to get your changes applied. Therefore, the EJB container has to be restarted which means you need to restart the Tomcat server to get the changes applied.
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.lckymn.com/2009/10/17/java-ee-application-development-using-tomcat-openejb-and-hibernate/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>VMware and SpringSource</title>
		<link>http://blog.lckymn.com/2009/08/11/vmware-and-springsource/</link>
		<comments>http://blog.lckymn.com/2009/08/11/vmware-and-springsource/#comments</comments>
		<pubDate>Tue, 11 Aug 2009 08:10:49 +0000</pubDate>
		<dc:creator>Kevin</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Spring Framework]]></category>
		<category><![CDATA[Acquire]]></category>
		<category><![CDATA[SpringSource]]></category>
		<category><![CDATA[VMware]]></category>
		<category><![CDATA[VMware and SpringSource]]></category>

		<guid isPermaLink="false">http://blog.lckymn.com/?p=372</guid>
		<description><![CDATA[<p>I heard very surprising news today morning which is <a href="http://www.springsource.com" target="_blank">SpringSource</a> has agreed to be acquired by <a href="http://www.vmware.com" target="_blank">VMware</a>.</p>
<p><a href="http://blog.springsource.com/2009/08/10/springsource-chapter-two/" target="_blank">http://blog.springsource.com/2009/08/10/springsource-chapter-two/</a>
<a href="http://www.vmware.com/company/news/releases/springsource.html" target="_blank">http://www.vmware.com/company/news/releases/springsource.html</a>
<a href="http://blogs.vmware.com/console/2009/08/vmware-acquires-springsource.html" target="_blank">http://blogs.vmware.com/console/2009/08/vmware-acquires-springsource.html</a>
<a href="http://www.earthtimes.org/articles/show/vmware-to-acquire-springsource,921934.shtml" target="_blank">http://www.earthtimes.org/articles/show/vmware-to-acquire-springsource,921934.shtml</a></p>
<p>Looks like a good deal for both companies. <img src='http://blog.lckymn.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>VMware recently hired <a href="http://www.techcrunch.com/2009/07/13/google-loses-engineering-director-who-once-caused-steve-ballmer-to-melt-down/" target="_blank">Mark Lucovsky</a> from Google and now has SpringSource. I guess VMware is really doing well. <img src='http://blog.lckymn.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></description>
			<content:encoded><![CDATA[<p>I heard very surprising news today morning which is <a href="http://www.springsource.com" target="_blank">SpringSource</a> has agreed to be acquired by <a href="http://www.vmware.com" target="_blank">VMware</a>.</p>
<p><a href="http://blog.springsource.com/2009/08/10/springsource-chapter-two/" target="_blank">http://blog.springsource.com/2009/08/10/springsource-chapter-two/</a><br />
<a href="http://www.vmware.com/company/news/releases/springsource.html" target="_blank">http://www.vmware.com/company/news/releases/springsource.html</a><br />
<a href="http://blogs.vmware.com/console/2009/08/vmware-acquires-springsource.html" target="_blank">http://blogs.vmware.com/console/2009/08/vmware-acquires-springsource.html</a><br />
<a href="http://www.earthtimes.org/articles/show/vmware-to-acquire-springsource,921934.shtml" target="_blank">http://www.earthtimes.org/articles/show/vmware-to-acquire-springsource,921934.shtml</a></p>
<p>Looks like a good deal for both companies. <img src='http://blog.lckymn.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>VMware recently hired <a href="http://www.techcrunch.com/2009/07/13/google-loses-engineering-director-who-once-caused-steve-ballmer-to-melt-down/" target="_blank">Mark Lucovsky</a> from Google and now has SpringSource. I guess VMware is really doing well. <img src='http://blog.lckymn.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lckymn.com/2009/08/11/vmware-and-springsource/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Eclipse &#8211; &#8220;Too many open files&#8221; Problem</title>
		<link>http://blog.lckymn.com/2009/08/11/eclipse-too-many-open-files-problem/</link>
		<comments>http://blog.lckymn.com/2009/08/11/eclipse-too-many-open-files-problem/#comments</comments>
		<pubDate>Tue, 11 Aug 2009 07:39:39 +0000</pubDate>
		<dc:creator>Kevin</dc:creator>
				<category><![CDATA[Development Tools]]></category>
		<category><![CDATA[IT]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Ubuntu Linux]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Eclipse Ganymede]]></category>
		<category><![CDATA[Error]]></category>
		<category><![CDATA[Ganymede]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Problem]]></category>
		<category><![CDATA[Too many open files]]></category>

		<guid isPermaLink="false">http://blog.lckymn.com/?p=365</guid>
		<description><![CDATA[<p>If your OS is Linux and you are using Eclipse, you might possibly see the following error messages or similar after installing lots of plug-ins in Eclipse. In my case, it usually happened after installing <a href="http://www.eclipse.org/tptp/" target="_blank">TPTP</a> (I&#8217;m using Ubuntu Linux 9.04 Jaunty Jackalope Desktop 64bit by the way).</p>

Plug-in org.eclipse.jst.server.tomcat.core was unable to load class org.eclipse.jst.server.tomcat.core.internal.TomcatLaunchConfigurationDelegate.
 /eclipse_installed_path/eclipse/configuration/org.eclipse.osgi/.lazy.15 (Too many open files)

<p>or</p>

Problems occurred while trying to save the state of the workbench.
 Could not read master table.
 /your_workspace/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources (Too many <p style="border: 3px solid rgb(243, 197, 52); padding: 5px; background-color: rgb(254, 254, 184); width: 600px; text-align: center;">[...Continue reading <a href="http://blog.lckymn.com/2009/08/11/eclipse-too-many-open-files-problem/">Eclipse &#8211; &#8220;Too many open files&#8221; Problem</a>...]</p>]]></description>
			<content:encoded><![CDATA[<p>If your OS is Linux and you are using Eclipse, you might possibly see the following error messages or similar after installing lots of plug-ins in Eclipse. In my case, it usually happened after installing <a href="http://www.eclipse.org/tptp/" target="_blank">TPTP</a> (I&#8217;m using Ubuntu Linux 9.04 Jaunty Jackalope Desktop 64bit by the way).</p>
<pre class="brush: plain; gutter: false;">
Plug-in org.eclipse.jst.server.tomcat.core was unable to load class org.eclipse.jst.server.tomcat.core.internal.TomcatLaunchConfigurationDelegate.
 /eclipse_installed_path/eclipse/configuration/org.eclipse.osgi/.lazy.15 (Too many open files)
</pre>
<p>or</p>
<pre class="brush: plain; gutter: false;">
Problems occurred while trying to save the state of the workbench.
 Could not read master table.
 /your_workspace/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources (Too many open files)
</pre>
<p>or</p>
<pre class="brush: plain; gutter: false;">
java.util.zip.ZipException: error in opening zip file
</pre>
<p>This is because there are too many files opened and these are more files than the number of open files allowed . So Eclipse cannot open more files and displays the errors above.</p>
<p>Let&#8217;s see the number of open files.</p>
<pre class="brush: bash; gutter: false;">
$ lsof | wc -l
</pre>
<p>e.g.)</p>
<pre class="brush: bash; gutter: false;">
$ lsof | wc -l
8965
</pre>
<p>In my case, it was 8965.</p>
<p>What about the number of files Eclipse opens. To see it, use </p>
<pre class="brush: bash; gutter: false;">
$ lsof | grep eclipse | wc -l
</pre>
<p>In my case, </p>
<pre class="brush: bash; gutter: false;">
$ lsof | grep eclipse | wc -l
2094
</pre>
<p>2094 files are opened.</p>
<p>Now check the limitation of open files</p>
<pre class="brush: bash; gutter: false; highlight: [9];">
$ ulimit -a
core file size          (blocks, -c) #
data seg size           (kbytes, -d) #
scheduling priority             (-e) #
file size               (blocks, -f) #
pending signals                 (-i) #
max locked memory       (kbytes, -l) #
max memory size         (kbytes, -m) #
open files                      (-n) 1024
pipe size            (512 bytes, -p) #
POSIX message queues     (bytes, -q) #
real-time priority              (-r) #
stack size              (kbytes, -s) #
cpu time               (seconds, -t) #
max user processes              (-u) #
virtual memory          (kbytes, -v) #
file locks                      (-x) #
</pre>
<p>or just use</p>
<pre class="brush: bash; gutter: false;">
$ ulimit -n
1024
</pre>
<p>To change it, open the file /etc/security/limits.conf and put a greater number than 1024 depending on the number of open files you checked with <code>lsof | wc -l</code> just before.<br />
For example,<br />
Open the file</p>
<pre class="brush: plain; gutter: false; highlight: [3,4];">
$ gksudo gedit /etc/security/limits.conf
add these lines
*                soft    nofile          9216
*                hard    nofile          9216
</pre>
<p>I just chose some big number that is 9216 (9 * 1024) as it&#8217;s greater than 8965 </p>
<p>Log out and in then check with ulimit. It should show like this.</p>
<pre class="brush: bash; gutter: false;">
$ ulimit -n
9216
</pre>
<p>You may try this</p>
<pre class="brush: bash; gutter: false;">
$ ulimit -n 9216
</pre>
<p>yet I don&#8217;t believe it changes the limit for open files permanently. So you&#8217;d better modify <code>/etc/security/limits.conf</code> file.</p>
<p>If it is still not changed. Restart the computer and check again. If it still doesn&#8217;t show the changed value, open /etc/pam.d/common-session file and add <code>session required pam_limits.so</code>.</p>
<p>Open the file to edit</p>
<pre class="brush: bash; gutter: false;">
$ gksudo gedit /etc/pam.d/common-session
</pre>
<p>Add the following line</p>
<pre class="brush: bash; gutter: false;">
session required pam_limits.so
</pre>
<p>Log out and in. Now it should work!</p>
<pre class="brush: bash; gutter: false;">
$ ulimit -n
9216
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.lckymn.com/2009/08/11/eclipse-too-many-open-files-problem/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Method Chaining, to use, or not to use</title>
		<link>http://blog.lckymn.com/2009/06/30/method-chaining-to-use-or-not-to-use/</link>
		<comments>http://blog.lckymn.com/2009/06/30/method-chaining-to-use-or-not-to-use/#comments</comments>
		<pubDate>Mon, 29 Jun 2009 17:33:28 +0000</pubDate>
		<dc:creator>Kevin</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Coding Style]]></category>
		<category><![CDATA[Command-Query Separation]]></category>
		<category><![CDATA[Debug]]></category>
		<category><![CDATA[Domain-Driven Design]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Fluent Interface]]></category>
		<category><![CDATA[Formatter]]></category>
		<category><![CDATA[Formatting]]></category>
		<category><![CDATA[JavaBean]]></category>
		<category><![CDATA[Method Chaining]]></category>
		<category><![CDATA[Readable]]></category>

		<guid isPermaLink="false">http://blog.lckymn.com/?p=347</guid>
		<description><![CDATA[<p>It was a Gavin King&#8217;s book from which I first heard about <a href="http://en.wikipedia.org/wiki/Method_chaining" target="_blank">method chaining</a> since it is not that popular style in Java.</p>
<p>Bauer and King in their book entitled &#8216;Java Persistence with Hibernate&#8217; (2007), point out that method chaining is convenient in some cases and is more popular in <a href="http://en.wikipedia.org/wiki/Smalltalk" target="_blank">Smalltalk</a> than in <a href="http://en.wikipedia.org/wiki/Java_(programming_language)" target="_blank">Java</a> for Smalltalk, unlike Java, does not have <code>void</code> type. Thus when a method is invoked, it normally returns the object itself <p style="border: 3px solid rgb(243, 197, 52); padding: 5px; background-color: rgb(254, 254, 184); width: 600px; text-align: center;">[...Continue reading <a href="http://blog.lckymn.com/2009/06/30/method-chaining-to-use-or-not-to-use/">Method Chaining, to use, or not to use</a>...]</p>]]></description>
			<content:encoded><![CDATA[<p>It was a Gavin King&#8217;s book from which I first heard about <a href="http://en.wikipedia.org/wiki/Method_chaining" target="_blank">method chaining</a> since it is not that popular style in Java.</p>
<p>Bauer and King in their book entitled &#8216;Java Persistence with Hibernate&#8217; (2007), point out that method chaining is convenient in some cases and is more popular in <a href="http://en.wikipedia.org/wiki/Smalltalk" target="_blank">Smalltalk</a> than in <a href="http://en.wikipedia.org/wiki/Java_(programming_language)" target="_blank">Java</a> for Smalltalk, unlike Java, does not have <code>void</code> type. Thus when a method is invoked, it normally returns the object itself in which the method is placed.</p>
<p>Although it is used to improve readability and to reduce the amount of source code, I didn&#8217;t really like this style as it can be less readable and might make code difficult to debug. How can the technique to improve readability make the code less readable? By less readable, I mean the code may possibly be unpredictable or make the programmer confused in some cases.</p>
<p>Let&#8217;s look at some example.</p>
<p>This is a simple JavaBean named <code>Item</code></p>
<pre class="brush: java;">
package com.lckymn.kevin.test.methodchaining;

/**
 * @author Lee, SeongHyun (Kevin)
 */
public class Item
{
	private int id;
	private String name;

	public Item(int id, String name)
	{
		this.id = id;
		this.name = name;
	}

	public int getId()
	{
		return id;
	}

	public void setId(int id)
	{
		this.id = id;
	}

	public String getName()
	{
		return name;
	}

	public void setName(String name)
	{
		this.name = name;
	}

	@Override
	public String toString()
	{
		return &quot;ID: &quot; + id + &quot;\n&quot; + &quot;Name: &quot; + name + &quot;\n&quot;;
	}
}
</pre>
<p>This is a Storage class designed to use method chaining.</p>
<pre class="brush: java;">
package com.lckymn.kevin.test.methodchaining;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Lee, SeongHyun (Kevin)
 */
public class Storage
{
	private List&lt;Item&gt; items;

	public Storage()
	{
		this.items = new ArrayList&lt;Item&gt;();
	}

	public Storage put(String name)
	{
		items.clear();
		return and(name);
	}

	public Storage and(String name)
	{
		items.add(new Item(name.hashCode(), name));
		return this;
	}

	public Item get(int index)
	{
		return items.get(index);
	}

	public List&lt;Item&gt; getAll()
	{
		return items;
	}
}
</pre>
<p>Now, let&#8217;s use it.</p>
<pre class="brush: java;">
package com.lckymn.kevin.test.methodchaining;

/**
 * @author Lee, SeongHyun (Kevin)
 */
public final class MethodChainingTest
{
	public static void main(String[] args)
	{
		String name = new Storage().put(&quot;A&quot;).and(&quot;B&quot;).and(null).and(&quot;D&quot;).get(0).getName();
		System.out.println(&quot;Name: &quot; + name + &quot;\n&quot;);

		System.exit(0);
	}

}
</pre>
<p>What is this? It looks like instantiating a <code>Storage</code> object yet the end it assigns <code>String</code> value to <code>String</code> variable named <code>name</code>?</p>
<p>It seems confusing. First, instantiate <code>Storage</code>. Then call several methods in it. Finally call the method which returns a <code>String</code> value. However, the <code>Storage</code> class doesn&#8217;t even have any method returning the <code>String</code> value. It is the method in the <code>Item</code> class.</p>
<p>OK, move to the other problem that is difficulty in debuging.<br />
The example code above does not have any compile time error yet when it runs the result is </p>
<pre class="brush: bash; gutter: false;">
Exception in thread &quot;main&quot; java.lang.NullPointerException
	at com.lckymn.kevin.test.methodchaining.Storage.and(Storage.java:26)
	at com.lckymn.kevin.test.methodchaining.MethodChainingTest.main(MethodChainingTest.java:10)
</pre>
<p>The tenth line in the <code>MethodChainingTest.main</code> method is this.</p>
<pre class="brush: java; first-line: 10; highlight: [10];">
		String name = new Storage().put(&quot;A&quot;).and(&quot;B&quot;).and(null).and(&quot;D&quot;).get(0).getName();
</pre>
<p>The twenty-sixth line in the <code>Storage.and</code> method is this.</p>
<pre class="brush: java; first-line: 26; highlight: [26];">
		items.add(new Item(name.hashCode(), name));
</pre>
<p>So this line of the code causes <code>NullPointerException</code> but <code>and()</code> method is called three times in the tenth line of the <code>MethodChainingTest</code> class. Which one of these causes the error? In the example, it is very obvious that the <code>and()</code> method call with <code>null</code> parameter is the one. However, in real-life programme, it is usually much more difficult to find.</p>
<p>So, as already mentioned, I did not like using method chaining.  Then again there came a time when it was very convenient and useful to use method chaining. I found it very useful when I was making a XML generator programme for an Ajax application. I made it using <a href="http://en.wikipedia.org/wiki/JAXP" target="_blank">Java API for XML Processing (JAXP)</a>. It required to generate simple XML based on a given object so it might be too much to use <a href="http://en.wikipedia.org/wiki/XML_data_binding" target="_blank">XML data binding</a> frameworks and tools such as <a href="http://en.wikipedia.org/wiki/JAXB" target="_blank">Java Architecture for XML Binding (JAXB)</a> and <a href="http://en.wikipedia.org/wiki/XStream" target="_blank">XStream</a>. Although both JAXB and XStream are simple and easy to use and can be used to serialise objects, I wanted to have more control than what the framework provides. JAXP with <a href="http://en.wikipedia.org/wiki/Simple_API_for_XML" target="_blank">Simple API for XML (SAX)</a> parsing interface was just suitable for what I needed, yet it is not very pleasant to use the SAX interface. It uses ContentHandler interface when making XML contents and the following code is what it looks like when using it.</p>
<pre class="brush: java; gutter: false;">
contentHandler.startDocument();

AttributesImpl atts = new AttributesImpl();
atts.addAttribute(null, null, &quot;type&quot;, null, &quot;User&quot;);
contentHandler.startElement(null, null, &quot;users&quot;, atts);

atts.clear();
atts.addAttribute(null, null, &quot;id&quot;, null, &quot;kevin&quot;);
atts.addAttribute(null, null, &quot;surname&quot;, null, &quot;Lee&quot;);
atts.addAttribute(null, null, &quot;givenName&quot;, null, &quot;Kevin&quot;);
contentHandler.startElement(null, null, &quot;user&quot;, atts);
contentHandler.characters(&quot;Test value&quot;.toCharArray(), 0, &quot;Test value&quot;.length());
contentHandler.endElement(null, null, &quot;user&quot;);

atts.clear();
atts.addAttribute(null, null, &quot;id&quot;, null, &quot;john&quot;);
atts.addAttribute(null, null, &quot;surname&quot;, null, &quot;Doe&quot;);
atts.addAttribute(null, null, &quot;givenName&quot;, null, &quot;John&quot;);
contentHandler.startElement(null, null, &quot;user&quot;, atts);
contentHandler.characters(&quot;Blah Blah&quot;.toCharArray(), 0, &quot;Blah Blah&quot;.length());
contentHandler.endElement(null, null, &quot;user&quot;);

atts.clear();
atts.addAttribute(null, null, &quot;id&quot;, null, &quot;tom&quot;);
atts.addAttribute(null, null, &quot;surname&quot;, null, &quot;Smith&quot;);
atts.addAttribute(null, null, &quot;givenName&quot;, null, &quot;Tom&quot;);
contentHandler.startElement(null, null, &quot;user&quot;, atts);
contentHandler.characters(&quot;12345&quot;.toCharArray(), 0, &quot;12345&quot;.length());
contentHandler.endElement(null, null, &quot;user&quot;);

contentHandler.endElement(null, null, &quot;users&quot;);

contentHandler.endDocument();
</pre>
<p>As all I want was simple XML for an Ajax application, I had to type &#8216;<code>null</code>&#8216; many times as parameter values for namespace URI and local name which were definitely unnecessary for my programme. Since the data transfered through network need to be small, XML sent to the front-end Ajax application had better not have the data such as namespace and schema location information and so on.</p>
<p>However, what I all had was, as shown above, the ugly code which repeatedly calls same methods with many &#8216;null&#8217; parameters. So I tried to find a better way and eventually came up with that it might be a good idea to use method chaining.  Even so, there were still the two problems I mentioned.</p>
<p>The method chaining code example that I showed earlier is, in fact, a misuse of method chaining. That can be much better if it is used properly. After all, it is not the technique that makes the code less maintainable but how it is used that makes the code less maintainable.</p>
<p>Think about this. If a knife is used by a murderer, the result of using it would be a dead body while if it is used by a chef, the result would be a delicious meal unless the chef is the murderer. <img src='http://blog.lckymn.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  (I think I used this sentence when I had my presentation in the third year in my undergraduate days. The subject was about IT and ethics, and I was emphasising that technologies have nothing to do with ethics yet how we use these is important when it comes to ethics).</p>
<p>So, how can those two problems be solved? First of all, please don&#8217;t get me wrong. I am not saying that the way I am going to tell here is the best, but it is just what I do. That&#8217;s it.</p>
<p>I chose to implement <a href="http://en.wikipedia.org/wiki/Fluent_interface" target="_blank">fluent interface</a> yet with my own taste.</p>
<div class="txc-textbox" style="border: 3px solid rgb(243, 197, 52); padding: 10px; background-color: rgb(254, 254, 184);">
Cho, YoungHo (2008) in his article, &#8216;<a href="http://aeternum.egloos.com/1173825" target="_blank">Applicaiton of Domain-Driven Design 2.Aggregate and Repository #3</a>&#8216;, also says that although <a href="http://en.wikipedia.org/wiki/Fluent_interface" target="_blank">FLUENT INTERFACE</a> might violate the principle of <a href="http://en.wikipedia.org/wiki/Command-query_separation" target="_blank">COMMAND-QUERY SEPARATION</a> which enforces to separate the method to change the state of an object from the method to query the state, FLUENT INTERFACE using method chaining can enable the interface design to be more readable and easier to use.</p>
<p>If you can understand Korean and are interested in <a href="http://en.wikipedia.org/wiki/Domain-driven_design" target="_blank">Domain-Driven Design (DDD)</a>, his articles about DDD are really worth reading.<br />
<a href="http://aeternum.egloos.com/category/Domain-Driven%20Design" target="_blank">http://aeternum.egloos.com/category/Domain-Driven%20Design</a><br />
It is well written with appropriate example code and supporting theories and principles.
</div>
<p>So my tastes are<br />
1. The prefix &#8216;Fluent&#8217; shall be used to tell it is a fluent interface.<br />
e.g.)<br />
public interface FluentContentHandler<br />
public interface FluentStorage</p>
<p>2. <code>void</code> return type shall be used to stop method chaining if the method should not be used with other methods in the fluent interface or if it has some side-effect when using with other methods so that the programmer should be noticed it by void return type.<br />
e.g.)<br />
void endDoc()<br />
void finish()</p>
<p>3. Otherwise, all the methods shall return the type of interface itself, and the name of the normal methods which return the type of the interface itself shall begin with verb.<br />
e.g.)<br />
FluentContentHandler openElem(String qName)<br />
FluentContentHandler setText(String qName)<br />
FluentSaxAttributes create(String qName, String value)</p>
<p>OR<br />
The name of the method which must be used before the other methods shall begin with a verb.<br />
e.g.)<br />
FluentSaxAttributes create(String qName, String value)<br />
The name of the method which must be used after the method the name of which begins with a verb shall be an appropriate preposition or conjunction.<br />
e.g.)<br />
FluentSaxAttributes with(String qName, String value)<br />
FluentSaxAttributes and(String qName, String value)</p>
<p>4. If other types than the interface itself need to be returned, distinguishable method names shall be used. The name of the methods which return other type than the type of the interface itself shall begin with a preposition followed by a noun.<br />
e.g.)<br />
List toList()<br />
Map toMap()<br />
Collection toCollection()</p>
<p>I believe, these can help me to get over the first matter, and the code would be more readable as expected.</p>
<p>So let&#8217;s have a look at the new fluent interfaces for my XML generator programme.</p>
<pre class="brush: java;">
package com.lckymn.kevin.test.xml;

import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;

/**
 * @author Lee, SeongHyun (Kevin)
 */
public interface FluentSaxContentHandler
{
	void startDoc() throws SAXException;

	void endDoc() throws SAXException;

	FluentSaxContentHandler openElem(String qName) throws SAXException;

	FluentSaxContentHandler openElem(String qName, FluentSaxAttributes attributes) throws SAXException;

	FluentSaxContentHandler setText(String text) throws SAXException;

	void closeElem(String qName) throws SAXException;
}
</pre>
<p>The programmer using this interface had better be aware of that <code>startDoc()</code> and <code>endDoc()</code> methods are to start and to end the XML document so use it once and therefore these return <code>void</code> type to warn. Similarly, <code>closeElem()</code> method the type of which is <code>void</code> closes the element with the name given as the parameter so the programmer had better stop method chaining here and open a new element with another method chaining.</p>
<pre class="brush: java;">
package com.lckymn.kevin.test.xml;

import org.xml.sax.helpers.AttributesImpl;

/**
 * @author Lee, SeongHyun (Kevin)
 */
public interface FluentSaxAttributes
{
	FluentSaxAttributes create(String qName, String value);

	FluentSaxAttributes add(String qName, String value);

	AttributesImpl toAttributesImpl();
}
</pre>
<p>Since the <code>ContentHandler</code> requires <code>AttributesImpl</code> as attributes <code>toAttributesImpl()</code> method needs to return <code>AttributesImpl</code> and therefore its name consists of the preposition &#8216;to&#8217; and the noun &#8216;AttributesImpl&#8217;.</p>
<p>Now let&#8217;s use these.</p>
<pre class="brush: java; gutter: false;">
	contentHandler.startDoc();

	contentHandler.openElem(&quot;users&quot;, atts.create(&quot;type&quot;, &quot;User&quot;));

	contentHandler.openElem(&quot;user&quot;, atts.create(&quot;id&quot;, &quot;kevin&quot;).add(&quot;surname&quot;, &quot;Lee&quot;).add(&quot;givenName&quot;, &quot;Kevin&quot;)).setText(&quot;Test value&quot;).closeElem(&quot;user&quot;);
	contentHandler.openElem(&quot;user&quot;, atts.create(&quot;id&quot;, &quot;john&quot;).add(&quot;surname&quot;, &quot;Doe&quot;).add(&quot;givenName&quot;, &quot;John&quot;)).setText(&quot;Blah Blah&quot;).closeElem(&quot;user&quot;);
	contentHandler.openElem(&quot;user&quot;, atts.create(&quot;id&quot;, &quot;tom&quot;).add(&quot;surname&quot;, &quot;Smith&quot;).add(&quot;givenName&quot;, &quot;Tom&quot;)).setText(&quot;12345&quot;).closeElem(&quot;user&quot;);

	contentHandler.closeElem(&quot;users&quot;);

	contentHandler.endDoc();
</pre>
<p>It looks much simpler and readable than the previous code below.</p>
<pre class="brush: java; gutter: false;">
	contentHandler.startDocument();

	AttributesImpl atts = new AttributesImpl();
	atts.addAttribute(null, null, &quot;type&quot;, null, &quot;User&quot;);
	contentHandler.startElement(null, null, &quot;users&quot;, atts);

	atts.clear();
	atts.addAttribute(null, null, &quot;id&quot;, null, &quot;kevin&quot;);
	atts.addAttribute(null, null, &quot;surname&quot;, null, &quot;Lee&quot;);
	atts.addAttribute(null, null, &quot;givenName&quot;, null, &quot;Kevin&quot;);
	contentHandler.startElement(null, null, &quot;user&quot;, atts);
	contentHandler.characters(&quot;Test value&quot;.toCharArray(), 0, &quot;Test value&quot;.length());
	contentHandler.endElement(null, null, &quot;user&quot;);

	atts.clear();
	atts.addAttribute(null, null, &quot;id&quot;, null, &quot;john&quot;);
	atts.addAttribute(null, null, &quot;surname&quot;, null, &quot;Doe&quot;);
	atts.addAttribute(null, null, &quot;givenName&quot;, null, &quot;John&quot;);
	contentHandler.startElement(null, null, &quot;user&quot;, atts);
	contentHandler.characters(&quot;Blah Blah&quot;.toCharArray(), 0, &quot;Blah Blah&quot;.length());
	contentHandler.endElement(null, null, &quot;user&quot;);

	atts.clear();
	atts.addAttribute(null, null, &quot;id&quot;, null, &quot;tom&quot;);
	atts.addAttribute(null, null, &quot;surname&quot;, null, &quot;Smith&quot;);
	atts.addAttribute(null, null, &quot;givenName&quot;, null, &quot;Tom&quot;);
	contentHandler.startElement(null, null, &quot;user&quot;, atts);
	contentHandler.characters(&quot;12345&quot;.toCharArray(), 0, &quot;12345&quot;.length());
	contentHandler.endElement(null, null, &quot;user&quot;);

	contentHandler.endElement(null, null, &quot;users&quot;);

	contentHandler.endDocument();
</pre>
<p>Yet there is one more problem still left that is difficulty in debugging.</p>
<p>King and Bauer (2007) suggests that &#8220;it’s better to write each method invocation on a different line&#8221;.</p>
<p>So rewrite the code</p>
<pre class="brush: java; gutter: false;">
	contentHandler.startDoc();

	contentHandler.openElem(&quot;users&quot;, atts.create(&quot;type&quot;, &quot;User&quot;));

	contentHandler.openElem(&quot;user&quot;, atts.create(&quot;id&quot;, &quot;kevin&quot;)
			.add(&quot;surname&quot;, &quot;Lee&quot;)
			.add(&quot;givenName&quot;, &quot;Kevin&quot;))
			.setText(&quot;Test value&quot;)
			.closeElem(&quot;user&quot;);
	contentHandler.openElem(&quot;user&quot;, atts.create(&quot;id&quot;, &quot;john&quot;)
			.add(&quot;surname&quot;, &quot;Doe&quot;)
			.add(&quot;givenName&quot;, &quot;John&quot;))
			.setText(&quot;Blah Blah&quot;)
			.closeElem(&quot;user&quot;);
	contentHandler.openElem(&quot;user&quot;, atts.create(&quot;id&quot;, &quot;tom&quot;)
			.add(&quot;surname&quot;, &quot;Smith&quot;)
			.add(&quot;givenName&quot;, &quot;Tom&quot;))
			.setText(&quot;12345&quot;)
			.closeElem(&quot;user&quot;);

	contentHandler.closeElem(&quot;users&quot;);

	contentHandler.endDoc();
</pre>
<p>Now not only does it solve the problem in debugging but it is also even more readable. My problem solved! <img src='http://blog.lckymn.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /><br />
Well, unfortunately there is one more problem. <img src='http://blog.lckymn.com/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> </p>
<p>I am using Eclipse and it has a nice automatic formatting feature. So whenever I press SHIFT+CTRL+F, it automatically formats the code opened in the editor based on the format configuration. This means if I use that function, I lose the coding style of writing each method invocation on a different line as Eclipse formatter puts all the method on a different line together on one line. So do I have to reformat by myself after every automatic formatting? It&#8217;s really annoying. <img src='http://blog.lckymn.com/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> </p>
<p>Fortunately, a few changes in formatter configuration can solve this problem.</p>
<p>Click the &#8216;Window&#8217; menu -> &#8216;Preferences&#8217;</p>
<p>When the &#8216;Preferences&#8217; menu pops up<br />
-Expand the &#8216;Java&#8217; -> Expand the &#8216;Code Style&#8217; -> Select the &#8216;Fomatter&#8217;</p>
<p>-Click the &#8216;Edit&#8217; button on the top right-hand side.<br />
<div id="attachment_353" class="wp-caption alignnone" style="width: 693px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/06/formatter_configuration_01.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/06/formatter_configuration_01.jpg" alt="Expand the &#039;Java&#039; -&gt; Expand the &#039;Code Style&#039; -&gt; Select the &#039;Fomatter&#039; -&gt; Click the &#039;Edit&#039; button on the top right-hand side" title="Formatter Configuration for Method Chaining 01" width="683" height="740" class="size-full wp-image-353" /></a><p class="wp-caption-text">Expand the 'Java' -> Expand the 'Code Style' -> Select the 'Fomatter' -> Click the 'Edit' button on the top right-hand side</p></div></p>
<p>-The profile window appears -> Select the &#8216;Line Wrapping&#8217; -> Expand the &#8216;Function Calls&#8217; -> Select the &#8216;Qualified invocations&#8217; -> Select the &#8216;Wrap all elements, except first element if not necessary&#8217; as the &#8216;Line wrapping policy&#8217; -> Select the &#8216;Default indentation&#8217; as the &#8216;Indentation policy&#8217; -> Check the &#8216;Force split&#8217; -> Click the &#8216;OK&#8217; button.<br />
<div id="attachment_354" class="wp-caption alignnone" style="width: 757px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/06/formatter_configuration_02.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/06/formatter_configuration_02.jpg" alt="Profile window appears -&gt; Select the &#039;Line Wrapping&#039; -&gt; Expand the &#039;Function Calls&#039; -&gt; Select the &#039;Qualified invocations&#039; -&gt; Select the &#039;Wrap all elements, except first element if not necessary&#039; as the &#039;Line wrapping policy&#039; -&gt; Select the &#039;Default indentation&#039; as the &#039;Indentation policy&#039; -&gt; Check the &#039;Force split&#039; -&gt; Click the &#039;OK&#039; button" title="Formatter Configuration for Method Chaining 02" width="747" height="834" class="size-full wp-image-354" /></a><p class="wp-caption-text">Profile window appears -> Select the 'Line Wrapping' -> Expand the 'Function Calls' -> Select the 'Qualified invocations' -> Select the 'Wrap all elements, except first element if not necessary' as the 'Line wrapping policy' -> Select the 'Default indentation' as the 'Indentation policy' -> Check the 'Force split' -> Click the 'OK' button</p></div></p>
<p>-Click the &#8216;OK&#8217; button to apply the changes.</p>
<p>Now, the Eclipse Java formatter formats the code, using method chaining, as what I want.</p>
<p>Finally, how can I improve my first example of method chaining?<br />
The Item class does not need to be changed.</p>
<p>Write the fluent interface, FluentStorage.</p>
<pre class="brush: java;">
package com.lckymn.kevin.test.fluentinterface;

import java.util.List;

/**
 * @author Lee, SeongHyun (Kevin)
 */
public interface FluentStorage
{
	FluentStorage add(String name);

	List&lt;Item&gt; toList();
}
</pre>
<p>Write the class implements it.</p>
<pre class="brush: java;">
package com.lckymn.kevin.test.fluentinterface;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Lee, SeongHyun (Kevin)
 */
public class FluentListStorage implements FluentStorage
{
	private List&lt;Item&gt; items;

	public FluentListStorage()
	{
		items = new ArrayList&lt;Item&gt;();
	}

	@Override
	public FluentStorage add(String name)
	{
		items.add(new Item(name.hashCode(), name));
		return this;
	}

	@Override
	public List&lt;Item&gt; toList()
	{
		return items;
	}

}
</pre>
<p>Now use the fluent interface.</p>
<pre class="brush: java;">
package com.lckymn.kevin.test.fluentinterface;

import java.util.List;

/**
 * @author Lee, SeongHyun (Kevin)
 */
public final class MethodChainingTest
{
	public static void main(String[] args)
	{
		FluentStorage fluentStorage = new FluentListStorage().add(&quot;A&quot;)
				.add(&quot;B&quot;)
				.add(null)
				.add(&quot;D&quot;);

		List&lt;Item&gt; items = fluentStorage.toList();
		for (Item item : items)
		{
			System.out.println(item);
		}
		int howMany = items.size();
		System.out.println(&quot;There &quot; + (1 &lt; howMany ? &quot;are &quot; + howMany + &quot; items&quot; : &quot;is &quot; + howMany + &quot; item&quot;) + &quot; in the storage.&quot;);
		System.exit(0);
	}

}
</pre>
<p>When it runs, it displays the following error messages yet now I know that the fourteenth line causes the error.</p>
<pre class="brush: bash; gutter: false; highlight: [3];">
Exception in thread &quot;main&quot; java.lang.NullPointerException
	at com.lckymn.kevin.test.fluentinterface.FluentListStorage.add(FluentListStorage.java:21)
	at com.lckymn.kevin.test.fluentinterface.MethodChainingTest.main(MethodChainingTest.java:14)
</pre>
<p>The fourteenth line is this.</p>
<pre class="brush: java; first-line: 14;">
				.add(null)
</pre>
<p>So change it to</p>
<pre class="brush: java; first-line: 14;">
				.add(&quot;C&quot;)
</pre>
<p>I could finally have the correct result.</p>
<pre class="brush: plain; gutter: false;">
ID: 65
Name: A

ID: 66
Name: B

ID: 67
Name: C

ID: 68
Name: D

There are 4 items in the storage.
</pre>
<p>So method chaining, to use, or not to use? It&#8217;s all up to you. <img src='http://blog.lckymn.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p><strong>References</strong><br />
Bauer, C. and King, G. 2007, <i>Java Persistence with Hibernate</i>, Manning Publications Co., New York.</p>
<p>Cho, Y. 2008, <i>Applicaiton of Domain-Driven Design 2. Aggregate and Repository #3</i>, viewed 29 June 2009, &lt;<a href="http://aeternum.egloos.com/1173825" target="_blank">http://aeternum.egloos.com/1173825</a>&gt;.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lckymn.com/2009/06/30/method-chaining-to-use-or-not-to-use/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Installing 64bit Flash Player in Ubuntu Linux</title>
		<link>http://blog.lckymn.com/2009/06/07/installing-64bit-flash-player-in-ubuntu-linux/</link>
		<comments>http://blog.lckymn.com/2009/06/07/installing-64bit-flash-player-in-ubuntu-linux/#comments</comments>
		<pubDate>Sat, 06 Jun 2009 14:05:07 +0000</pubDate>
		<dc:creator>Kevin</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[Ubuntu Linux]]></category>
		<category><![CDATA[64bit Flash Player]]></category>
		<category><![CDATA[Crash]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[Flash Player]]></category>
		<category><![CDATA[Flash Player Plug-in]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Opera]]></category>
		<category><![CDATA[Ubuntu Linux 64bit]]></category>
		<category><![CDATA[Web Browser]]></category>

		<guid isPermaLink="false">http://blog.lckymn.com/?p=341</guid>
		<description><![CDATA[<p>I think there are numerous 64 bit Ubuntu users who are suffering from the crash of Flash Player just like myself.  There is a better way to install Flash Player for 64 bit Linux than installing one from the Ubuntu repository and that is what I am about to write.  This is obviously not the perfect solution yet I think the best way to use 64bit Flash Player for now.  I hope Adobe will release a stable 64 bit Flash <p style="border: 3px solid rgb(243, 197, 52); padding: 5px; background-color: rgb(254, 254, 184); width: 600px; text-align: center;">[...Continue reading <a href="http://blog.lckymn.com/2009/06/07/installing-64bit-flash-player-in-ubuntu-linux/">Installing 64bit Flash Player in Ubuntu Linux</a>...]</p>]]></description>
			<content:encoded><![CDATA[<p>I think there are numerous 64 bit Ubuntu users who are suffering from the crash of Flash Player just like myself.  There is a better way to install Flash Player for 64 bit Linux than installing one from the Ubuntu repository and that is what I am about to write.  This is obviously not the perfect solution yet I think the best way to use 64bit Flash Player for now.  I hope Adobe will release a stable 64 bit Flash Player for Linux soon.  Anyway, here we go!</p>
<p>Adobe has released an alpha version of Flash Player for 64bit Linux.<br />
<a href="http://labs.adobe.com/downloads/flashplayer10.html" target="_blank" style="text-decoration: line-through;">http://labs.adobe.com/downloads/flashplayer10.html</a><br />
<a href="http://labs.adobe.com/downloads/flashplayer10_64bit.html" target="_blank">http://labs.adobe.com/downloads/flashplayer10_64bit.html</a><br />
At the bottom of the web page, you can find the download link.</p>
<pre>Download 64-bit Plugin for Linux (TAR.GZ, 3.56 MB)
</pre>
<p>In my case, the latest alpha version of 64 bit Flash player does not work well (e.g. Video on youtube constantly freezes) yet the previous alpha one works better. So first, try the latest one and if it doesn&#8217;t work well, download the following one.</p>
<p><a href="http://download.macromedia.com/pub/labs/flashplayer10/libflashplayer-10.0.d21.1.linux-x86_64.so.tar.gz" target="_blank">http://download.macromedia.com/pub/labs/flashplayer10/libflashplayer-10.0.d21.1.linux-x86_64.so.tar.gz</a></p>
<div class="txc-textbox" style="border: 3px solid rgb(243, 197, 52); padding: 10px; background-color: rgb(254, 254, 184);">
*** This part is added on the 28th of September, 2009 ***<br />
I installed the latest alpha version which is <code>libflashplayer-10.0.32.18.linux-x86_64.so.tar.gz</code> today (the 28th of September, 2009). So far, it seems fine.
</div>
<p>Before installing it, if there is a previously installed Flash player, it has to be removed first.</p>
<p>To check it, open &#8216;Synaptic Package Manager&#8217;.<br />
System -&gt; Administration -&gt; Synaptic Package Manager<br />
<div id="attachment_342" class="wp-caption alignnone" style="width: 918px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/06/flashplayer.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/06/flashplayer.jpg" alt="Search by &#039;flash&#039; and make sure neither &lt;code&gt;flashplugin-nonfree&lt;/code&gt; nor &lt;code&gt;flashplugin-installer&lt;/code&gt; is installed. If any of these are installed, remove first." title="Flash Player should be removed." width="908" height="746" class="size-full wp-image-342" /></a><p class="wp-caption-text">Search by 'flash' and make sure neither <code>flashplugin-nonfree</code> nor <code>flashplugin-installer</code> is installed. If any of these are installed, remove first.</p></div><br />
-Search by &#8216;flash&#8217; and make sure neither <code>flashplugin-nonfree</code> nor <code>flashplugin-installer</code> is installed. If any of these are installed, remove first.</p>
<p>Extract the libflashplayer file downloaded to the firefox &#8216;plugins&#8217; directory.<br />
(libflashplayer-10.0.d21.1.linux-x86_64.so.tar.gz file is in the <code>/home/username/Desktop</code> directory).</p>
<pre class="brush: bash; gutter: false;">
$ cd /usr/lib/firefox/plugins
$ sudo tar -zxvf ~/Desktop/libflashplayer-10.0.d21.1.linux-x86_64.so.tar.gz
</pre>
<p>To use this Flash player in other browsers such as Opera, create the symbolic link to the <code>/usr/lib/firefox/plugins/libflashplayer.so</code> file in the &#8216;/usr/lib/mozilla/plugins&#8217; directory.</p>
<pre class="brush: bash; gutter: false;">
$ cd /usr/lib/mozilla/plugins
$ sudo ln -s /usr/lib/firefox/plugins/libflashplayer.so
</pre>
<p>If the file with the same name already exists, user &#8216;f&#8217; option to overwrite it.</p>
<pre class="brush: bash; gutter: false;">
$ sudo ln -sf /usr/lib/firefox/plugins/libflashplayer.so
</pre>
<p>Now, open the Firefox and test if it works well. <img src='http://blog.lckymn.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<div class="txc-textbox" style="border: 3px solid rgb(243, 197, 52); padding: 10px; background-color: rgb(254, 254, 184);">
*** This part is added on the 28th of September, 2009 ***<br />
I also tried what the following blog entry says about several weeks ago.<br />
<a href="http://blogs.adobe.com/penguin.swf/2008/08/secrets_of_the_mmscfg_file_1.html">Secrets Of The mms.cfg File</a></p>
<p>I created the directory <code>/etc/adobe</code> and created a file named <code>mms.cfg</code> in the directory (so the absolute path of the file is <code>/etc/adobe/mms.cfg</code>).</p>
<p>Then I put the following line in the file.<br />
<code>OverrideGPUValidation=true</code></p>
<p>It seems to work for mine. When I watch a video clip on youtube, it plays smoother than before.
</p></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.lckymn.com/2009/06/07/installing-64bit-flash-player-in-ubuntu-linux/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Enabling Visual Effects in Ubuntu</title>
		<link>http://blog.lckymn.com/2009/06/04/enabling-visual-effects-in-ubunt/</link>
		<comments>http://blog.lckymn.com/2009/06/04/enabling-visual-effects-in-ubunt/#comments</comments>
		<pubDate>Thu, 04 Jun 2009 11:54:39 +0000</pubDate>
		<dc:creator>Kevin</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[Ubuntu Linux]]></category>
		<category><![CDATA[ATI]]></category>
		<category><![CDATA[Compiz]]></category>
		<category><![CDATA[Compiz-Fusion]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[nVidia]]></category>
		<category><![CDATA[Visual Effects]]></category>

		<guid isPermaLink="false">http://blog.lckymn.com/?p=330</guid>
		<description><![CDATA[<p>Somebody asked a question regarding my video on youtube.
<a href="http://www.youtube.com/watch?v=TOp83ByFrMA" target="_blank">http://www.youtube.com/watch?v=TOp83ByFrMA</a></p>
<p>Unfortunately I don&#8217;t really have time to explain the details nor am I sure if Ubuntu supports his/her graphics card so I&#8217;m putting here some information which can be a starting point to get what he/she wants.</p>
<p>To enable some basic visual effects, select the &#8216;Appearance&#8217; menu.
-System -&#62; Preferences -&#62; Appearance
<div id="attachment_331" class="wp-caption alignnone" style="width: 658px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/06/visualeffect01.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/06/visualeffect01.jpg" alt="System -&#62; Preferences -&#62; Appearance" title="Open &#039;Appearance&#039;" width="648" height="297" class="size-full wp-image-331" /></a><p class="wp-caption-text">System <p style="border: 3px solid rgb(243, 197, 52); padding: 5px; background-color: rgb(254, 254, 184); width: 600px; text-align: center;">[...Continue reading <a href="http://blog.lckymn.com/2009/06/04/enabling-visual-effects-in-ubunt/">Enabling Visual Effects in Ubuntu</a>...]</p>]]></description>
			<content:encoded><![CDATA[<p>Somebody asked a question regarding my video on youtube.<br />
<a href="http://www.youtube.com/watch?v=TOp83ByFrMA" target="_blank">http://www.youtube.com/watch?v=TOp83ByFrMA</a></p>
<p>Unfortunately I don&#8217;t really have time to explain the details nor am I sure if Ubuntu supports his/her graphics card so I&#8217;m putting here some information which can be a starting point to get what he/she wants.</p>
<p>To enable some basic visual effects, select the &#8216;Appearance&#8217; menu.<br />
-System -&gt; Preferences -&gt; Appearance<br />
<div id="attachment_331" class="wp-caption alignnone" style="width: 658px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/06/visualeffect01.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/06/visualeffect01.jpg" alt="System -&gt; Preferences -&gt; Appearance" title="Open &#039;Appearance&#039;" width="648" height="297" class="size-full wp-image-331" /></a><p class="wp-caption-text">System -> Preferences -> Appearance</p></div></p>
<p>-Select the &#8216;Visual Effects&#8217; tab -&gt; Select the &#8216;Extra&#8217; effect -&gt; Click the &#8216;Close&#8217; button.<br />
<div id="attachment_332" class="wp-caption alignnone" style="width: 627px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/06/visualeffect02.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/06/visualeffect02.jpg" alt="Select the &#039;Visual Effects&#039; tab -&gt; Select the &#039;Extra&#039; effect -&gt; Click the &#039;Close&#039; button." title="Select the &#039;Extra&#039; effect" width="617" height="534" class="size-full wp-image-332" /></a><p class="wp-caption-text">Select the 'Visual Effects' tab -> Select the 'Extra' effect -> Click the 'Close' button.</p></div><br />
If Ubuntu or Compiz doesn&#8217;t support your graphics card, you may get some error message here.<br />
If you are using ATI or nVidia Graphics card, I strongly recommend you to install EnvyNG which automatically checks what Graphics card you use and finds the proper driver for it. It only works for ATI and nVidia ones.  I am using Intel one so I cannot use it and therefore can&#8217;t explain how to use it.  To install it, open the &#8216;Synaptic Package Manager&#8217;<br />
System -&gt; Administration -&gt; Synaptic Package Manager<br />
and search by envyng then you can see &#8216;envyng-core&#8217;, &#8216;envyng-gtk&#8217; and &#8216;envyng-qt&#8217;. Install envyng-gtk (I assume you&#8217;re using Ubuntu but not Kubuntu) and it will install envyng-core and envyng-gtk.</p>
<p>OK, get back to the visual effect one. After selecting the &#8216;Extra&#8217; visual effect, it should have some visual effects and now it&#8217;s time to customise it to have more effects. If you have not installed &#8216;CompizConfig Setting Manager&#8217; yet, install it first.</p>
<p>-Run &#8216;Add/Remove Applications&#8217; -&gt; 1. Make sure it shows &#8216;All available applications&#8217; -&gt; 2. Search &#8216;compiz&#8217; -&gt; 3. Check &#8216;Advanced Desktop Effects Settings (ccsm) -&gt; 4. Click the &#8216;Apply Changes&#8217; button.<br />
<div id="attachment_333" class="wp-caption alignnone" style="width: 811px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/06/visualeffect03.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/06/visualeffect03.jpg" alt="Run &#039;Add/Remove Applications&#039; -&gt; 1. Make sure it shows &#039;All available applications&#039; -&gt; 2. Search &#039;compiz&#039; -&gt; 3. Check &#039;Advanced Desktop Effects Settings (ccsm) -&gt; 4. Click the &#039;Apply Changes&#039; button." title="Install &#039;CompizConfig Setting Manager&#039;" width="801" height="556" class="size-full wp-image-333" /></a><p class="wp-caption-text">Run 'Add/Remove Applications' -> 1. Make sure it shows 'All available applications' -> 2. Search 'compiz' -> 3. Check 'Advanced Desktop Effects Settings (ccsm) -> 4. Click the 'Apply Changes' button.</p></div></p>
<p>Run the &#8216;CompizConfig Setting Manager&#8217;<br />
-System -&gt; Preferences -&gt; CompizConfig Setting Manager<br />
<div id="attachment_334" class="wp-caption alignnone" style="width: 670px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/06/visualeffect04.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/06/visualeffect04.jpg" alt="System -&gt; Preferences -&gt; CompizConfig Setting Manager" title="Run the &#039;CompizConfig Setting Manager&#039;" width="660" height="290" class="size-full wp-image-334" /></a><p class="wp-caption-text">System -> Preferences -> CompizConfig Setting Manager</p></div></p>
<p>Now you can have whatever you want with Compiz-Fusion!<br />
e.g.) To have the Cube, enable the &#8216;Desktop Cube&#8217; and &#8216;Rotate Cube&#8217;<br />
<div id="attachment_335" class="wp-caption alignnone" style="width: 1012px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/06/visualeffect05.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/06/visualeffect05.jpg" alt="Do whatever you want!" title="Customise the visual effects" width="1002" height="619" class="size-full wp-image-335" /></a><p class="wp-caption-text">Do whatever you want!</p></div></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lckymn.com/2009/06/04/enabling-visual-effects-in-ubunt/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Spring ROO M1 Coming Soon</title>
		<link>http://blog.lckymn.com/2009/05/21/spring-roo-m1-coming-soon/</link>
		<comments>http://blog.lckymn.com/2009/05/21/spring-roo-m1-coming-soon/#comments</comments>
		<pubDate>Thu, 21 May 2009 13:02:32 +0000</pubDate>
		<dc:creator>Kevin</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Spring Framework]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[Spring ROO]]></category>
		<category><![CDATA[Spring ROO M1]]></category>
		<category><![CDATA[SpringSource]]></category>

		<guid isPermaLink="false">http://blog.lckymn.com/?p=319</guid>
		<description><![CDATA[<p>Today, I met and talked with a few people from SpringSource at a pub in North Sydney including Ben and Stefan (sorry Stefan. It&#8217;s just in alphabetical order <img src='http://blog.lckymn.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ) who are developing Spring ROO.</p>
<p>Anyone who are interested in Spring ROO had better keep an eye on this thread as they are going to release ROO M1 soon.
<a href="http://forum.springsource.org/showthread.php?t=71985" target="_blank">http://forum.springsource.org/showthread.php?t=71985</a></p>
<p>I heard that a lot of cool plug-ins for ROO will also be available and am <p style="border: 3px solid rgb(243, 197, 52); padding: 5px; background-color: rgb(254, 254, 184); width: 600px; text-align: center;">[...Continue reading <a href="http://blog.lckymn.com/2009/05/21/spring-roo-m1-coming-soon/">Spring ROO M1 Coming Soon</a>...]</p>]]></description>
			<content:encoded><![CDATA[<p>Today, I met and talked with a few people from SpringSource at a pub in North Sydney including Ben and Stefan (sorry Stefan. It&#8217;s just in alphabetical order <img src='http://blog.lckymn.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ) who are developing Spring ROO.</p>
<p>Anyone who are interested in Spring ROO had better keep an eye on this thread as they are going to release ROO M1 soon.<br />
<a href="http://forum.springsource.org/showthread.php?t=71985" target="_blank">http://forum.springsource.org/showthread.php?t=71985</a></p>
<p>I heard that a lot of cool plug-ins for ROO will also be available and am really looking forward to it.</p>
<div class="txc-textbox" style="border: 3px solid rgb(243, 197, 52); padding: 10px; background-color: rgb(254, 254, 184);">
Spring ROO M1 was released on the 27th of May 2009.
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.lckymn.com/2009/05/21/spring-roo-m1-coming-soon/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>ROO So Cool!!! -04-</title>
		<link>http://blog.lckymn.com/2009/05/17/roo-so-cool-04/</link>
		<comments>http://blog.lckymn.com/2009/05/17/roo-so-cool-04/#comments</comments>
		<pubDate>Sun, 17 May 2009 01:03:43 +0000</pubDate>
		<dc:creator>Kevin</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Spring Framework]]></category>
		<category><![CDATA[AJDT]]></category>
		<category><![CDATA[AspectJ]]></category>
		<category><![CDATA[AspectJ Development Tools]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Eclipse JEE]]></category>
		<category><![CDATA[Hibernate]]></category>
		<category><![CDATA[Inter-type declarations]]></category>
		<category><![CDATA[J2EE]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JavaBean]]></category>
		<category><![CDATA[JEE]]></category>
		<category><![CDATA[JPA]]></category>
		<category><![CDATA[M2Eclipse]]></category>
		<category><![CDATA[Maven]]></category>
		<category><![CDATA[Maven Integration for Eclipse]]></category>
		<category><![CDATA[Maven2]]></category>
		<category><![CDATA[Mixin]]></category>
		<category><![CDATA[Multiple Inheritance]]></category>
		<category><![CDATA[ORM]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[Spring ROO]]></category>
		<category><![CDATA[SpringSource Tool Suite]]></category>
		<category><![CDATA[STS]]></category>

		<guid isPermaLink="false">http://blog.lckymn.com/?p=283</guid>
		<description><![CDATA[<p>Continued from
<a href="http://blog.lckymn.com/2009/05/17/roo-so-cool-03/" target="_blank">http://blog.lckymn.com/2009/05/17/roo-so-cool-03/</a></p>
<p>There are two other aspects which are <code>Choice_Roo_Plural</code> and <code>Choice_Roo_ToString</code>.</p>
<div id="attachment_243" class="wp-caption alignnone" style="width: 913px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-22.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-22.jpg" alt="&#34;Choice&#34; in Plural Form, &#34;Choices&#34;" title="&#34;Choice&#34; in Plural Form, &#34;Choices&#34;" width="903" height="417" class="size-full wp-image-243" /></a><p class="wp-caption-text">&#34;Choice&#34; in Plural Form, &#34;Choices&#34;</p></div>
<code>Choice_Roo_Plural</code> declares that the <code>Choice</code> has a method named <code>getPluralName()</code> which returns a String type value, &#8220;Choices&#8221; which is the plural form of &#8220;Choice&#8221;. I don&#8217;t really get why it is necessary though.  I first thought it might be the <p style="border: 3px solid rgb(243, 197, 52); padding: 5px; background-color: rgb(254, 254, 184); width: 600px; text-align: center;">[...Continue reading <a href="http://blog.lckymn.com/2009/05/17/roo-so-cool-04/">ROO So Cool!!! -04-</a>...]</p>]]></description>
			<content:encoded><![CDATA[<p>Continued from<br />
<a href="http://blog.lckymn.com/2009/05/17/roo-so-cool-03/" target="_blank">http://blog.lckymn.com/2009/05/17/roo-so-cool-03/</a></p>
<p>There are two other aspects which are <code>Choice_Roo_Plural</code> and <code>Choice_Roo_ToString</code>.</p>
<div id="attachment_243" class="wp-caption alignnone" style="width: 913px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-22.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-22.jpg" alt="&quot;Choice&quot; in Plural Form, &quot;Choices&quot;" title="&quot;Choice&quot; in Plural Form, &quot;Choices&quot;" width="903" height="417" class="size-full wp-image-243" /></a><p class="wp-caption-text">&quot;Choice&quot; in Plural Form, &quot;Choices&quot;</p></div><br />
<code>Choice_Roo_Plural</code> declares that the <code>Choice</code> has a method named <code>getPluralName()</code> which returns a String type value, &#8220;Choices&#8221; which is the plural form of &#8220;Choice&#8221;. I don&#8217;t really get why it is necessary though.  I first thought it might be the name of the table with which the <code>Choice_Roo_Entity</code> matches, yet the table name is <code>choice</code>.</p>
<pre class="brush: plain; gutter: false;">
Bind entity com.springsource.vote.domain.Choice on table choice
</pre>
<p>It is probably for the future use as a name of domain object in plural form may be frequently required when displaying the list of it.</p>
<p>Now, let&#8217;s look at the last aspect.<br />
<div id="attachment_244" class="wp-caption alignnone" style="width: 919px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-23.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-23.jpg" alt="toString() method for Choice" title="toString() method for Choice" width="909" height="417" class="size-full wp-image-244" /></a><p class="wp-caption-text">toString() method for Choice</p></div><br />
The last one is <code>Choice_Roo_ToString</code> which declare that Choice has <code>toString()</code> method.</p>
<pre class="brush: java;">
privileged aspect Choice_Roo_ToString {

    public java.lang.String Choice.toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(&quot;id: &quot;).append(getId()).append(&quot;, &quot;);
        sb.append(&quot;version: &quot;).append(getVersion()).append(&quot;, &quot;);
        sb.append(&quot;namingChoice: &quot;).append(getNamingChoice()).append(&quot;, &quot;);
        sb.append(&quot;description: &quot;).append(getDescription()).append(&quot;, &quot;);
        return sb.toString();
    }    

}
</pre>
<p>It returns String containing the information about <code>Choice</code> which includes all the values of the variables from the aspects as well. This String is used to display the information about Choice object in the view, <code>WEB-INF/jsp/vote/create.jsp</code>.</p>
<p>All these mixins can be good Separation of Concerns (SoC).  Each aspect has what should be a concern in a particular mixin only. For example, id and version of Choice are not really a concern of <code>Choice</code> itself as it does not have any meaning for Choice, yet it is very important for OR mapping. Thus it is separated from <code>Choice</code> and only occurs in <code>Choice_Roo_Entity</code> which plays the role of a persistent object.</p>
<p>It is not a completely new ways to write mixin using inter-type declarations in AspectJ (<a href="http://today.java.net/pub/a/today/2005/12/15/writing-mixins-with-aop.html" target="_blank">http://today.java.net/pub/a/today/2005/12/15/writing-mixins-with-aop.html</a>). Nevertheless, Spring ROO is still so cool as I have never seen any automatically generated code by Java frameworks uses mixins written using inter-type declarations as a nice way of SoC. I may need to call ROO RSoC (Real Separation of Concerns). <img src='http://blog.lckymn.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>OK, I am now running out of time so had better finish this post quickly.  </p>
<p>I would just finally like to point out some minor issues I found.</p>
<p>1. An error in dojo JS toolkit.<br />
<div id="attachment_165" class="wp-caption alignnone" style="width: 851px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-15.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-15.jpg" alt="dojo JS Toolkit Error" title="dojo JS Toolkit Error" width="841" height="588" class="size-full wp-image-165" /></a><p class="wp-caption-text">dojo JS Toolkit Error</p></div>
<p>2. An error in roo.css file.<br />
<div id="attachment_245" class="wp-caption alignnone" style="width: 946px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-24.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-24.jpg" alt="CSS Error" title="CSS Error" width="936" height="408" class="size-full wp-image-245" /></a><p class="wp-caption-text">CSS Error</p></div></p>
<pre class="brush: css; first-line: 38; highlight: [41];">
#wrap {
	margin:0 auto;
  	position:relative;
  	float:center;
  	top: 0px;
  	left:0px;
  	width:800px;
  	text-align:left;  	

}
</pre>
<p><code>center</code> is not a float value.</p>
<p>3. Using a String&#8217;s equals() method to test for an empty String. This might be OK for a small application like the ROO example but it can bring about some performance issue for a big application with numerous simultaneous user requests.<br />
<div id="attachment_246" class="wp-caption alignnone" style="width: 913px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-25.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-25.jpg" alt="Performance Issue - Test for Empty String" title="Performance Issue - Test for Empty String" width="903" height="405" class="size-full wp-image-246" /></a><p class="wp-caption-text">Performance Issue - Test for Empty String</p></div><br />
So the following code from <code>ChoiceEditor_Roo_Editor</code></p>
<pre class="brush: java;">
if (text == null || &quot;&quot;.equals(text))
</pre>
<p>had better be</p>
<pre class="brush: java;">
if (text == null || 0 == text.length())
</pre>
<p>I wrote more details about it here with performance tests.<br />
<a href="http://blog.lckymn.com/2009/05/17/test-for-empty-string/" target="_blank" style="color: blue; font-weight: bolder;">http://blog.lckymn.com/2009/05/17/test-for-empty-string/</a></p>
<p>Finally, it&#8217;s my wish. I found that aspect code is not really supported by the Eclipse functions for Java such as <code>Call Hierarchy</code> and <code>Open Declaration</code>. It would be much better if aspects are fully supported by the Eclipse functions for Java. However, it may have something to do with AJDT not Spring ROO integration.</p>
<p>Phew, I have eventually written this. <img src='http://blog.lckymn.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' />  Even though I tried ROO approximately two weeks ago, I did not have time to write about it.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lckymn.com/2009/05/17/roo-so-cool-04/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>ROO So Cool!!! -03-</title>
		<link>http://blog.lckymn.com/2009/05/17/roo-so-cool-03/</link>
		<comments>http://blog.lckymn.com/2009/05/17/roo-so-cool-03/#comments</comments>
		<pubDate>Sun, 17 May 2009 01:02:34 +0000</pubDate>
		<dc:creator>Kevin</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Spring Framework]]></category>
		<category><![CDATA[AJDT]]></category>
		<category><![CDATA[AspectJ]]></category>
		<category><![CDATA[AspectJ Development Tools]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Eclipse JEE]]></category>
		<category><![CDATA[Hibernate]]></category>
		<category><![CDATA[Inter-type declarations]]></category>
		<category><![CDATA[J2EE]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JavaBean]]></category>
		<category><![CDATA[JEE]]></category>
		<category><![CDATA[JPA]]></category>
		<category><![CDATA[M2Eclipse]]></category>
		<category><![CDATA[Maven]]></category>
		<category><![CDATA[Maven Integration for Eclipse]]></category>
		<category><![CDATA[Maven2]]></category>
		<category><![CDATA[Mixin]]></category>
		<category><![CDATA[Multiple Inheritance]]></category>
		<category><![CDATA[ORM]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[Spring ROO]]></category>
		<category><![CDATA[SpringSource Tool Suite]]></category>
		<category><![CDATA[STS]]></category>

		<guid isPermaLink="false">http://blog.lckymn.com/?p=275</guid>
		<description><![CDATA[<p>Continued from
<a href="http://blog.lckymn.com/2009/05/17/roo-so-cool-02/" target="_blank">http://blog.lckymn.com/2009/05/17/roo-so-cool-02/</a></p>
<p>Now, let&#8217;s look at more interesting one that is the ROO generated source code!</p>
<p>As you can see, there are many AspectJ aspects in the <code>com.springsource.vote.domain</code> package. So I&#8217;ll firstly try to look at the <code>Choice</code> class which is not an aspect.</p>
<p><div id="attachment_239" class="wp-caption alignnone" style="width: 989px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-18.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-18.jpg" alt="Domain object - Choice" title="Domain object - Choice" width="979" height="744" class="size-full wp-image-239" /></a><p class="wp-caption-text">Domain object - Choice</p></div>
Wow! Is that it? Without the annotations, it consists of only two lines <p style="border: 3px solid rgb(243, 197, 52); padding: 5px; background-color: rgb(254, 254, 184); width: 600px; text-align: center;">[...Continue reading <a href="http://blog.lckymn.com/2009/05/17/roo-so-cool-03/">ROO So Cool!!! -03-</a>...]</p>]]></description>
			<content:encoded><![CDATA[<p>Continued from<br />
<a href="http://blog.lckymn.com/2009/05/17/roo-so-cool-02/" target="_blank">http://blog.lckymn.com/2009/05/17/roo-so-cool-02/</a></p>
<p>Now, let&#8217;s look at more interesting one that is the ROO generated source code!</p>
<p>As you can see, there are many AspectJ aspects in the <code>com.springsource.vote.domain</code> package. So I&#8217;ll firstly try to look at the <code>Choice</code> class which is not an aspect.</p>
<p><div id="attachment_239" class="wp-caption alignnone" style="width: 989px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-18.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-18.jpg" alt="Domain object - Choice" title="Domain object - Choice" width="979" height="744" class="size-full wp-image-239" /></a><p class="wp-caption-text">Domain object - Choice</p></div><br />
Wow! Is that it? Without the annotations, it consists of only two lines of code in the class.  Just two variable declarations.</p>
<p>So where are the others?</p>
<p>Check out the <code>Choice_Roo_Entity</code> aspect.<br />
<div id="attachment_240" class="wp-caption alignnone" style="width: 919px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-19.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-19.jpg" alt="Persistent Object (Aspect)" title="Persistent Object (Aspect)" width="909" height="424" class="size-full wp-image-240" /></a><p class="wp-caption-text">Persistent Object (Aspect)</p></div><br />
It appears to be a persistent object class with a persistence manager which means it includes data access logic. This sounds like normal <a href="http://www.martinfowler.com/eaaCatalog/activeRecord.html" target="_blank">Active Record</a> yet if you closer look at the code, it uses AspectJ&#8217;s inter-type declaration to add more attributes and behaviours to the domain object <code>Choice</code>.</p>
<pre class="brush: java;">
    @javax.persistence.Id
    @javax.persistence.GeneratedValue(strategy = javax.persistence.GenerationType.AUTO)
    @javax.persistence.Column(name = &quot;id&quot;)
    private java.lang.Long Choice.id;
</pre>
<p>This code above is declaring long type id variable to the type Choice to use as an identifier for OR mapping.  Because it is declared as a private variable, it is impossible to access it inside the code of Choice but possible only inside this <code>Choice_Roo_Entity</code> aspect.</p>
<p>What about the <code>Choice_Roo_JavaBean</code>.<br />
<div id="attachment_241" class="wp-caption alignnone" style="width: 922px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-20.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-20.jpg" alt="JavaBean (Aspect)" title="JavaBean (Aspect)" width="912" height="424" class="size-full wp-image-241" /></a><p class="wp-caption-text">JavaBean (Aspect)</p></div><br />
It has all the getters and setters for the <code>Choice</code> class and again inter-type declaration is used for adding these accessor methods.  So an instance of Choice type cannot only behave as a persistent object but also as a JavaBean object.  If you look into the jsp file, you can see it is used just like the methods belong to <code>Choice</code> class.<br />
In order to access the variables inside <code>Choice</code> object, the <code>Choice_Roo_JavaBean</code> is defined as <code>privileged</code> aspect.</p>
<pre class="brush: java; highlight: [1,4,8,12,16];">
privileged aspect Choice_Roo_JavaBean {

    public java.lang.String Choice.getNamingChoice() {
        return this.namingChoice;
    }    

    public void Choice.setNamingChoice(java.lang.String namingChoice) {
        this.namingChoice = namingChoice;
    }    

    public java.lang.String Choice.getDescription() {
        return this.description;
    }    

    public void Choice.setDescription(java.lang.String description) {
        this.description = description;
    }    

}
</pre>
<p>So as shown above, <code>Choice_Roo_JavaBean</code> is a privileged aspect and therefore it can access <code>namingChoice</code> and <code>description</code> variables which are declared in <code>Choice</code>.</p>
<p>So what is it? It is a mixin.  <a href="http://en.wikipedia.org/wiki/Mixin" target="_blank">Mixin</a> is a class which provides a functionality to a subclass yet mixin itself is not supposed to stand alone.  So a class can collect its functionality by inheriting from one or more mixins through multiple inheritance.  However, as we all know, Java does not support multiple inheritance. So to use mixins in Java world, inter-type declarations in AspectJ can be used.</p>
<pre class="brush: java; highlight: [8,13];">
privileged aspect Choice_Roo_Entity {

	(...)

    @javax.persistence.Id
    @javax.persistence.GeneratedValue(strategy = javax.persistence.GenerationType.AUTO)
    @javax.persistence.Column(name = &quot;id&quot;)
    private java.lang.Long Choice.id;    

    (...)

    public java.lang.Long Choice.getId() {
        return this.id;
    }
}
</pre>
<p>As seen in the aspect code above, a long type variable is added to the type Choice and a getId() method which returns a long type value that is the value in the variable, id, just added by the aspect. So an instance of Choice type can have getId() method even though it does not exist in the Choice class. Therefore, as mentioned, Choice type can have characteristics of both persistent object and JavaBean.  </p>
<p>AspectJ is also used to declare Choice type as a configurable type.<br />
<div id="attachment_242" class="wp-caption alignnone" style="width: 802px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-21.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-21.jpg" alt="Make Choice @Configurable" title="Make Choice @Configurable" width="792" height="172" class="size-full wp-image-242" /></a><p class="wp-caption-text">Make Choice @Configurable</p></div><br />
This code reveals that <code>Choice</code> type has <code>@org.springframework.beans.factory.annotation.Configurable</code> annotation.</p>
<pre class="brush: java;">
privileged aspect Choice_Roo_Configurable {

    declare @type: Choice: @org.springframework.beans.factory.annotation.Configurable;    

}
</pre>
<p>Next:<br />
<a href="http://blog.lckymn.com/2009/05/17/roo-so-cool-04/" target="_blank">http://blog.lckymn.com/2009/05/17/roo-so-cool-04/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lckymn.com/2009/05/17/roo-so-cool-03/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>ROO So Cool!!! -02-</title>
		<link>http://blog.lckymn.com/2009/05/17/roo-so-cool-02/</link>
		<comments>http://blog.lckymn.com/2009/05/17/roo-so-cool-02/#comments</comments>
		<pubDate>Sun, 17 May 2009 01:01:45 +0000</pubDate>
		<dc:creator>Kevin</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Spring Framework]]></category>
		<category><![CDATA[AJDT]]></category>
		<category><![CDATA[AspectJ]]></category>
		<category><![CDATA[AspectJ Development Tools]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Eclipse JEE]]></category>
		<category><![CDATA[Hibernate]]></category>
		<category><![CDATA[Inter-type declarations]]></category>
		<category><![CDATA[J2EE]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JavaBean]]></category>
		<category><![CDATA[JEE]]></category>
		<category><![CDATA[JPA]]></category>
		<category><![CDATA[M2Eclipse]]></category>
		<category><![CDATA[Maven]]></category>
		<category><![CDATA[Maven Integration for Eclipse]]></category>
		<category><![CDATA[Maven2]]></category>
		<category><![CDATA[Mixin]]></category>
		<category><![CDATA[Multiple Inheritance]]></category>
		<category><![CDATA[ORM]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[Spring ROO]]></category>
		<category><![CDATA[SpringSource Tool Suite]]></category>
		<category><![CDATA[STS]]></category>

		<guid isPermaLink="false">http://blog.lckymn.com/?p=273</guid>
		<description><![CDATA[<p>Continued from
<a href="http://blog.lckymn.com/2009/05/17/roo-so-cool-01/" target="_blank">http://blog.lckymn.com/2009/05/17/roo-so-cool-01/</a></p>
<p>Let&#8217;s run this project to see what it looks like.</p>
<p><div id="attachment_159" class="wp-caption alignnone" style="width: 833px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-09.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-09.jpg" alt="Run ROO Generated Application on Server" title="Run ROO Generated Application on Server" width="823" height="570" class="size-full wp-image-159" /></a><p class="wp-caption-text">Run ROO Generated Application on Server</p></div>
Right click on the project -> Select the <code>Run As</code> option on the menu -> Select the <code>Run on Server</code>.</p>
<p><div id="attachment_160" class="wp-caption alignnone" style="width: 626px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-10.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-10.jpg" alt="Choose Server" title="Choose Server" width="616" height="709" class="size-full wp-image-160" /></a><p class="wp-caption-text">Choose Server</p></div>
Select <p style="border: 3px solid rgb(243, 197, 52); padding: 5px; background-color: rgb(254, 254, 184); width: 600px; text-align: center;">[...Continue reading <a href="http://blog.lckymn.com/2009/05/17/roo-so-cool-02/">ROO So Cool!!! -02-</a>...]</p>]]></description>
			<content:encoded><![CDATA[<p>Continued from<br />
<a href="http://blog.lckymn.com/2009/05/17/roo-so-cool-01/" target="_blank">http://blog.lckymn.com/2009/05/17/roo-so-cool-01/</a></p>
<p>Let&#8217;s run this project to see what it looks like.</p>
<p><div id="attachment_159" class="wp-caption alignnone" style="width: 833px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-09.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-09.jpg" alt="Run ROO Generated Application on Server" title="Run ROO Generated Application on Server" width="823" height="570" class="size-full wp-image-159" /></a><p class="wp-caption-text">Run ROO Generated Application on Server</p></div><br />
Right click on the project -> Select the <code>Run As</code> option on the menu -> Select the <code>Run on Server</code>.</p>
<p><div id="attachment_160" class="wp-caption alignnone" style="width: 626px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-10.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-10.jpg" alt="Choose Server" title="Choose Server" width="616" height="709" class="size-full wp-image-160" /></a><p class="wp-caption-text">Choose Server</p></div><br />
Select <code>Choose an existing server</code> -> Select any <code>Servlet Container</code> or <code>JEE Server</code> on which you would like ROO generated application to run (If you do not have any available ones, install set it up first). -> Click the <code>Next</code> button.</p>
<p><div id="attachment_161" class="wp-caption alignnone" style="width: 628px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-11.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-11.jpg" alt="Click Finish to Run" title="Click Finish to Run" width="618" height="705" class="size-full wp-image-161" /></a><p class="wp-caption-text">Click Finish to Run</p></div><br />
Make sure <code>vote</code> project appears on the right-hand side and Click the <code>Finish</code> button.</p>
<p><div id="attachment_162" class="wp-caption alignnone" style="width: 913px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-12.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-12.jpg" alt="ROO Generated Application is Running." title="ROO Generated Application is Running." width="903" height="695" class="size-full wp-image-162" /></a><p class="wp-caption-text">ROO Generated Application is Running.</p></div><br />
Now it&#8217;s running.</p>
<p>I opened Firefox 3 to test it instead of using the built-in browser of Eclipse.<br />
Let&#8217;s create a new choice.</p>
<p><div id="attachment_163" class="wp-caption alignnone" style="width: 849px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-13.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-13.jpg" alt="Create New Choice (Firefox3)" title="Create New Choice (Firefox3)" width="839" height="688" class="size-full wp-image-163" /></a><p class="wp-caption-text">Create New Choice (Firefox3)</p></div><br />
Click the <code>Create New Choice</code> menu.</p>
<p><div id="attachment_164" class="wp-caption alignnone" style="width: 849px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-14.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-14.jpg" alt="Create New Choice Form" title="Create New Choice Form" width="839" height="586" class="size-full wp-image-164" /></a><p class="wp-caption-text">Create New Choice Form</p></div><br />
It displays the <code>Create New Choice</code> form.</p>
<p>Wait a minute! Is that a JavaScript (JS) error that <a href="http://getfirebug.com/" target="_blank">Firebug</a> complains?<br />
<div id="attachment_165" class="wp-caption alignnone" style="width: 851px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-15.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-15.jpg" alt="dojo JS Toolkit Error" title="dojo JS Toolkit Error" width="841" height="588" class="size-full wp-image-165" /></a><p class="wp-caption-text">dojo JS Toolkit Error</p></div><br />
Yes, it is but it looks like an error in <a href="http://dojotoolkit.org/" target="_blank">dojo</a> JS toolkit which Spring JS uses. Anyway, despite the error, it works fine.</p>
<p><div id="attachment_166" class="wp-caption alignnone" style="width: 849px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-16.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-16.jpg" alt="Fill in the Form -&gt; Save" title="Fill in the Form -&gt; Save" width="839" height="582" class="size-full wp-image-166" /></a><p class="wp-caption-text">Fill in the Form -> Save</p></div><br />
Quickly fill in the form. -> Click the <code>Save</code> button.</p>
<p><div id="attachment_167" class="wp-caption alignnone" style="width: 850px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-17.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-17.jpg" alt="New Choice Created" title="New Choice Created" width="840" height="588" class="size-full wp-image-167" /></a><p class="wp-caption-text">New Choice Created</p></div><br />
The entered data are added and a new Choice is created.</p>
<p>Next:<br />
<a href="http://blog.lckymn.com/2009/05/17/roo-so-cool-03/" target="_blank">http://blog.lckymn.com/2009/05/17/roo-so-cool-03/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lckymn.com/2009/05/17/roo-so-cool-02/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>ROO So Cool!!! -01-</title>
		<link>http://blog.lckymn.com/2009/05/17/roo-so-cool-01/</link>
		<comments>http://blog.lckymn.com/2009/05/17/roo-so-cool-01/#comments</comments>
		<pubDate>Sun, 17 May 2009 01:00:26 +0000</pubDate>
		<dc:creator>Kevin</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Spring Framework]]></category>
		<category><![CDATA[AJDT]]></category>
		<category><![CDATA[AspectJ]]></category>
		<category><![CDATA[AspectJ Development Tools]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Eclipse JEE]]></category>
		<category><![CDATA[Hibernate]]></category>
		<category><![CDATA[Inter-type declarations]]></category>
		<category><![CDATA[J2EE]]></category>
		<category><![CDATA[JavaBean]]></category>
		<category><![CDATA[JEE]]></category>
		<category><![CDATA[JPA]]></category>
		<category><![CDATA[M2Eclipse]]></category>
		<category><![CDATA[Maven]]></category>
		<category><![CDATA[Maven Integration for Eclipse]]></category>
		<category><![CDATA[Maven2]]></category>
		<category><![CDATA[Mixin]]></category>
		<category><![CDATA[Multiple Inheritance]]></category>
		<category><![CDATA[ORM]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[Spring ROO]]></category>
		<category><![CDATA[SpringSource Tool Suite]]></category>
		<category><![CDATA[STS]]></category>

		<guid isPermaLink="false">http://blog.lckymn.com/?p=146</guid>
		<description><![CDATA[<p>The end of the last month Spring Source released Spring ROO in alpha stage.  My friend, <a href="http://stsmedia.net/" target="_blank">Dr. Stefan Schmidt</a>, who in fact used to teach me J2EE technology at UTS when I was a UTS student, has been working for Spring Source and is now involved in ROO development. Although ROO sounds really like Australian, it signifies Real Object-Oriented (ROO).  After the release of the alpha version, Dr. Schmidt posted <a href="http://stsmedia.net/introducing-spring-roo/" target="_blank">an introductory tutorial of <p style="border: 3px solid rgb(243, 197, 52); padding: 5px; background-color: rgb(254, 254, 184); width: 600px; text-align: center;">[...Continue reading <a href="http://blog.lckymn.com/2009/05/17/roo-so-cool-01/">ROO So Cool!!! -01-</a>...]</p>]]></description>
			<content:encoded><![CDATA[<p>The end of the last month Spring Source released Spring ROO in alpha stage.  My friend, <a href="http://stsmedia.net/" target="_blank">Dr. Stefan Schmidt</a>, who in fact used to teach me J2EE technology at UTS when I was a UTS student, has been working for Spring Source and is now involved in ROO development. Although ROO sounds really like Australian, it signifies Real Object-Oriented (ROO).  After the release of the alpha version, Dr. Schmidt posted <a href="http://stsmedia.net/introducing-spring-roo/" target="_blank">an introductory tutorial of ROO</a> on his blog.  He explained well so I could easily try this new mind-blowing technology. <img src='http://blog.lckymn.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Let&#8217;s start a journey!</p>
<p>-Check your maven and JVM versions.</p>
<pre class="brush: bash; gutter: false;">
$ mvn --version
Maven version: 2.0.9
Java version: 1.6.0_13
OS name: &quot;linux&quot; version: &quot;2.6.28-11-generic&quot; arch: &quot;amd64&quot; Family: &quot;unix&quot;
</pre>
<p>- I&#8217;m using Ubuntu Linux 9.04 Jaunty Jackalope desktop edition 64bit and installed Sun JDK &amp; Maven2 from its repository.</p>
<p>-Extract <code>spring-roo-1.0.0.A2.zip</code> file to <code>/somepath/roo-1.0.0.A2</code><br />
-Add the environment variable ROO_HOME with the path of Roo home in the <code>.bashrc</code> file.<br />
-Add $ROO_HOME/bin to PATH in the <code>.bashrc</code> file.<br />
e.g.)</p>
<pre class="brush: bash; gutter: false;">
export ROO_HOME=/opt/lib/spring/roo-1.0.0.A2
PATH=${PATH}:$ROO_HOME/bin

export PATH
</pre>
<p>For Eclipse,<br />
-Extract <code>sts-roo-integration-1.0.0.A2.zip</code> file to the <code>eclipse/dropins</code> folder to use Spring ROO integration.<br />
This copying to the dropins directory only works for Eclipse Ganymede.</p>
<p>-Install ROO packages in the maven repository.</p>
<pre class="brush: bash; gutter: false;">
mvn install:install-file -DgroupId=org.springframework.roo \
  -DartifactId=roo-annotations -Dversion=1.0.0.A2 -Dpackaging=jar \
  -Dfile=$ROO_HOME/dist/roo-annotations-1.0.0.A2.jar
</pre>
<p>-Result</p>
<pre class="brush: bash; gutter: false;">
$ mvn install:install-file -DgroupId=org.springframework.roo \
       -DartifactId=roo-annotations -Dversion=1.0.0.A2 -Dpackaging=jar \
       -Dfile=$ROO_HOME/dist/roo-annotations-1.0.0.A2.jar
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'install'.
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Default Project
[INFO]    task-segment: [install:install-file] (aggregator-style)
[INFO] ------------------------------------------------------------------------
[INFO] [install:install-file]
[INFO] Installing /opt/lib/spring/roo-1.0.0.A2/dist/roo-annotations-1.0.0.A2.jar to /home/blade2/.m2/repository/org/springframework/roo/roo-annotations/1.0.0.A2/roo-annotations-1.0.0.A2.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2 seconds
[INFO] Finished at: Tue May 05 22:09:23 EST 2009
[INFO] Final Memory: 7M/165M
[INFO] ------------------------------------------------------------------------
</pre>
<p>-Now starts ROO console!</p>
<pre class="brush: bash; gutter: false;">
$ mkdir roo_test
$ cd roo_test/
$ roo.sh
</pre>
<div id="attachment_149" class="wp-caption alignnone" style="width: 801px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-00.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-00.jpg" alt="ROO Console" title="ROO Console" width="791" height="583" class="size-full wp-image-149" /></a><p class="wp-caption-text">ROO Console</p></div>
<p>-Create a project directory for a ROO project.</p>
<pre>
roo&gt; script vote.roo
(... wait until ROO console does it's job...)
roo&gt; exit
</pre>
<p>Instead of following the script that Dr. Schmidt provided, I just used <code>vote.roo</code> which can be found in the <code>samples</code> directory. Well no special reasons, it just looks simpler. That&#8217;s it. <img src='http://blog.lckymn.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />   If you are seeking more interesting one, you&#8217;d better try the one on the blog of Dr. Schmidt and then try your own one. ^O^</p>
<p>-In order to import the ROO project, just created, to Eclipse (STS), run maven2&#8217;s eclipse plug-in.</p>
<pre class="brush: bash; gutter: false;">
$ mvn eclipse:eclipse
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'eclipse'.
[INFO] ------------------------------------------------------------------------
[INFO] Building vote
[INFO]    task-segment: [eclipse:eclipse]
[INFO] ------------------------------------------------------------------------
[INFO] Preparing eclipse:eclipse
Downloading:
... lots of dependencies including spring framework 3.0.0.M2 ...

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 7 minutes 26 seconds
[INFO] Finished at: Tue May 05 22:32:18 EST 2009
[INFO] Final Memory: 31M/353M
[INFO] ------------------------------------------------------------------------
</pre>
<p>Well, although it says</p>
<blockquote><p>
Sources for some artifacts are not available.<br />
Javadoc for some artifacts is not available.
</p></blockquote>
<p>it is not that important unless I really want to see the missing source code and Javadoc of the artifacts listed with the message.</p>
<p>If you want to get it, add <code>-DdownloadSources=true  -DdownloadJavadocs=true</code> options and run maven again.</p>
<pre class="brush: bash; gutter: false;">
$ mvn eclipse:eclipse -DdownloadSources=true  -DdownloadJavadocs=true
</pre>
<p><del datetime="2009-05-17T17:36:05+00:00">I&#8217;m not sure if the source is available though.</del> <del datetime="2009-05-21T13:38:58+00:00">The source code is not available at the moment though.</del> I was wrong. The source code is available. Check this out. <a href="http://forum.springsource.org/showthread.php?t=71985" target="_blank">http://forum.springsource.org/showthread.php?t=71985</a></p>
<p>-Now run Eclipse. Since ROO is a part of Spring Framework, I&#8217;m using SpringSource Tool Suite (STS) for this practice.</p>
<div id="attachment_150" class="wp-caption alignnone" style="width: 511px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-01.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-01.jpg" alt="SpringSource Tool Suite" title="SpringSource Tool Suite" width="501" height="341" class="size-full wp-image-150" /></a><p class="wp-caption-text">SpringSource Tool Suite</p></div>
<p>Well, before I go further, here are what I am using.<br />
*SpringSource Tool Suite (STS) 2.0.0</p>
<ul>
<li>Apart from all the Spring related plug-ins that STS comes with, it also comes with several good plug-ins such as AspectJ Development Tools (AJDT), <a href="http://pmd.sourceforge.net/integrations.html#eclipse" target="_blank">PMD for Eclipse</a> (Java source code analyser) and EclEmma (Code Coverage Tool) which are what I usually install when I use pure Eclipse JEE.</li>
</ul>
<p>*Eclipse Plug-ins</p>
<ul>
<li>Subclipse</li>
<li>Maven Integration for Eclipse (M2Eclipse)</li>
<li>Aptana</li>
<li>JDepend (Java source code analyser)</li>
<li>Copy Fully Qualified Class Name Plugin</li>
<li>Resource Bundle Editor</li>
<li>and of course Spring ROO Integration for Eclipse (I heard a new STS will include it).</li>
</ul>
<p>However, what are really required for this ROO practice are Eclipse JEE, Spring IDE, AJDT, M2Eclipse and Spring ROO Integration. Or you can simply use STS and install M2Eclipse and Spring ROO Integration.  If you use Eclipse JEE Ganymede and install Spring IDE, it will automatically install AJDT as a dependency of Spring IDE since Ganymede has a smart software &amp; add-ons update manager. <img src='http://blog.lckymn.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>(Good News: A free version of STS is released. Check this out<br />
<a href="http://blog.springsource.com/2009/05/07/springsource-tool-suite-now-free/" target="_blank">SpringSource Tool Suite now free</a>).</p>
<p><div id="attachment_151" class="wp-caption alignnone" style="width: 916px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-02.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-02.jpg" alt="Import ROO project" title="Import ROO project" width="906" height="693" class="size-full wp-image-151" /></a><p class="wp-caption-text">Import ROO project</p></div><br />
Right click on the project explorer -> Select <code>Import</code></p>
<p><div id="attachment_152" class="wp-caption alignnone" style="width: 920px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-03.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-03.jpg" alt="Existing Projects into Workspace" title="Existing Projects into Workspace" width="910" height="699" class="size-full wp-image-152" /></a><p class="wp-caption-text">Existing Projects into Workspace</p></div><br />
Expand the <code>General</code> entry -> Select <code>Existing Projects into Workspace</code> -> Click the <code>Next</code> button.</p>
<p><div id="attachment_153" class="wp-caption alignnone" style="width: 919px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-04.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-04.jpg" alt="Select Project to Import" title="Select Project to Import" width="909" height="696" class="size-full wp-image-153" /></a><p class="wp-caption-text">Select Project to Import</p></div><br />
Browse the roo project directory created by roo. In my case it&#8217;s <code>roo_test</code> -> Click the <code>Finish</code> button.<br />
(NOTE: Because I created the roo project directory inside the workspace of Eclipse (STS), I don&#8217;t need to check <code>Copy projects into workspace</code> option.)</p>
<p><div id="attachment_154" class="wp-caption alignnone" style="width: 919px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-05.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-05.jpg" alt="Turn AJDT&#039;s Weaving Service on" title="Turn AJDT&#039;s Weaving Service on" width="909" height="696" class="size-full wp-image-154" /></a><p class="wp-caption-text">Turn AJDT's Weaving Service on</p></div><br />
If Eclipse asks to turn on weaving service function of AJDT, Click the <code>Yes</code> button.</p>
<p><div id="attachment_155" class="wp-caption alignnone" style="width: 919px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-06.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-06.jpg" alt="Restart STS (Eclipse)" title="Restart STS (Eclipse)" width="909" height="696" class="size-full wp-image-155" /></a><p class="wp-caption-text">Restart STS (Eclipse)</p></div><br />
Restart Eclipse.</p>
<p><div id="attachment_156" class="wp-caption alignnone" style="width: 477px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-07_01.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-07_01.jpg" alt="Dependency Problems" title="Dependency Problems" width="467" height="698" class="size-full wp-image-156" /></a><p class="wp-caption-text">Dependency Problems</p></div><br />
Eclipse is restarted and there are errors in the project as the require dependencies are not in the project directory.</p>
<p>So now, let M2Eclipse resolves this dependency problem. That&#8217;s why I&#8217;m using this plug-in. I want to focus on real problems in software development rather than focusing on providing dependency libraries for development.</p>
<p><div id="attachment_157" class="wp-caption alignnone" style="width: 804px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-07_02.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-07_02.jpg" alt="Let M2Eclipse Resolves Dependencies" title="Let M2Eclipse Resolves Dependencies" width="794" height="708" class="size-full wp-image-157" /></a><p class="wp-caption-text">Let M2Eclipse Resolves Dependencies</p></div><br />
Right click on the project -> Select the <code>Maven</code> option on the menu -> Select the <code>Enable Dependency Management</code>.<br />
Wait until it does its job.</p>
<p><div id="attachment_158" class="wp-caption alignnone" style="width: 475px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-08.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/05/roo-08.jpg" alt="Dependency Problems Solved" title="Dependency Problems Solved" width="465" height="699" class="size-full wp-image-158" /></a><p class="wp-caption-text">Dependency Problems Solved</p></div><br />
As shown here, Maven resolved it so all the required dependencies are there.</p>
<p>Next:<br />
<a href="http://blog.lckymn.com/2009/05/17/roo-so-cool-02/" target="_blank">http://blog.lckymn.com/2009/05/17/roo-so-cool-02/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lckymn.com/2009/05/17/roo-so-cool-01/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Test for Empty String</title>
		<link>http://blog.lckymn.com/2009/05/17/test-for-empty-string/</link>
		<comments>http://blog.lckymn.com/2009/05/17/test-for-empty-string/#comments</comments>
		<pubDate>Sun, 17 May 2009 00:30:22 +0000</pubDate>
		<dc:creator>Kevin</dc:creator>
				<category><![CDATA[Fundamental]]></category>
		<category><![CDATA[IT]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Empty String]]></category>
		<category><![CDATA[equals]]></category>
		<category><![CDATA[Maintainability]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[String]]></category>

		<guid isPermaLink="false">http://blog.lckymn.com/?p=171</guid>
		<description><![CDATA[<p>If you programme in Java (or other languages), the first thing to do when validating a String value might be checking if the String variable has the reference pointing to any String object or not (in other words, if it is null or not) or if the String object to which the reference in the String variable points contains an empty String (&#8221;") value.  In both cases, there is nothing to validate. Or you might purposely expect it and <p style="border: 3px solid rgb(243, 197, 52); padding: 5px; background-color: rgb(254, 254, 184); width: 600px; text-align: center;">[...Continue reading <a href="http://blog.lckymn.com/2009/05/17/test-for-empty-string/">Test for Empty String</a>...]</p>]]></description>
			<content:encoded><![CDATA[<p>If you programme in Java (or other languages), the first thing to do when validating a String value might be checking if the String variable has the reference pointing to any String object or not (in other words, if it is null or not) or if the String object to which the reference in the String variable points contains an empty String (&#8221;") value.  In both cases, there is nothing to validate. Or you might purposely expect it and if so, want to do something else. One way or another, the test happens frequently.  In Java, like other languages, there are, of course, many ways to do it. However, there can be a better way than other ways in terms of performance.  The reason why I&#8217;m writing it is that we seem to often forget that kind of basic principles while we are focusing on higher level design issues.  It is maintainability that I think the most important in software development but the better way to test for an empty String that I am about to point out here does not reduce maintainability yet increases performance.</p>
<p>To be honest, I had not thought of any other ways until the second grade when I was a university student. At that time, I coded like the following whenever I tried to test for an empty String.</p>
<pre class="brush: java;">
if (text == null || text.equals(&quot;&quot;))
</pre>
<p>(By the way, I now programme in this way when I check if an Object type variable is null.</p>
<pre class="brush: java;">
if (null == object)
</pre>
<p>This is to avoid some problem caused by a possible typo mistake that is (object = null) which means assigning null to the variable so it refers to nowhere.  Yet if I use (null == object), that mistake would be (null = object). This is assigning whatever in the object variable to null which does not make any sense and will cause a compile time error thus I can easily notice it.  So I follow this way even though I did not make this kind of mistake before. I will also never do it as long as I keep that style. <img src='http://blog.lckymn.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> )</p>
<p>Move back to the original topic, when I became a third year student which was the final year of my course, I was attracted to Object-Orientation and Java.  Probably at the same time, I also enjoyed checking out the source code of JDK.  I thought &#8220;it doesn&#8217;t seem to be a good idea to use the equals method for empty String test&#8221; after I read the source of the method in Java String class.</p>
<p>Here is the source code of the equals() method of String class in JDK 1.6.0_13.</p>
<pre class="brush: java;">
    /**
     * Compares this string to the specified object.  The result is {@code
     * true} if and only if the argument is not {@code null} and is a {@code
     * String} object that represents the same sequence of characters as this
     * object.
     *
     * @param  anObject
     *         The object to compare this {@code String} against
     *
     * @return  {@code true} if the given object represents a {@code String}
     *          equivalent to this string, {@code false} otherwise
     *
     * @see  #compareTo(String)
     * @see  #equalsIgnoreCase(String)
     */
    public boolean equals(Object anObject) {
	if (this == anObject) {
	    return true;
	}
	if (anObject instanceof String) {
	    String anotherString = (String)anObject;
	    int n = count;
	    if (n == anotherString.count) {
		char v1[] = value;
		char v2[] = anotherString.value;
		int i = offset;
		int j = anotherString.offset;
		while (n-- != 0) {
		    if (v1[i++] != v2[j++])
			return false;
		}
		return true;
	    }
	}
	return false;
    }
</pre>
<p>For just simple empty String test, the code does not seem to be right, as you see, it requires several lines of code to be processed for that simple test. Since String is immutable its length value is always a constant int value and it is therefore comparing the length of the String with zero should be faster than using the <code>equals()</code> method.</p>
<p>So in order to see how many lines of code in the <code>equals()</code> method are processed to test for an empty String, I made simple test code.  I copied code partially from Java&#8217;s String class and made TestString class which has the same <code>equals()</code> method as what String class has then added some code to display how many lines are processed.</p>
<pre class="brush: java;">
package com.lckymn.test.emptystring;

import java.util.Arrays;

/**
 * This is TestString class the code of which is copied from java.lang.String class to test the equals() method of the String class. It just
 * has the part of String code which is enough to see how many lines of code are processed for empty String test.
 *
 * @author Lee, SeongHyun (Kevin)
 * @version 0.01 (2009-05-05)
 */
public final class TestString
{
	/** The value is used for character storage. */
	private final char value[];

	/** The offset is the first index of the storage that is used. */
	private final int offset;

	/** The count is the number of characters in the String. */
	private final int count;

	public TestString()
	{
		this.offset = 0;
		this.count = 0;
		this.value = new char[0];
	}

	public TestString(char value[])
	{
		int size = value.length;
		this.offset = 0;
		this.count = size;
		this.value = Arrays.copyOf(value, size);
	}

	public TestString(int offset, int count, char value[])
	{
		this.value = value;
		this.offset = offset;
		this.count = count;
	}

	public boolean equals(Object anObject)
	{
		int tempCount = 0;
		System.out.println(++tempCount + &quot;: A&quot;);
		if (this == anObject)
		{
			System.out.println(++tempCount + &quot;: B&quot;);
			return true;
		}
		System.out.println(++tempCount + &quot;: C&quot;);
		if (anObject instanceof TestString)
		{
			System.out.println(++tempCount + &quot;: D&quot;);
			TestString anotherString = (TestString) anObject;
			System.out.println(++tempCount + &quot;: E&quot;);
			int n = count;
			System.out.println(++tempCount + &quot;: F&quot;);
			if (n == anotherString.count)
			{
				System.out.println(++tempCount + &quot;: G&quot;);
				char v1[] = value;
				System.out.println(++tempCount + &quot;: H&quot;);
				char v2[] = anotherString.value;
				System.out.println(++tempCount + &quot;: I&quot;);
				int i = offset;
				System.out.println(++tempCount + &quot;: J&quot;);
				int j = anotherString.offset;
				System.out.println(++tempCount + &quot;: K&quot;);
				while (n-- != 0)
				{
					System.out.println(++tempCount + &quot;: L&quot;);
					if (v1[i++] != v2[j++])
					{
						System.out.println(++tempCount + &quot;: M&quot;);
						return false;
					}
				}
				System.out.println(++tempCount + &quot;: N&quot;);
				return true;
			}
		}
		System.out.println(++tempCount + &quot;: O&quot;);
		return false;
	}

}
</pre>
<p>The following is the test code using the TestString.</p>
<pre class="brush: java;">
package com.lckymn.test.emptystring;

/**
 * This class is to see how many lines of code in the equals() method of String class are processed to test for an empty String.
 *
 * @author Lee, SeongHyun (Kevin)
 * @version 0.01 (2009-05-05)
 *
 */
public final class EmptyTest
{
	private static final String EMPTY = &quot;It's empty.\n&quot;;
	private static final String NOT_EMPTY = &quot;It's not empty.\n&quot;;

	/**
	 * @param args
	 */
	public static void main(String[] args)
	{

		TestString emptyOne = new TestString();
		TestString anotherEmptyOne = new TestString();
		TestString testString = new TestString(new char[] { 'H', 'e', 'l', 'l', 'o' });

		System.out.println(&quot;TestString emptyOne = new TestString();\n&quot; + &quot;TestString anotherEmptyOne = new TestString();\n&quot;
				+ &quot;TestString testString = new TestString(new char[] { 'H', 'e', 'l', 'l', 'o' });\n&quot;);

		System.out.println(&quot;emptyOne.equals(emptyOne): &quot;);
		if (emptyOne.equals(emptyOne))
		{
			System.out.println(EMPTY);
		}
		else
		{
			System.out.println(NOT_EMPTY);
		}

		System.out.println(&quot;emptyOne.equals(anotherEmptyOne): &quot;);
		if (emptyOne.equals(anotherEmptyOne))
		{
			System.out.println(EMPTY);
		}
		else
		{
			System.out.println(NOT_EMPTY);
		}

		System.out.println(&quot;emptyOne.equals(testString)&quot;);
		if (emptyOne.equals(testString))
		{
			System.out.println(EMPTY);
		}
		else
		{
			System.out.println(NOT_EMPTY);
		}

		System.exit(0);
	}

}
</pre>
<p>The result of this code is</p>
<pre class="brush: plain; gutter: false;">
TestString emptyOne = new TestString();
TestString anotherEmptyOne = new TestString();
TestString testString = new TestString(new char[] { 'H', 'e', 'l', 'l', 'o' });

emptyOne.equals(emptyOne):
1: A
2: B
It's empty.

emptyOne.equals(anotherEmptyOne):
1: A
2: C
3: D
4: E
5: F
6: G
7: H
8: I
9: J
10: K
11: N
It's empty.

emptyOne.equals(testString)
1: A
2: C
3: D
4: E
5: F
6: O
It's not empty.
</pre>
<p>The first test is comparing two empty TestString objects which are in fact an identical object. To recognise it is an empty String, two lines of the code are executed.</p>
<pre class="brush: plain; gutter: false; highlight: [3];">
emptyOne.equals(emptyOne):
1: A
2: B
It's empty.
</pre>
<p>The second test is comparing two empty TestString objects each of which has a reference to a different TestString object meaning emptyOne.equals(anotherEmptyOne) is true but emptyOne == anotherEmptyOne is false.  It requires to process eleven lines of the code to know anotherEmptyOne object is an empty TestString object.</p>
<pre class="brush: plain; gutter: false; highlight: [12];">
emptyOne.equals(anotherEmptyOne):
1: A
2: C
3: D
4: E
5: F
6: G
7: H
8: I
9: J
10: K
11: N
It's empty.
</pre>
<p>The final one is testing if testString TestString object is an empty TestString object. Since testString has &#8220;Hello&#8221;, it is not empty. To find it, six lines of the code are implemented.</p>
<pre class="brush: plain; gutter: false; highlight: [7];">
emptyOne.equals(testString)
1: A
2: C
3: D
4: E
5: F
6: O
It's not empty.
</pre>
<p>Based on the test above, it is quite obvious that <code>equals()</code> method cannot perform better than comparing zero(0) with the length of String object as the former one requires two to eleven (average: (2+11+6)/3 = 10) lines of code to test for an empty String whereas a length comparison requires only one or two lines of code.  So I finally tested if it is truly faster to check String&#8217;s length to test for an empty String.</p>
<p>The following is the test code.</p>
<pre class="brush: java;">
package com.lckymn.test.emptystring;

/**
 * This class is to benchmark the performance of the equals() method in String class and comparing the length of the String object in order
 * to test if the String object contains an empty String.
 *
 * @author Lee, SeongHyun (Kevin)
 * @version 0.01 (2009-05-05)
 */
public final class EmptyPerformanceTest
{
	public static final int HOW_MANY_TIMES = 1000000000;

	/**
	 * @param args
	 */
	public static void main(String[] args)
	{
		String emptyOne = &quot;&quot;;
		String anotherEmptyOne = new String(&quot;&quot;);
		String notEmptyOne = &quot;Hello&quot;;

		System.out.println(&quot;String emptyOne = \&quot;\&quot;;\n&quot; + &quot;String anotherEmptyOne = new String(\&quot;\&quot;);\n&quot;
				+ &quot;String notEmptyOne = \&quot;Hello\&quot;;\n&quot;);

		long result = 0;

		result = System.currentTimeMillis();
		for (int i = 0; i &lt; HOW_MANY_TIMES; i++)
		{
			if (&quot;&quot;.equals(emptyOne))
				;
		}
		result = System.currentTimeMillis() - result;
		System.out.println(&quot;\&quot;\&quot;.equals(emptyOne): &quot; + result);

		result = System.currentTimeMillis();
		for (int i = 0; i &lt; HOW_MANY_TIMES; i++)
		{
			if (&quot;&quot;.equals(anotherEmptyOne))
				;
		}
		result = System.currentTimeMillis() - result;
		System.out.println(&quot;\&quot;\&quot;.equals(anotherEmptyOne): &quot; + result);

		result = System.currentTimeMillis();
		for (int i = 0; i &lt; HOW_MANY_TIMES; i++)
		{
			if (&quot;&quot;.equals(notEmptyOne))
				;
		}
		result = System.currentTimeMillis() - result;
		System.out.println(&quot;\&quot;\&quot;.equals(notEmptyOne): &quot; + result);

		System.out.println(&quot;&quot;);

		result = System.currentTimeMillis();
		for (int i = 0; i &lt; HOW_MANY_TIMES; i++)
		{
			if (0 == emptyOne.length())
				;
		}
		result = System.currentTimeMillis() - result;
		System.out.println(&quot;0 == emptyOne.length(): &quot; + result);

		result = System.currentTimeMillis();
		for (int i = 0; i &lt; HOW_MANY_TIMES; i++)
		{
			if (0 == anotherEmptyOne.length())
				;
		}
		result = System.currentTimeMillis() - result;
		System.out.println(&quot;0 == anotherEmptyOne.length(): &quot; + result);

		result = System.currentTimeMillis();
		for (int i = 0; i &lt; HOW_MANY_TIMES; i++)
		{
			if (0 == notEmptyOne.length())
				;
		}
		result = System.currentTimeMillis() - result;
		System.out.println(&quot;0 == notEmptyOne.length(): &quot; + result);

		System.exit(0);
	}
}
</pre>
<p>And&#8230; seeing is believing&#8230; so here is the result.</p>
<pre class="brush: plain; gutter: false; highlight: [5,6,7,9,10,11];">
String emptyOne = &quot;&quot;;
String anotherEmptyOne = new String(&quot;&quot;);
String notEmptyOne = &quot;Hello&quot;;

&quot;&quot;.equals(emptyOne): 1470
&quot;&quot;.equals(anotherEmptyOne): 6951
&quot;&quot;.equals(notEmptyOne): 5601

0 == emptyOne.length(): 5
0 == anotherEmptyOne.length(): 5
0 == notEmptyOne.length(): 5
</pre>
<p>Using <code>equals()</code> method to test both empty String objects which are also an identical object took 1470 milliseconds while comparing 0 with the length of the emptyOne object took 5 milliseconds.<br />
If the target object is not the same empty object, it is worse. The test shows it took 6951 milliseconds. Again, the length comparison took just 5 milliseconds.  Considering that the test conducted one billion times, taking just 5 milliseconds is really fast.<br />
Finally, as seen in the test, it took 5601 milliseconds to know the given String is not empty.  The length checking is still 5 milliseconds.</p>
<p>Although each test is repeated 1,000,000,000 times, the difference is, in my opinion, not really acceptable as we may have numerous other places to lose the performance of the software thus it might be a good idea to prevent predictable ones from happening.</p>
<p>So better do this when testing for an empty String. <img src='http://blog.lckymn.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<pre class="brush: java;">
if (null == text || 0 == text.length())
{
	// it is empty.
}
</pre>
<p>Or if you are using JDK 1.6 (Java 6), you can also use <a href="http://java.sun.com/javase/6/docs/api/java/lang/String.html#isEmpty()" target="_blank">String&#8217;s isEmpty()</a> method which does exactly the same as checking if its length is 0.</p>
<pre class="brush: java;">
if (null == text || text.isEmpty())
{
	// it is empty.
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.lckymn.com/2009/05/17/test-for-empty-string/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Communication with Users</title>
		<link>http://blog.lckymn.com/2009/05/14/communication-with-users/</link>
		<comments>http://blog.lckymn.com/2009/05/14/communication-with-users/#comments</comments>
		<pubDate>Thu, 14 May 2009 10:52:45 +0000</pubDate>
		<dc:creator>Kevin</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[Mine]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[TeCTra]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Communication]]></category>
		<category><![CDATA[Email]]></category>
		<category><![CDATA[Feedback]]></category>
		<category><![CDATA[Issue Tracking]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[User]]></category>

		<guid isPermaLink="false">http://blog.lckymn.com/?p=137</guid>
		<description><![CDATA[<p>I have developed Team Contribution Tracking (TeCTra) system for UTS. It is an Ajax web application the back-end of which is built using Java.  A few months ago, a new function to get feedback from users was added to TeCTra.</p>
<div id="attachment_138" class="wp-caption aligncenter" style="width: 547px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/tectra_user_feedback_function.jpg"><img class="size-full wp-image-138" title="TeCTra User Feedback Function" src="http://blog.lckymn.com/wp-content/uploads/2009/05/tectra_user_feedback_function.jpg" alt="TeCTra User Feedback Function" width="537" height="81" /></a><p class="wp-caption-text">TeCTra User Feedback Function</p></div>
<p>About a half month ago, I&#8217;ve got a feedback email from a user.  This is <p style="border: 3px solid rgb(243, 197, 52); padding: 5px; background-color: rgb(254, 254, 184); width: 600px; text-align: center;">[...Continue reading <a href="http://blog.lckymn.com/2009/05/14/communication-with-users/">Communication with Users</a>...]</p>]]></description>
			<content:encoded><![CDATA[<p>I have developed Team Contribution Tracking (TeCTra) system for UTS. It is an Ajax web application the back-end of which is built using Java.  A few months ago, a new function to get feedback from users was added to TeCTra.</p>
<div id="attachment_138" class="wp-caption aligncenter" style="width: 547px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/tectra_user_feedback_function.jpg"><img class="size-full wp-image-138" title="TeCTra User Feedback Function" src="http://blog.lckymn.com/wp-content/uploads/2009/05/tectra_user_feedback_function.jpg" alt="TeCTra User Feedback Function" width="537" height="81" /></a><p class="wp-caption-text">TeCTra User Feedback Function</p></div>
<p>About a half month ago, I&#8217;ve got a feedback email from a user.  This is sent through the function above.</p>
<div id="attachment_140" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/tectra_user_feedback_01.jpg"><img class="size-full wp-image-140" title="TeCTra User Feedback 01" src="http://blog.lckymn.com/wp-content/uploads/2009/05/tectra_user_feedback_01.jpg" alt="TeCTra User Feedback Email" width="300" height="250" /></a><p class="wp-caption-text">TeCTra User Feedback Email</p></div>
<div id="attachment_141" class="wp-caption aligncenter" style="width: 396px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/tectra_user_feedback_02.jpg"><img class="size-full wp-image-141" title="TeCTra User Feedback 02" src="http://blog.lckymn.com/wp-content/uploads/2009/05/tectra_user_feedback_02.jpg" alt="TeCTra User Feedback Email" width="386" height="192" /></a><p class="wp-caption-text">TeCTra User Feedback Email</p></div>
<p>This feedback is about the usability of TeCTra. What he/she points out is that the button to create a new task in the time sheet tab is positioned too close to the remove button so users may click the remove button by mistake when they want to click the add task button.<br />
As the image below shows, the last remove button is too close to the new task button.  So as mentioned in the feedback, users might click the remove button by mistake.</p>
<div id="attachment_143" class="wp-caption aligncenter" style="width: 850px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/tectra-old-remove_task_and_new_task.jpg"><img class="size-full wp-image-143" title="TeCTra - Old Remove Task Buttons and New Task Button" src="http://blog.lckymn.com/wp-content/uploads/2009/05/tectra-old-remove_task_and_new_task.jpg" alt="The last remove task button is too close to the new task button." width="840" height="624" /></a><p class="wp-caption-text">The last remove task button is too close to the new task button.</p></div>
<p>We, the development team of the TeCTra, had a discussion about this and other issues then decided to move the buttons to the right-hand side. Since the front-end is developed by my friend, Sverre, he changed the positions of the remove buttons.  My boss, Dr. Richard Raban, also brought other issues so I and my friend took care of all of these and deployed a new version of TeCTra.</p>
<div id="attachment_144" class="wp-caption aligncenter" style="width: 785px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/tectra-new-remove_task_and_new_task.jpg"><img class="size-full wp-image-144" title="TeCTra - New Remove Task Buttons and New Task Button" src="http://blog.lckymn.com/wp-content/uploads/2009/05/tectra-new-remove_task_and_new_task.jpg" alt="Now the remove buttons are all right-justified so users will not click it by chance when they want to click the new task button." width="775" height="548" /></a><p class="wp-caption-text">Now the remove buttons are all right-justified so users will not click it by chance when they want to click the new task button.</p></div>
<p>It is good to have an issue tracking system so that the users of software can easily report bugs they found or require new functions they want.  This might be good enough yet it is even better if the application itself has issue tracking and feedback functions as I&#8217;ve learned from the user feedback function.  Thus I am thinking to implement feedback and bug reporting functions which directly add a new ticket to an issue tracking system from my next application development.  So it does not only send a feedback email to the developer but also add an issue to the issue tracking system.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lckymn.com/2009/05/14/communication-with-users/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Enable Ctrl+Alt+Backspace Again</title>
		<link>http://blog.lckymn.com/2009/05/03/enable-ctrl-alt-backspace-again/</link>
		<comments>http://blog.lckymn.com/2009/05/03/enable-ctrl-alt-backspace-again/#comments</comments>
		<pubDate>Sun, 03 May 2009 12:43:09 +0000</pubDate>
		<dc:creator>Kevin</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[Ubuntu Linux]]></category>
		<category><![CDATA[Ctrl+Alt+Backspace]]></category>
		<category><![CDATA[DontZap]]></category>
		<category><![CDATA[Jaunty Jackalope]]></category>
		<category><![CDATA[Karmic Koala]]></category>
		<category><![CDATA[Restart X]]></category>
		<category><![CDATA[Restart Xorg]]></category>
		<category><![CDATA[Ubuntu Linux 9.04]]></category>
		<category><![CDATA[Ubuntu Linux 9.04 Jaunty Jackalope]]></category>
		<category><![CDATA[Ubuntu Linux 9.10]]></category>
		<category><![CDATA[Ubuntu Linux 9.10 Karmic Koala]]></category>
		<category><![CDATA[Ubuntu Linux Jaunty Jackalope]]></category>
		<category><![CDATA[Ubuntu Linux Karmic Koala]]></category>
		<category><![CDATA[Xorg]]></category>
		<category><![CDATA[Xorg Server]]></category>

		<guid isPermaLink="false">http://blog.lckymn.com/?p=123</guid>
		<description><![CDATA[<code>Ctrl+Alt+Backspace</code> Disabled
<p>As stated in the <a href="http://www.ubuntu.com/getubuntu/releasenotes/904" target="_blank">Ubuntu 9.04 release notes</a>, Ctrl-Alt-Backspace key combination to restart Xorg is disabled.</p>

<p>Ctrl-Alt-Backspace disabled by default in Xorg</p>
<p>
The Ctrl-Alt-Backspace key combination to force a restart of X is now disabled by default, to eliminate the problem of accidentally triggering the key combination. Users who do want this function can enable it in their xorg.conf, or by running the command <code>dontzap --disable</code>.
</p>

Enable <code>Ctrl+Alt+Backspace</code> Again
Ubuntu Linux 9.10 Karmic Koala
<div class="txc-textbox" style="border: 3px solid rgb(243, 197, 52); <p style="border: 3px solid rgb(243, 197, 52); padding: 5px; background-color: rgb(254, 254, 184); width: 600px; text-align: center;">[...Continue reading <a href="http://blog.lckymn.com/2009/05/03/enable-ctrl-alt-backspace-again/">Enable Ctrl+Alt+Backspace Again</a>...]</p>]]></description>
			<content:encoded><![CDATA[<h1><code>Ctrl+Alt+Backspace</code> Disabled</h1>
<p>As stated in the <a href="http://www.ubuntu.com/getubuntu/releasenotes/904" target="_blank">Ubuntu 9.04 release notes</a>, Ctrl-Alt-Backspace key combination to restart Xorg is disabled.</p>
<blockquote>
<p><strong>Ctrl-Alt-Backspace disabled by default in Xorg</strong></p>
<p>
The Ctrl-Alt-Backspace key combination to force a restart of X is now disabled by default, to eliminate the problem of accidentally triggering the key combination. Users who do want this function can enable it in their xorg.conf, or by running the command <code>dontzap --disable</code>.
</p>
</blockquote>
<h1>Enable <code>Ctrl+Alt+Backspace</code> Again</h1>
<h2>Ubuntu Linux 9.10 Karmic Koala</h2>
<div class="txc-textbox" style="border: 3px solid rgb(243, 197, 52); padding: 10px; background-color: rgb(254, 254, 184);">
This part is added on the 23rd of November in 2009 as in the 9.10 version, enabling <code>Ctrl+Alt+Backspace</code> is different from doing it in the 9.04 version.<br />
If you are using Ubuntu Linux 9.04 Jaunty Jackalope, please scroll down to skip this part then you can find one for Jaunty Jackalope.
</div>
<p><div id="attachment_470" class="wp-caption alignnone" style="width: 718px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/01_open_the_keyboard_menu.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/05/01_open_the_keyboard_menu.jpg" alt="* System -&gt; Preferences -&gt; Keyboard" title="01 System -&gt; Preferences -&gt; Keyboard" width="708" height="318" class="size-full wp-image-470" /></a><p class="wp-caption-text">* System -> Preferences -> Keyboard</p></div><br />
* System -> Preferences -> Keyboard</p>
<p><div id="attachment_471" class="wp-caption alignnone" style="width: 509px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/02_click_layout_options.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/05/02_click_layout_options.jpg" alt="Select the &#039;Layouts&#039; tab -&gt; Click the &#039;Layout Options&#039; button" title="02 Select the &#039;Layouts&#039; tab -&gt; Click the &#039;Layout Options&#039; button" width="499" height="546" class="size-full wp-image-471" /></a><p class="wp-caption-text">Select the 'Layouts' tab -> Click the 'Layout Options' button</p></div><br />
* Select the &#8216;Layouts&#8217; tab -> Click the &#8216;Layout Options&#8217; button</p>
<p><div id="attachment_472" class="wp-caption alignnone" style="width: 586px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/03_check_the_key_sequence_to_terminate_x.jpg"><img src="http://blog.lckymn.com/wp-content/uploads/2009/05/03_check_the_key_sequence_to_terminate_x.jpg" alt="Click the &#039;Key sequence to kill the X server&#039; to expand it -&gt; Check the &#039;Control + Alt + Backspace&#039; option -&gt; Click the &#039;Close&#039; button" title="03 Click the &#039;Key sequence to kill the X server&#039; to expand it -&gt; Check the &#039;Control + Alt + Backspace&#039; option -&gt; Click the &#039;Close&#039; button" width="576" height="542" class="size-full wp-image-472" /></a><p class="wp-caption-text">Click the 'Key sequence to kill the X server' to expand it -> Check the 'Control + Alt + Backspace' option -> Click the 'Close' button</p></div><br />
* Click the &#8216;Key sequence to kill the X server&#8217; to expand it -> Check the &#8216;Control + Alt + Backspace&#8217; option -> Click the &#8216;Close&#8217; button</p>
<p>Done!!!</p>
<h2>Ubuntu Linux 9.04 Jaunty Jackalope</h2>
<p>* Open the <code>/etc/X11/xorg.conf</code> file and add</p>
<pre>
Section "ServerFlags"
	Option	"DontZap"	"False"
EndSection
</pre>
<p>* Or simply use <code>dontzap</code>.<br />
* If it is not installed already,</p>
<pre>$ sudo apt-get install dontzap </pre>
<p>* Use the <code>dontzap</code> command to enable <code>Ctrl+Alt+Backspace</code></p>
<pre>$ sudo dontzap --disable </pre>
<p>This acually adds </p>
<pre>
Section "ServerFlags"
	Option	"DontZap"	"False"
EndSection
</pre>
<p>to the <code>/etc/X11/xorg.conf</code> file.</p>
<p>* After it is done, make sure to log out &#038; in for the change to take effect.</p>
<p>* To enable the &#8220;DontZap&#8221; option again,</p>
<pre>$ sudo dontzap --enable </pre>
<p>* More information about the <code>DontZap</code> option.</p>
<blockquote>
<p>
<a href="http://www.x.org/archive/X11R6.8.0/doc/xorg.conf.5.html#sect4" target="_blank">http://www.x.org/archive/X11R6.8.0/doc/xorg.conf.5.html#sect4</a>
</p>
<pre>
Option "DontZap" "boolean"
</pre>
<p>
    This disallows the use of the Ctrl+Alt+Backspace sequence. That sequence is normally used to terminate the Xorg server. When this option is enabled, that key sequence has no special meaning and is passed to clients. Default: off.
</p>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://blog.lckymn.com/2009/05/03/enable-ctrl-alt-backspace-again/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Change Back to Previous Update Notification</title>
		<link>http://blog.lckymn.com/2009/05/03/change-back-to-previou-update-notification/</link>
		<comments>http://blog.lckymn.com/2009/05/03/change-back-to-previou-update-notification/#comments</comments>
		<pubDate>Sun, 03 May 2009 11:53:14 +0000</pubDate>
		<dc:creator>Kevin</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[Ubuntu Linux]]></category>
		<category><![CDATA[Configuration Editor]]></category>
		<category><![CDATA[gconf-editor]]></category>
		<category><![CDATA[Ubuntu Linux 9.04 Jaunty Jackalope]]></category>
		<category><![CDATA[Ubuntu Linux Jaunty Jackalope]]></category>
		<category><![CDATA[Update Notification]]></category>
		<category><![CDATA[Update Notifier]]></category>

		<guid isPermaLink="false">http://blog.lckymn.com/?p=98</guid>
		<description><![CDATA[<p>According to the <a title="Ubuntu 9.04 Release Notes" href="http://www.ubuntu.com/getubuntu/releasenotes/904" target="_blank">Ubuntu 9.04 release notes</a>, there is a change in the update notification.</p>
<p>Change in notifications of available updates</p>
<p>Ubuntu 9.04 introduces a change to the handling of package updates, launching update-manager directly instead of displaying a notification icon in the GNOME panel. Users will still be notified of security updates on a daily basis, but for updates that are not security-related, users will only be prompted once a week.</p>
<p>Users who wish to continue <p style="border: 3px solid rgb(243, 197, 52); padding: 5px; background-color: rgb(254, 254, 184); width: 600px; text-align: center;">[...Continue reading <a href="http://blog.lckymn.com/2009/05/03/change-back-to-previou-update-notification/">Change Back to Previous Update Notification</a>...]</p>]]></description>
			<content:encoded><![CDATA[<p>According to the <a title="Ubuntu 9.04 Release Notes" href="http://www.ubuntu.com/getubuntu/releasenotes/904" target="_blank">Ubuntu 9.04 release notes</a>, there is a change in the update notification.</p>
<blockquote><p><strong>Change in notifications of available updates</strong></p>
<p>Ubuntu 9.04 introduces a change to the handling of package updates, launching update-manager directly instead of displaying a notification icon in the GNOME panel. Users will still be notified of security updates on a daily basis, but for updates that are not security-related, users will only be prompted once a week.</p>
<p>Users who wish to continue receiving update notifications in the previous manner can restore the earlier behavior using the following command:</p>
<pre>gconftool -s --type bool /apps/update-notifier/auto_launch false </pre>
</blockquote>
<p>As it says, this can be changed back to the previous style with the following command.</p>
<pre>
$ gconftool -s --type bool /apps/update-notifier/auto_launch false
</pre>
<p>or through the <code>Configuration Editor</code></p>
<div id="attachment_104" class="wp-caption aligncenter" style="width: 831px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/updatenotification01.jpg"><img class="size-full wp-image-104" title="Install Configuration Editor" src="http://blog.lckymn.com/wp-content/uploads/2009/05/updatenotification01.jpg" alt="Install the Configuration Editor if it is not already installed." width="821" height="597" /></a><p class="wp-caption-text">Install the Configuration Editor if it is not already installed.</p></div>
<pre></pre>
<div id="attachment_105" class="wp-caption aligncenter" style="width: 447px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/updatenotification02.jpg"><img class="size-full wp-image-105" title="Open Configuration Editor" src="http://blog.lckymn.com/wp-content/uploads/2009/05/updatenotification02.jpg" alt="Open the Configuration Editor" width="437" height="626" /></a><p class="wp-caption-text">Open the Configuration Editor<br />
Applications -&gt; System Tools -&gt; Configuration Editor</p></div>
<pre></pre>
<div id="attachment_106" class="wp-caption aligncenter" style="width: 680px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/updatenotification03.jpg"><img class="size-full wp-image-106" title="Expand apps category" src="http://blog.lckymn.com/wp-content/uploads/2009/05/updatenotification03.jpg" alt="Expand &lt;code&gt;apps&lt;/code&gt; category" width="670" height="449" /></a><p class="wp-caption-text">Expand the <code>apps</code> category</p></div>
<pre></pre>
<div id="attachment_107" class="wp-caption aligncenter" style="width: 681px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/updatenotification04.jpg"><img class="size-full wp-image-107" title="Click the update-notifier" src="http://blog.lckymn.com/wp-content/uploads/2009/05/updatenotification04.jpg" alt="Click the &lt;code&gt;update-notifier&lt;/code&gt; to select it." width="671" height="449" /></a><p class="wp-caption-text">Click the <code>update-notifier</code> to select it.<br />
The configuration details of it appears on the right hand side</p></div>
<pre></pre>
<div id="attachment_108" class="wp-caption aligncenter" style="width: 679px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/updatenotification05.jpg"><img class="size-full wp-image-108" title="Uncheck the auto_launch key" src="http://blog.lckymn.com/wp-content/uploads/2009/05/updatenotification05.jpg" alt="Uncheck the value of the &lt;code&gt;auto_launch&lt;/code&gt; key." width="669" height="448" /></a><p class="wp-caption-text">Uncheck the value of the <code>auto_launch</code> key.<br />
Close the <code>Configuration Editor</code><br />
* Optional: <code>regular_auto_launch_interval</code> can be changed for more or less frequent notification</p></div>
<pre></pre>
<div id="attachment_109" class="wp-caption aligncenter" style="width: 538px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/05/updatenotification06.jpg"><img class="size-full wp-image-109" title="Update Notifier is back" src="http://blog.lckymn.com/wp-content/uploads/2009/05/updatenotification06.jpg" alt="Update Notifier will appear when there are available updates instead of the update manager directly launched." width="528" height="87" /></a><p class="wp-caption-text">Update Notifier will appear when there are available updates instead of the update manager directly launched.</p></div>
<pre></pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.lckymn.com/2009/05/03/change-back-to-previou-update-notification/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My Desktop in April 2009</title>
		<link>http://blog.lckymn.com/2009/04/27/my-desktop-in-april-2009/</link>
		<comments>http://blog.lckymn.com/2009/04/27/my-desktop-in-april-2009/#comments</comments>
		<pubDate>Sun, 26 Apr 2009 16:39:33 +0000</pubDate>
		<dc:creator>Kevin</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[Ubuntu Linux]]></category>
		<category><![CDATA[64bit]]></category>
		<category><![CDATA[9.04]]></category>
		<category><![CDATA[Cairo-Dock]]></category>
		<category><![CDATA[Compiz]]></category>
		<category><![CDATA[GNOME Do]]></category>
		<category><![CDATA[Jaunty Jackalope]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mac4Lin]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[Ubuntu Linux 9.04]]></category>
		<category><![CDATA[Ubuntu Linux 9.04 Jaunty Jackalope]]></category>
		<category><![CDATA[Ubuntu Linux Jaunty Jackalope]]></category>

		<guid isPermaLink="false">http://blog.lckymn.com/?p=76</guid>
		<description><![CDATA[<div style="text-align: center;">Ubuntu Linux Desktop 9.04 Jaunty Jackalope 64bit + Compiz + Mac4Lin + GNOME Do + Cairo Dock
<object width="854" height="505"><embed src="http://www.youtube.com/v/_Etr9stJl5Q&#038;hl=en&#038;fs=1&#038;ap=%2526fmt%3D22" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="854" height="505"></embed></object></div>


<div style="text-align: center;">Ubuntu Linux Desktop 9.04 Jaunty Jackalope 64bit + Compiz + Mac4Lin + GNOME Do + Cairo Dock
(Same Screencast but Lower Quality than the First One)
<object width="854" height="505"><embed src="http://www.youtube.com/v/_Etr9stJl5Q&#038;hl=en&#038;fs=1&#038;ap=%2526fmt%3D35" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="854" height="505"></embed></object></div>
<p style="text-align: center;">


<p style="text-align: center;">CPU: E2160 1.80 GHz
RAM: 4 GiB
Graphic Chip: Intel G33/31 (on board)</p>


<p>This is Ubuntu Linux 9.04 just <p style="border: 3px solid rgb(243, 197, 52); padding: 5px; background-color: rgb(254, 254, 184); width: 600px; text-align: center;">[...Continue reading <a href="http://blog.lckymn.com/2009/04/27/my-desktop-in-april-2009/">My Desktop in April 2009</a>...]</p>]]></description>
			<content:encoded><![CDATA[<div style="text-align: center;">Ubuntu Linux Desktop 9.04 Jaunty Jackalope 64bit + Compiz + Mac4Lin + GNOME Do + Cairo Dock<br />
<object width="854" height="505"><param name="movie" value="http://www.youtube.com/v/_Etr9stJl5Q&#038;hl=en&#038;fs=1&#038;ap=%2526fmt%3D22"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/_Etr9stJl5Q&#038;hl=en&#038;fs=1&#038;ap=%2526fmt%3D22" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="854" height="505"></embed></object></div>
<pre>
</pre>
<div style="text-align: center;">Ubuntu Linux Desktop 9.04 Jaunty Jackalope 64bit + Compiz + Mac4Lin + GNOME Do + Cairo Dock<br />
(<span style="color: #0000ff;"><strong>Same Screencast but Lower Quality than the First One</strong></span>)<br />
<object width="854" height="505"><param name="movie" value="http://www.youtube.com/v/_Etr9stJl5Q&#038;hl=en&#038;fs=1&#038;ap=%2526fmt%3D35"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/_Etr9stJl5Q&#038;hl=en&#038;fs=1&#038;ap=%2526fmt%3D35" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="854" height="505"></embed></object></div>
<p style="text-align: center;">
<pre>
</pre>
<p style="text-align: center;">CPU: E2160 1.80 GHz<br />
RAM: 4 GiB<br />
Graphic Chip: Intel G33/31 (on board)</p>
<pre>
</pre>
<p>This is Ubuntu Linux 9.04 just released about two days ago (24th, April) as I already mentioned in my previous post.</p>
<p>I used a LiveCD of Ubuntu Linux 9.04 to check if it works well on my PC. It fortunately works well so I upgraded mine from 8.10 to 9.04.  The screencast above is made after the upgrade. It looks slow in the video yet that&#8217;s because of the software I used to record the desktop. It works really fast indeed without the software used to screencast.</p>
<p>These are screenshots taken before the upgrade.</p>
<div id="attachment_91" class="wp-caption aligncenter" style="width: 910px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/04/upgrade_to_9_04_01.jpg"><img class="size-full wp-image-91" title="upgrade_to_9_04_01" src="http://blog.lckymn.com/wp-content/uploads/2009/04/upgrade_to_9_04_01.jpg" alt="Start Upgrading to 9.04" width="900" height="563" /></a><p class="wp-caption-text">Start Upgrading to 9.04</p></div>
<div id="attachment_92" class="wp-caption aligncenter" style="width: 910px"><a href="http://blog.lckymn.com/wp-content/uploads/2009/04/upgrade_to_9_04_02.jpg"><img class="size-full wp-image-92" title="upgrade_to_9_04_02" src="http://blog.lckymn.com/wp-content/uploads/2009/04/upgrade_to_9_04_02.jpg" alt="Upgrade In Progress" width="900" height="563" /></a><p class="wp-caption-text">Upgrade In Progress</p></div>
<p>The size of the memory installed on my PC is 4 GiB but it does not have to be 4GiB or bigger.  I need 4 GiB for the software I use to develop web applications.  Those development tools and servers require lots of memory.  However, based on my experience, without using that kind of heavy applications, 2 GiB is enough or even 1 GiB is still fine although for 1 GiB memory I rather recommend <a title="Xubuntu" href="http://en.wikipedia.org/wiki/Xubuntu" target="_blank">Xubuntu</a> which is a type of Ubuntu with <a title="Xfce" href="http://en.wikipedia.org/wiki/Xfce" target="_blank">Xfce</a> as its desktop environment.  Xfce is lightweight and fast.</p>
<p>Anyway, Ubuntu 9.04 Jaunty Jackalope works fine so far although I found some trivial problems such as the one described here.<br />
<a title="https://bugs.launchpad.net/gnome-app-install/+bug/354563/" href="https://bugs.launchpad.net/gnome-app-install/+bug/354563/" target="_blank"> https://bugs.launchpad.net/gnome-app-install/+bug/354563/</a></p>
<div class="txc-textbox" style="border: 3px solid rgb(243, 197, 52); padding: 10px; background-color: rgb(254, 254, 184);">
<i>This part is added on the 3rd of May, 2009</i><br />
WARNING: If you would like to install Ubuntu 9.04, you had better check out the Ubuntu 9.04 release notes especially the known issues part.<br />
<a href="http://www.ubuntu.com/getubuntu/releasenotes/904" target="_blank">http://www.ubuntu.com/getubuntu/releasenotes/904</a></p>
<p>※ Intel graphics card users should read carefully &#8216;Performance regressions on Intel graphics cards&#8217; and &#8216;Display freezes with Intel graphics cards&#8217; issues in the release notes.  You may also visit the link below to solve these problems with the Intel graphics cards but follow the post at your own risk.<br />
<a href="http://www.ubuntugeek.com/intel-graphics-performance-guide-for-ubuntu-904-jaunty-users.html" target="_blank">http://www.ubuntugeek.com/intel-graphics-performance-guide-for-ubuntu-904-jaunty-users.html</a>
</div>
<p>Compiz also seems to be a bit unstable yet hasn&#8217;t crashed.  I&#8217;m sure the Ubuntu development team will make it stable soon.  It normally becomes fairly stable one month after it is released.  In the meantime, the users can report all the bugs they found through the issue tracking system for Ubuntu that is <a title="Ubuntu in Launchpad" href="http://launchpad.net/ubuntu" target="_blank">Launchpad</a>.</p>
<p>So what I feel about the new release is that it seems to be more stable than the previous release (8.10). I&#8217;m quite satisfied so far.  The following information is a quick review of the new one.</p>
<p>* The problems in the previous version (8.10) yet fixed in the new version.<br />
-X-Window (probably only GNOME?) freezes if Ctrl+Alt+F1~F6 keys are pressed to enter console mode =&gt; Fixed in 9.04</p>
<p>-Firefox freezes with Google toolbar when opening more than one Firefox window. =&gt; Fixed in 9.04 (I&#8217;m not sure if it was fixed before but I had it when I used 8.04).</p>
<p>-The window decorator of some KDE applications using QT library (e.g. Umbrello, Kompare) disappears and it is impossible to resize the windows of these applications. As far as I remember, it only happens in 64bit version meaning 32bit version doesn&#8217;t have it. =&gt; Fixed in 9.04</p>
<p>-Using comma to separate cells in Open Office 3.0 Spread Sheet causes some error. The bug described here.<br />
<a title="https://bugs.launchpad.net/ubuntu/+source/openoffice.org/+bug/306602" href="https://bugs.launchpad.net/ubuntu/+source/openoffice.org/+bug/306602" target="_blank"> https://bugs.launchpad.net/ubuntu/+source/openoffice.org/+bug/306602</a><br />
=&gt; Fixed in 9.04. Ubuntu 8.10 doesn&#8217;t have Open Office 3.0 but 2.4. When I installed 3.0 through the repository the information about which is taken from the link blow, it had that problem.<br />
<a title="http://news.softpedia.com/news/How-To-Install-OpenOffice-org-3-0-in-Ubuntu-8-10-96449.shtml" href="http://news.softpedia.com/news/How-To-Install-OpenOffice-org-3-0-in-Ubuntu-8-10-96449.shtml" target="_blank"> http://news.softpedia.com/news/How-To-Install-OpenOffice-org-3-0-in-Ubuntu-8-10-96449.shtml</a></p>
<p>Oh I forgot to say that Ubuntu 9.04 has Open Office 3.0 pre-installed by the way. <img src='http://blog.lckymn.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>OK, these are what I found so far.</p>
<p>I&#8217;m using Compiz, GNOME Do, Cairo Dock and many other useful applications.  One good news is that Cairo Dock which is my favourite <a title="Dock (Computing)" href="http://en.wikipedia.org/wiki/Dock_(computing)" target="_blank">Dock application</a> can now be found from the Ubuntu repository which means all I need to do in order to install it is to use &#8216;Add/Remove Application&#8217; menu. <img src='http://blog.lckymn.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' />   I had to add the Cairo Dock repository manually before if I want to install it or even worse scenario is downloading the deb package file and install it manually.</p>
<p>A new file system namely ext4 which is faster than ext3 is available in Ubuntu 9.04. However, for now it might not be a good idea to use it as there may be some problem like this.<br />
<a title="https://bugs.edge.launchpad.net/ubuntu/+source/linux/+bug/317781?comments=all" href="https://bugs.edge.launchpad.net/ubuntu/+source/linux/+bug/317781?comments=all" target="_blank"> https://bugs.edge.launchpad.net/ubuntu/+source/linux/+bug/317781?comments=all</a><br />
It seems to be fixed though. Anyway, the comments in this bug report post are very interesting. <img src='http://blog.lckymn.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' />   This might be evidence of how Linux is being evolved by the developers as well as the users of it I believe. <img src='http://blog.lckymn.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lckymn.com/2009/04/27/my-desktop-in-april-2009/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
	</channel>
</rss>
