<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;D0AFQHg8cSp7ImA9WhRXFE0.&quot;"><id>tag:blogger.com,1999:blog-11200164</id><updated>2011-12-20T13:28:31.679-05:00</updated><category term="Python" /><category term="Performance" /><category term="Architecture" /><category term="Evars" /><category term="Hibernate" /><category term="AJAX" /><category term="String" /><category term="Parsing" /><category term="Pragmatic" /><category term="Beer" /><category term="Future" /><category term="Concurrency" /><category term="Programming" /><category term="Felix" /><category term="event sourcing" /><category term="Web Development" /><category term="Opinion" /><category term="Scala" /><category term="Community" /><category term="Collections" /><category term="TDD" /><category term="Server Side" /><category term="hardware" /><category term="Software Development" /><category term="URL" /><category term="UML" /><category term="XML" /><category term="Modeling" /><category term="Design" /><category term="Java VM" /><category term="Java" /><category term="Data Driven" /><category term="Null" /><category term="Extreme Programming" /><category term="Refactoring" /><category term="Open Source" /><category term="OPath" /><category term="Competition" /><category term="Loud Thinking" /><category term="PyConsole" /><category term="Linux" /><category term="Eclipse" /><category term="How-to" /><category term="Debug" /><category term="Tooling" /><category term="Frustrations" /><category term="Non-tech" /><category term="Patterns" /><category term="blogging" /><category term="Ant" /><category term="Gargbage Collection" /><category term="Optimization" /><title>Nirav's Contemplations</title><subtitle type="html">Thoughts on Programming, Software and Open Source.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://blog.nirav.name/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://blog.nirav.name/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Nirav Thaker</name><uri>http://www.blogger.com/profile/07204297663478577248</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_PebfjbIpLKY/SYO5wL9XgUI/AAAAAAAAByY/MhgUWfUq5Hc/S220/DSCN1212+-+Copy.JPG" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>80</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/blogspot/nirav" /><feedburner:info uri="blogspot/nirav" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><link rel="license" type="text/html" href="http://creativecommons.org/licenses/by-sa/2.0/" /><logo>http://creativecommons.org/images/public/somerights20.gif</logo><xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" /><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2Fblogspot%2Fnirav" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fblogspot%2Fnirav" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.feedburner.com%2Fblogspot%2Fnirav" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.feedburner.com/blogspot/nirav" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fblogspot%2Fnirav" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fblogspot%2Fnirav" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fblogspot%2Fnirav" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><entry gd:etag="W/&quot;D0cGRXg8fSp7ImA9WhRQEUk.&quot;"><id>tag:blogger.com,1999:blog-11200164.post-9184760994063214505</id><published>2011-12-05T22:58:00.001-05:00</published><updated>2011-12-05T23:17:04.675-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-05T23:17:04.675-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="Collections" /><category scheme="http://www.blogger.com/atom/ns#" term="URL" /><category scheme="http://www.blogger.com/atom/ns#" term="Performance" /><title>Avoid storing references of java.net.URL</title><content type="html">Normally, I avoid writing something so obvious but since I'm bitten multiple times now, it might help future me.&lt;br /&gt;
&lt;br /&gt;
Never&lt;b&gt; ever store&lt;/b&gt; references of java.net.URL in Java collections. The reasoning is pretty simple, 'equals' and 'hashCode' methods of this class does extremely expensive synchronous DNS lookup on &lt;b&gt;every&lt;/b&gt; call.&lt;br /&gt;
&lt;br /&gt;
It is not uncommon to see most of your thread's time being spent on monitors:&lt;br /&gt;
&lt;br /&gt;
"pool-2-thread-2" prio=10 tid=0x92061400 nid=0x1744 waiting for monitor entry [0x91fad000]&lt;br /&gt;
&amp;nbsp;&amp;nbsp; java.lang.Thread.State: BLOCKED (on object monitor)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; at java.net.URLStreamHandler.getHostAddress(URLStreamHandler.java:429)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; - waiting to lock &amp;lt;0x9731b200&amp;gt; (a sun.net.www.protocol.http.Handler)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; at java.net.URLStreamHandler.hashCode(URLStreamHandler.java:354)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; at java.net.URL.hashCode(URL.java:875)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; - locked &amp;lt;0xaac87290&amp;gt; (a java.net.URL)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; at java.util.HashMap.getEntry(HashMap.java:361)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; at java.util.HashMap.containsKey(HashMap.java:352)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; at java.util.HashSet.contains(HashSet.java:201)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
"pool-2-thread-1" prio=10 tid=0x9205e800 nid=0x1743 runnable [0x91ffe000]&lt;br /&gt;
&amp;nbsp;&amp;nbsp; java.lang.Thread.State: RUNNABLE&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; at java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; at java.net.InetAddress$1.lookupAllHostAddr(InetAddress.java:866)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; at java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1258)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; at java.net.InetAddress.getAllByName0(InetAddress.java:1211)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; at java.net.InetAddress.getAllByName(InetAddress.java:1127)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; at java.net.InetAddress.getAllByName(InetAddress.java:1063)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; at java.net.InetAddress.getByName(InetAddress.java:1013)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; at java.net.URLStreamHandler.getHostAddress(URLStreamHandler.java:437)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; - locked &amp;lt;0x9731b200&amp;gt; (a sun.net.www.protocol.http.Handler)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; at java.net.URLStreamHandler.hashCode(URLStreamHandler.java:354)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; at java.net.URL.hashCode(URL.java:875)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; - locked &amp;lt;0xaac97228&amp;gt; (a java.net.URL)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; at java.util.HashMap.getEntry(HashMap.java:361)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; at java.util.HashMap.containsKey(HashMap.java:352)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; at java.util.HashSet.contains(HashSet.java:201)&lt;br /&gt;
&lt;br /&gt;
This stack-trace just depicts hashCode but expect similar blocking code for 'equals' too. If you care a bit about performance, just stay away from this goddamned class.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11200164-9184760994063214505?l=blog.nirav.name' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=PZ63DSBFiYM:_j1dFotyLxQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=PZ63DSBFiYM:_j1dFotyLxQ:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=PZ63DSBFiYM:_j1dFotyLxQ:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=PZ63DSBFiYM:_j1dFotyLxQ:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=PZ63DSBFiYM:_j1dFotyLxQ:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=PZ63DSBFiYM:_j1dFotyLxQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/nirav/~4/PZ63DSBFiYM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nirav.name/feeds/9184760994063214505/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=11200164&amp;postID=9184760994063214505" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/9184760994063214505?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/9184760994063214505?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/nirav/~3/PZ63DSBFiYM/avoid-storing-references-of-javaneturl.html" title="Avoid storing references of java.net.URL" /><author><name>Nirav Thaker</name><uri>http://www.blogger.com/profile/07204297663478577248</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_PebfjbIpLKY/SYO5wL9XgUI/AAAAAAAAByY/MhgUWfUq5Hc/S220/DSCN1212+-+Copy.JPG" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.nirav.name/2011/12/avoid-storing-references-of-javaneturl.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEAHSXo-cSp7ImA9WhRREUQ.&quot;"><id>tag:blogger.com,1999:blog-11200164.post-6296665226041810473</id><published>2011-11-24T21:25:00.001-05:00</published><updated>2011-11-24T23:52:18.459-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-11-24T23:52:18.459-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java VM" /><category scheme="http://www.blogger.com/atom/ns#" term="String" /><category scheme="http://www.blogger.com/atom/ns#" term="Performance" /><category scheme="http://www.blogger.com/atom/ns#" term="Optimization" /><title>Optimizing string memory footprint in Java - Part 1</title><content type="html">This is first in a series of blog posts where I will try to describe my miserable attempts at storing large amount of strings to build efficient spell correction and auto-suggest facility in Java. I learned some important lessons doing this and it will be a waste if I didn't share it. So here it goes..&lt;br /&gt;
&lt;br /&gt;
In order to efficiently store large amount of strings, we first need to understand how JVM stores string objects in memory. In this post I will try to summarize memory layout of String object.&lt;br /&gt;
&lt;br /&gt;
Each object in JVM has fixed, unavoidable structural overhead called object header that JVM uses for various tasks such as Garbage Collection, Identification, addressing and others that I don't understand. A 32-bit HotSpot VM uses 8 bytes header per object, 64-bit HotSpot VM &lt;a href="http://docs.oracle.com/javase/7/docs/technotes/guides/vm/performance-enhancements-7.html" target="_blank"&gt;with heap larger than 32g&lt;/a&gt; as well as &lt;a href="http://www.ibm.com/developerworks/java/jdk/" target="_blank"&gt;IBM's J9&lt;/a&gt; VM takes 16 bytes per object. As always, arrays are treated differently. &lt;a href="http://java.sun.com/docs/books/jvms/second_edition/html/Compiling.doc.html#4091" target="_blank"&gt;Array&lt;/a&gt; is an object so it has a fixed header of its own as described above. However, since Java spec guarantees array bounds check on &lt;a href="http://java.sun.com/docs/books/jvms/second_edition/html/VMSpecIX.fm1.html#6956334" target="_blank"&gt;every array operation&lt;/a&gt; it has to store length of each array which is another 4 byte, making effective array header size 12 bytes instead of regular 8 for objects. And finally there's object padding in multiples of 8 or 16 bytes, depending on CPU word size and JVM to make memory to CPU communication efficient.&lt;br /&gt;
&lt;br /&gt;
Assuming 32-bit JVM, the &lt;a href="http://docs.oracle.com/javase/7/docs/api/java/lang/String.html" target="_blank"&gt;java.lang.String&lt;/a&gt; class has three bookkeeping integer fields called offset, count, hash occupying 12 bytes plus a 4 byte char array pointer and 8 byte header totaling 24 bytes fixed overhead per string. This is inefficient but slightly clever because padding is not required for string object itself making hash a free cache.&lt;br /&gt;
&lt;br /&gt;
Here's the formula to calculate String's shallow and deep sizes: &lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Shallow size = HEADER + ( offset + count + hash + char array pointer) = 24 bytes&lt;/li&gt;
&lt;li&gt;Retained size = Shallow size + 12 byte array header + (nchars * 2 + PAD)&lt;/li&gt;
&lt;/ul&gt;
Where PAD = ((nchars * 2) mod 8 or 16) is padding rounded off to 8/16 bytes if array elements' size is not multiple of 8/16.&lt;br /&gt;
&lt;br /&gt;
So, on a 32-bit HotSpot VM, 6 byte word "Memory" takes :&lt;br /&gt;
24 + 12 + (6 * 2 + 4 PAD) = 24 + 12 + 16 = 52 bytes&lt;br /&gt;
&lt;br /&gt;
That is 77% JVM imposed overhead v/s 23% actual data considering it a unicode string.&lt;br /&gt;
&lt;br /&gt;
One way to make string representations efficient is to amortize structural overhead by storing larger strings. To illustrate, 100 char string will be 80% data v/s 20% overhead, 200 char string will be 94.33% data v/s overhead, 500 char string will be 97.6% data v/s overhead and so on. This will be one of the key technique in reducing string's memory footprint I will write about in later blog posts. Following is a rough graph that depicts this theory.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-HsTLMWT61DM/Ts8cm_M3AcI/AAAAAAAACMg/Hh4fgUAMQfc/s1600/Efficiency+increase+with+Characters+per+string.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://1.bp.blogspot.com/-HsTLMWT61DM/Ts8cm_M3AcI/AAAAAAAACMg/Hh4fgUAMQfc/s320/Efficiency+increase+with+Characters+per+string.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
It is easy to see that storing a lot of small strings actually waste huge amount of memory which in no less part the reason why Java is considered a memory hog.&lt;br /&gt;
&lt;br /&gt;
That's all with the basics of understanding overhead involved with storing strings. In next blog post, I will write about various implementations I tried and general rant on Java Collections' memory efficiency.&lt;br /&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11200164-6296665226041810473?l=blog.nirav.name' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=hzFZNO3jVyE:QtsBzhB9qzY:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=hzFZNO3jVyE:QtsBzhB9qzY:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=hzFZNO3jVyE:QtsBzhB9qzY:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=hzFZNO3jVyE:QtsBzhB9qzY:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=hzFZNO3jVyE:QtsBzhB9qzY:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=hzFZNO3jVyE:QtsBzhB9qzY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/nirav/~4/hzFZNO3jVyE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nirav.name/feeds/6296665226041810473/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=11200164&amp;postID=6296665226041810473" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/6296665226041810473?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/6296665226041810473?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/nirav/~3/hzFZNO3jVyE/optimizing-string-memory-footprint-in.html" title="Optimizing string memory footprint in Java - Part 1" /><author><name>Nirav Thaker</name><uri>http://www.blogger.com/profile/07204297663478577248</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_PebfjbIpLKY/SYO5wL9XgUI/AAAAAAAAByY/MhgUWfUq5Hc/S220/DSCN1212+-+Copy.JPG" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-HsTLMWT61DM/Ts8cm_M3AcI/AAAAAAAACMg/Hh4fgUAMQfc/s72-c/Efficiency+increase+with+Characters+per+string.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.nirav.name/2011/11/optimizing-string-memory-footprint-in.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkIMQnc6eyp7ImA9WhRTEUQ.&quot;"><id>tag:blogger.com,1999:blog-11200164.post-6963599670411074385</id><published>2011-10-24T22:25:00.001-04:00</published><updated>2011-11-01T20:43:03.913-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-11-01T20:43:03.913-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Gargbage Collection" /><category scheme="http://www.blogger.com/atom/ns#" term="Java VM" /><category scheme="http://www.blogger.com/atom/ns#" term="Performance" /><category scheme="http://www.blogger.com/atom/ns#" term="Opinion" /><title>On using "PermGen" as application level cache</title><content type="html">I was reading an interesting article '&lt;a href="http://marcgravell.blogspot.com/2011/10/assault-by-gc.html"&gt;Assualt by GC&lt;/a&gt;' by &lt;a href="http://stackexchange.com/"&gt;stack exchange&lt;/a&gt; guy and it felt like a&amp;nbsp;Déjà vu with my past couple of years of development on the JVM. It struck to me that we can definitely do better, so here it goes..&lt;br /&gt;
&lt;br /&gt;
Automatic &lt;a href="http://en.wikipedia.org/wiki/Garbage_collection_(computer_science)"&gt;GC&lt;/a&gt; is really a great step forward in software development, except when it is not. If you have deployed application on a JVM with large heap (4g+) you probably know what a long GC pause really feels like [insert familiar knock-knock joke about java]. Jokes aside, JVM's GC advancement is unprecedented. The amount of tuning you can do with different garbage collectors can define a niche profession.&lt;br /&gt;
&lt;br /&gt;
For most applications where GC latency isn't an issue; default garbage collector works just fine. For applications which need to scale GC can (and does) become a 'bottleneck'. If you disagree, try running a JVM under memory pressure and see app response times. It should be surprising because in most data driven applications bottleneck is usually IO or other IO bound resources (e.g. a DB). This situation generally happens when GC is completely thrashing the process because there are too many "tenured" objects which don't fit in the allocated heap or heap is fragmented and GC wastes a lot of time compacting the heap. Unlike .NET, Java folks are not very lucky with platform specific optimizations such as locking pages to prevent swapping. So it is not uncommon that a full GC causes excessive paging, making GC IO bound.&lt;br /&gt;
&lt;br /&gt;
Turns out that GCing large "tenured" object space is expensive compared to short lived young objects (sweep). A large population of "tenured" objects is generally a genuine requirement for long running server processes relying on large amounts of data and this requirement&amp;nbsp;shouldn't&amp;nbsp;really punish application with long GC pauses. While not impossible, it is not really practical to set size of tenured generation very large because it may adversely affect young generation collections. JVM GC optimization is a skill not in&amp;nbsp;abundance but the problem is all too common. So what can we do about it?&lt;br /&gt;
&lt;br /&gt;
One way to eliminate GC on predictable "tenured" application data is to just not store it on JVM heap (i.e. use &lt;a href="http://download.oracle.com/javase/7/docs/api/java/nio/ByteBuffer.html#allocateDirect(int)"&gt;direct byte buffer&lt;/a&gt; etc. ). I've been watching solutions like Terracotta's &lt;a href="http://www.terracotta.org/bigmemory"&gt;BigMemory&lt;/a&gt; which uses similar approach to address GC issues. However all such solutions seem a mix of &amp;nbsp;manual memory management with hacks to&amp;nbsp;circumvent GC which end up being half-baked reinvention of JVM's copy-on-write "permgen".&lt;br /&gt;
&lt;br /&gt;
Most of the java developers I know consider "permgen" to be some kind of evil which causes all kinds of problems including "eclipse crashing", crying JSP/[insert other template library] compiler, unpredictable class unloading and really large interned strings which stick around. "permgen" is &lt;a href="http://javaeesupportpatterns.blogspot.com/2011/10/java-7-features-permgen-removal.html"&gt;going&lt;/a&gt; to &lt;a href="http://hg.openjdk.java.net/jdk7/hotspot/hotspot/rev/3582bf76420e"&gt;go away&lt;/a&gt; from the hotspot vm, which is kind of sad because I think it could be a great way to achieve GC free heap storage for application level data (more specifically cache). This is not really possible unless "permgen" is used for one specific purpose, and if that specific purpose allows application to store its data, we can have standard supported GC free application data without the need of third party solutions which achieve the goal poorly. Even better would be &lt;a href="http://jcp.org/en/jsr/detail?id=107"&gt;java.cache&lt;/a&gt; using "permgen" for cache storage.&lt;br /&gt;
&lt;br /&gt;
One of the &lt;a href="http://news.ycombinator.com/item?id=3150407"&gt;commenter &lt;/a&gt;at HN talked about Smalltalk VM's way of using permgen (just send a message to &amp;nbsp;object to move itself to "permgen"). I like this approach because applications can control which objects are long lived which is sensible because they have the best knowledge about long lived objects. The only&amp;nbsp;similarity&amp;nbsp;in JVM we have is &lt;a href="http://download.oracle.com/javase/7/docs/api/java/lang/String.html#intern()"&gt;String.intern&lt;/a&gt;, which unfortunately caches strings forever and it is not really as useful as having&amp;nbsp;some kind&amp;nbsp;of eviction control.&lt;br /&gt;
&lt;br /&gt;
So, what do you think about this approach?&lt;br /&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11200164-6963599670411074385?l=blog.nirav.name' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=Gf1HgV02tRU:W_OpCe8mIJo:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=Gf1HgV02tRU:W_OpCe8mIJo:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=Gf1HgV02tRU:W_OpCe8mIJo:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=Gf1HgV02tRU:W_OpCe8mIJo:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=Gf1HgV02tRU:W_OpCe8mIJo:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=Gf1HgV02tRU:W_OpCe8mIJo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/nirav/~4/Gf1HgV02tRU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nirav.name/feeds/6963599670411074385/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=11200164&amp;postID=6963599670411074385" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/6963599670411074385?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/6963599670411074385?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/nirav/~3/Gf1HgV02tRU/using-permgen-for-application-level.html" title="On using &quot;PermGen&quot; as application level cache" /><author><name>Nirav Thaker</name><uri>http://www.blogger.com/profile/07204297663478577248</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_PebfjbIpLKY/SYO5wL9XgUI/AAAAAAAAByY/MhgUWfUq5Hc/S220/DSCN1212+-+Copy.JPG" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.nirav.name/2011/10/using-permgen-for-application-level.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D04BR3k-fyp7ImA9WhdWE0s.&quot;"><id>tag:blogger.com,1999:blog-11200164.post-5408345293892214814</id><published>2011-09-06T23:24:00.000-04:00</published><updated>2011-09-06T23:25:56.757-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-06T23:25:56.757-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Data Driven" /><category scheme="http://www.blogger.com/atom/ns#" term="event sourcing" /><category scheme="http://www.blogger.com/atom/ns#" term="Design" /><category scheme="http://www.blogger.com/atom/ns#" term="Opinion" /><title>Thoughts on Event sourcing</title><content type="html">I read about &lt;a href="http://martinfowler.com/eaaDev/EventSourcing.html"&gt;event sourcing&lt;/a&gt; a while back and I couldn't stop thinking about it so it had to explode here as a blog post.&lt;br /&gt;
&lt;br /&gt;
A typical data driven application involves &lt;a href="http://en.wikipedia.org/wiki/Create,_read,_update_and_delete"&gt;CRUD&lt;/a&gt; operations on domain entities which are important to business. Such application typically capture data from user or other system in a centralized database for reporting or for further distribution. Architecture of such application is generally simple and there's a vast 
ecosystem of platforms, frameworks, tools and libraries to support it.&lt;br /&gt;
&lt;br /&gt;
If we wanted to represent traditional design of such application in terms of a &lt;a href="http://en.wikipedia.org/wiki/Finite-state_machine"&gt;state machine&lt;/a&gt;, then we can say that such application capture, distribute and allow reporting of domain in a &lt;b&gt;certain state&lt;/b&gt;. The primary objective of such application is to facilitate data manipulation (CRUD) which changes state of the domain. For most applications it is generally a sound design ignoring familiar caveats.&lt;br /&gt;
&lt;br /&gt;
Thinking in terms of state machines, there's an interesting alternative: we can store all the &lt;b&gt;state transitions&lt;/b&gt; that led initial domain model to its current state. This second perspective to application design has many interesting repercussions. In this approach, current state of domain is no longer as important as the earlier approach because it can be recreated just by repeating all the transitions. This second approach is named "&lt;b&gt;Event sourcing&lt;/b&gt;" where event is just a little familiar name for state transition.&lt;br /&gt;
&lt;br /&gt;
Not every application care about the easy recreatibility aspect of domain, most business applications care only about current state of domain. However many applications, especially the ones with mandated audit trails or domain with significant historical data, can benefit from event sourcing. A common example of such application is a version control system, version control systems capture state transitions (diffs) of domain entities (source files) so you can switch to any state (version) and rebuild it to desired state by successive applications of&amp;nbsp; state transitions (diffs).&lt;br /&gt;
&lt;br /&gt;
As far as business domains goes, &lt;b&gt;Insurance domain&lt;/b&gt; by far seems to be a great area of application for event sourcing given that audit trail is a legal compliance requirement and insurance domain models tend to be really complex. Think of an insurance policy as a state and all the changes to it (endorsements) as transitions. By just tracking the transitions, one can rebuild a policy to its current state and reason about it for underwriting analysis and audit. Compare it, instead, with our initial approach of capturing multiple states (identical records in relational database) with complex logic to diff them and comparing them. This approach has profound positive implication on usability of application as well as testability, with this approach it is easy to visualize and rebuild data of interest to any point in time.&lt;br /&gt;
&lt;br /&gt;
One more interesting application of event sourcing, I think, is in data mining. If data is stored as events it is fairly easy to sample, plot and build historical and predictive models. My limited experience in mining data has always involved custom (expensive) efforts to store historical data, such custom efforts usually involve complex development efforts just to extract marginally meaningful information.&lt;br /&gt;
&lt;br /&gt;
It shouldn't be surprising that event sourcing can have significant influence on application architecture which may not be an easy sell especially in a larger setting. There are many related concepts to event sourcing, specifically &lt;a href="http://cqrsinfo.com/"&gt;CQRS&lt;/a&gt; which lead to wild architectures (which I'm not quite fond of yet). &lt;br /&gt;
&lt;br /&gt;
I'm learning this is not new or revolutionary and has been done in past but never caught up for whatever reasons, nonetheless I find it interesting. As far as my technical curiosities go I'm very much inclined to try it 
out with a pet project to see how far these benefits are viable. &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11200164-5408345293892214814?l=blog.nirav.name' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=NdGmVlWyqIY:dRvz_XxdiYg:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=NdGmVlWyqIY:dRvz_XxdiYg:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=NdGmVlWyqIY:dRvz_XxdiYg:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=NdGmVlWyqIY:dRvz_XxdiYg:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=NdGmVlWyqIY:dRvz_XxdiYg:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=NdGmVlWyqIY:dRvz_XxdiYg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/nirav/~4/NdGmVlWyqIY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nirav.name/feeds/5408345293892214814/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=11200164&amp;postID=5408345293892214814" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/5408345293892214814?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/5408345293892214814?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/nirav/~3/NdGmVlWyqIY/thoughts-on-event-sourcing.html" title="Thoughts on Event sourcing" /><author><name>Nirav Thaker</name><uri>http://www.blogger.com/profile/07204297663478577248</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_PebfjbIpLKY/SYO5wL9XgUI/AAAAAAAAByY/MhgUWfUq5Hc/S220/DSCN1212+-+Copy.JPG" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.nirav.name/2011/09/thoughts-on-event-sourcing.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0UBRXwzcCp7ImA9Wx9aFk4.&quot;"><id>tag:blogger.com,1999:blog-11200164.post-181016459060919936</id><published>2011-03-07T22:17:00.007-05:00</published><updated>2011-03-08T19:40:54.288-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-08T19:40:54.288-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Concurrency" /><category scheme="http://www.blogger.com/atom/ns#" term="Loud Thinking" /><title>Why Concurrency is hard</title><content type="html">Concurrency is hard because we haven't figure out how to make it easy. For most developers, specifically&amp;nbsp;web developers,&amp;nbsp;concurrency doesn't really matter. I envy that&amp;nbsp;assuasive&amp;nbsp;confident feeling of a sequential execution of http requests. The number of cores on my machine quadrupled in last three years and I don't know a single reliable, comforting (easy) way of harnessing it as much as possible, I feel a little sad about current state of concurrency support.&lt;br /&gt;
&lt;br /&gt;
Utilizing all the processing power consistently is a lot easier for well defined and not so concurrent tasks such as map-reduce. I have done it a lot, processing gigabytes of data by reducing the problem to independent subsets is&amp;nbsp;programmatic&amp;nbsp;triviality. On the other hand, I have always found developing a relatively concurrent application the "right way" to be a nightmare. Concurrency applications come in two mutually exclusive&amp;nbsp;flavours: slow or complex.&lt;br /&gt;
&lt;br /&gt;
At this point enthusiasts will point out &lt;a href="http://download.oracle.com/javase/6/docs/api/java/util/concurrent/package-summary.html"&gt;java.util.concurrent&lt;/a&gt; and move on. While j.u.concurrent is nice and a significant improvement over explicit synchronization, it still mandates that API users be concurrency wizards and its complexity exposure is nearly at par with explicit&amp;nbsp;synchronization. Here's one example&amp;nbsp;&lt;a href="http://dmy999.com/article/34/correct-use-of-concurrenthashmap"&gt;blog post&lt;/a&gt;&amp;nbsp;explaining common gotcha with &lt;a href="http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ConcurrentHashMap.html#put(K, V)"&gt;ConcurrentHashMap&lt;/a&gt;. The only benefit j.u.concurrency provides is finer grained control over where to do &lt;a href="http://en.wikipedia.org/wiki/Compare-and-swap"&gt;CAS&lt;/a&gt;. I am a huge fan of j.u.concurrent and have been using it pre-1.5 but I still don't think it makes concurrency so easy. For one more example,&lt;br /&gt;
&lt;br /&gt;
synchronized(this){ aRef = newVal;&amp;nbsp;&amp;nbsp;return aRef;}&lt;br /&gt;
&lt;br /&gt;
v/s&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;while (true) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;V x = atomicRef.get();&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (atomicRef.compareAndSet(x, newValue))&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return atomicRef.get();&lt;br /&gt;
&amp;nbsp;}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Which one do you think is easier to grasp?&lt;br /&gt;
&lt;br /&gt;
Many people think that &lt;a href="http://en.wikipedia.org/wiki/Actor_model"&gt;Actors&lt;/a&gt;&amp;nbsp;are the next big thing to tackle concurrency monster and complexities introduced by these shared memory model primitives. I too initially &lt;a href="http://blog.nirav.name/2009/04/forkjoin-concurrency-with-scala-actors.html"&gt;thought so&lt;/a&gt;, but then I found that Actor model isn't really the sweet spot in practice as it is touted. The very notion that Actors can fail and code must handle the tricky bits to recover from it makes it even more complex than using locks/mutexes etc. I am in constant a awe to see people talking so lightly about &amp;nbsp;fault tolerant/fail safe systems without giving thought on the amount of complexity it adds. I am not necessarily protesting that philosophy but that behaviour is just not common in yer average regular applications (will your user be happy if one actor failed to process her payment and was asked to retry?). We still live in dark ages of transparent concurrency.&lt;br /&gt;
&lt;br /&gt;
I remain as ignorant and&amp;nbsp;unsatisfied&amp;nbsp;about concurrency support as I was several years ago. For me, concurrency is hard so I am off to shopping!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11200164-181016459060919936?l=blog.nirav.name' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=B3ICP2KiH6s:R7y4GuyhUaM:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=B3ICP2KiH6s:R7y4GuyhUaM:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=B3ICP2KiH6s:R7y4GuyhUaM:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=B3ICP2KiH6s:R7y4GuyhUaM:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=B3ICP2KiH6s:R7y4GuyhUaM:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=B3ICP2KiH6s:R7y4GuyhUaM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/nirav/~4/B3ICP2KiH6s" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nirav.name/feeds/181016459060919936/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=11200164&amp;postID=181016459060919936" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/181016459060919936?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/181016459060919936?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/nirav/~3/B3ICP2KiH6s/why-concurrency-is-hard.html" title="Why Concurrency is hard" /><author><name>Nirav Thaker</name><uri>http://www.blogger.com/profile/07204297663478577248</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_PebfjbIpLKY/SYO5wL9XgUI/AAAAAAAAByY/MhgUWfUq5Hc/S220/DSCN1212+-+Copy.JPG" /></author><thr:total>5</thr:total><feedburner:origLink>http://blog.nirav.name/2011/03/why-concurrency-is-hard.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkACRH05eCp7ImA9Wx9WGUw.&quot;"><id>tag:blogger.com,1999:blog-11200164.post-4261005533582558812</id><published>2010-12-13T22:49:00.001-05:00</published><updated>2011-01-24T18:12:45.320-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-24T18:12:45.320-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Scala" /><category scheme="http://www.blogger.com/atom/ns#" term="Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="Null" /><title>Tackling nulls the functional way</title><content type="html">Most programmers have suffered null pointer one way or other - usually a core-dump followed by a segmentation fault on development machine or on a production box with application in smokes. NullPointerException results in a visible embarrassment of not thinking about "that something *could be* null".&lt;br /&gt;
&lt;br /&gt;
Tracking Null Pointer ranges from loading core-dump in gdb and tracing dereferenced pointer to stack traces pointing to exact location in source. However, ease of tracking nulls opens up the doors to ignore them in practice and throwing null-checks just becomes as common as throwing one more div to fix IE's layout problems which is bad.&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: large;"&gt;&lt;b&gt;Problems with Null:&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
I hate having to ignore nulls as it is not always enough just to add one more null check. The reason why I am writing this blog is because I have several problems with Nulls:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;All and Every reference can be a null in languages like Java. This covers everything: method parameters, return values, fields etc. There's no precise way for a programmer to know that some method might return null or accept null parameters. You absolutely have to resort to actual source code or&amp;nbsp;documentation&amp;nbsp;to see if it can possibly return null (and you are going to need good luck with that). All of it adds extra work when you really want to be focusing on fixing the real problem.&lt;/li&gt;
&lt;li&gt;The problem with NullPointerException is that they point to causal eventuality and not usually the actual cause. So what you see in stack traces are usually the code paths where damage is not really initiated but done when we are normally interested in case where damage is initiated.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Null is actually very&amp;nbsp;ambiguous. Is it the uninitialized value or&amp;nbsp;absence&amp;nbsp;of value or is it used to indicate an error? The paradigm of null fits well in database but not in programming model.&lt;/li&gt;
&lt;li&gt;Having Nulls in your code has major implications in code quality and complexity. For example, it is not unusual to see code branches with null checks breeding like rabbits when an API "may" return null which in turn results in extremely defensive code. This significantly taxes readability.&lt;/li&gt;
&lt;li&gt;Null makes Java's type system dumber when a method is&amp;nbsp;overridden and you want to call it. Writing code like methodDoingStuff((ActualType)null, otherArgs) isn't exactly a pretty sight. This results in subtle errors when arguments are non-generic.&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;In many ways Nulls are necessary evil. For those of us who care about readability and safety we can't ignore them yet we shouldn't just let it overtake safety and readability.&lt;br /&gt;
&lt;br /&gt;
I have come to know several techniques to tackle nulls. First, there is&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Null_Object_pattern"&gt;Null Object pattern&lt;/a&gt;&amp;nbsp;which is not entirely as ridiculous as the name implies but it's not practical in real life software having hundreds of class hierarchies and thousands of classes, and so, I will not talk about it. Then there are languages like Haskell and Scala with library classes that try to treat nulls in, IMO, a better way. Haskell has &lt;a href="http://www.haskell.org/ghc/docs/6.12.2/html/libraries/base-4.2.0.1/Data-Maybe.html"&gt;MayBe&lt;/a&gt; and Scala has &lt;a href="http://www.scala-lang.org/api/current/scala/Option.html"&gt;Options&lt;/a&gt;. After using options in Scala for a while in a &lt;a href="https://github.com/niravthaker/slibpst"&gt;side project&lt;/a&gt;, I found that I was no longer fighting with nulls. I knew exactly when I had to make a decision that a value is really optional and I must do alternate processing.&lt;br /&gt;
&lt;br /&gt;
The central idea behind Haskell's MayBe and Scala's Option is to introduce a definitive agreement on a value's eligibility to be either null or not-null&amp;nbsp;enforced&amp;nbsp;with the help of type system. I will talk about Scala's Option since I have worked with it, but the concept remains same. I will also introduce how to implement and use Options in Java since this is much more of a functional way of thinking about handling nulls and it doesn't (almost) take Scala's neat language features to implement it.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Treating nulls the better way:&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;Usual course of action when you are not sure what value to return from a method is:&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;script src="https://gist.github.com/737060.js?file=NullDefence.java"&gt;
&lt;/script&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;Most of the times it results in the last option because you don't have to fear about breaking everything (well, mostly) and everyone passes the buck like this.&lt;/div&gt;&lt;br /&gt;
We can do better with Scala's Option classes. We can wrap any reference in to Some or None and handle it with pattern matching or "for comprehension". For example:&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/737084.js?file=ScalaOptionExample.scala"&gt;
&lt;/script&gt;&lt;br /&gt;
Some(x) represents a wrapper with x as actual value; None represents&amp;nbsp;absence&amp;nbsp;of value. Some and None are subclasses of Option. Option has &lt;a href="https://lampsvn.epfl.ch/trac/scala/browser/scala/tags/R_2_8_1_final/src//library/scala/Option.scala#L1"&gt;all the interesting methods&lt;/a&gt;&amp;nbsp;you can use. When a variable in question is null we can: &amp;nbsp;fall back to default value, evaluate and return a function's computed value, filter and so on.&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: large;"&gt;&lt;b&gt;Options in Java:&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
Implementing Options in Java is surprisingly a trivial task. However,&amp;nbsp;it is&amp;nbsp;not as pleasant as Scala's options. Implementation boils down to a wrapper class Option with two children: Some and None. None represents a null but with a type (None[T]) and Some represents non-null type.&lt;br /&gt;
&lt;br /&gt;
To make Option interesting we make Option extend List, so we can iterate on it to mimic poor man's "for comprehension". We will also go as far as tagging both types with Enums so we can do poor man's pattern matching with a switch. You can find &lt;a href="https://github.com/niravthaker/common-utils/tree/master/src/name/nirav/common/utils/monads"&gt;example implementation of Options&lt;/a&gt;&amp;nbsp;in Java with a test case &lt;a href="https://github.com/niravthaker/common-utils/blob/master/test/name/nirav/common/utils/OptionsTest.java"&gt;demonstrating use of Options&lt;/a&gt;. Here's the small snippet which covers the essense:&lt;br /&gt;
&lt;script src="https://gist.github.com/739905.js?file=OptionsInJava.java"&gt;
&lt;/script&gt;&lt;br /&gt;
As you can see, Option opens up several doors to fix the null situation. You now have &amp;nbsp;choice to compute a value, use default value or do arbitrary stuff when you encounter nulls.&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: large;"&gt;&lt;b&gt;How are my null problem solved with Options:&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Using Options for optional/null-able references I have at least avoided "all things could be null" problem in my code. When an API is returning a Option,&lt;t&gt; I don't have to wonder if it can return null. Intention is pretty clear.&lt;/t&gt;&lt;/li&gt;
&lt;li&gt;When I am forced to handle null right at the time of using an API, I have to handle it right there: do alternate processing or use default. No surprises.&lt;/li&gt;
&lt;li&gt;Option is a very clear way of saying a variable represents possibly an absent value.&lt;/li&gt;
&lt;li&gt;Option doesn't really solve this problem completely. For example, method signatures with wrapper Option type can get really long (e.g. def method1(): Map[String, Option[List[Option[String]]] = {}). However, compared to null checks, I would prefer long method signature&amp;nbsp;any day. Other benefits out-weight this limitation.&lt;/li&gt;
&lt;li&gt;Clearly, Option[Integer] always means only Option[Integer] and not Option[Integer], Option[String], Option[Character], Option[Date] and so on. Compiler can infer exact method call from generic types.&lt;/li&gt;
&lt;/ol&gt;&lt;div&gt;As good as the concept behind optional values is, it doesn't and will not always save you from Null. You will still have to deal with existing libraries which return nulls and cause all these problems and more. However, most of the time null is problematic in your own code.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;&lt;b&gt;Where to use Options:&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;Here are the common places where I think using Options makes more sense:&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;APIs: Make your API as specific and as readable as possible; all optional parameters and return values should be Option&lt;t&gt;.&lt;/t&gt;&lt;/li&gt;
&lt;li&gt;Use in your domain model: You already have fair understanding on null-able columns, use Option&lt;t&gt; for null-able fields in your table. It is not hard to integrate using Options if you are using an ORM with interceptable DB fetch; you can initialize fields to None&lt;t&gt; if database contains null and so on.&lt;/t&gt;&lt;/t&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;In the interest of keeping this post relevant and on topic, I have completely avoided heavy theoretical baggage (monads et. al.) that's inevitable when theoretical functionalists (functional programmers) talk about Options. I really hope this post generates some interest in this topic. If you disagree or would like to share more on this topic, please leave a comment.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11200164-4261005533582558812?l=blog.nirav.name' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=wAOixV7X6Rs:086SNkcgr6k:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=wAOixV7X6Rs:086SNkcgr6k:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=wAOixV7X6Rs:086SNkcgr6k:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=wAOixV7X6Rs:086SNkcgr6k:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=wAOixV7X6Rs:086SNkcgr6k:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=wAOixV7X6Rs:086SNkcgr6k:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/nirav/~4/wAOixV7X6Rs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nirav.name/feeds/4261005533582558812/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=11200164&amp;postID=4261005533582558812" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/4261005533582558812?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/4261005533582558812?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/nirav/~3/wAOixV7X6Rs/tackling-nulls-functional-way.html" title="Tackling nulls the functional way" /><author><name>Nirav Thaker</name><uri>http://www.blogger.com/profile/07204297663478577248</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_PebfjbIpLKY/SYO5wL9XgUI/AAAAAAAAByY/MhgUWfUq5Hc/S220/DSCN1212+-+Copy.JPG" /></author><thr:total>1</thr:total><feedburner:origLink>http://blog.nirav.name/2010/12/tackling-nulls-functional-way.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE8BR3k6eyp7ImA9WxFRGUU.&quot;"><id>tag:blogger.com,1999:blog-11200164.post-8161252017475363531</id><published>2010-05-01T12:34:00.006-04:00</published><updated>2010-05-04T10:20:56.713-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-04T10:20:56.713-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="Future" /><category scheme="http://www.blogger.com/atom/ns#" term="Opinion" /><title>Future of a Java programmer</title><content type="html">As a long time Java only programmer professionally,&amp;nbsp;I have been pondering about how things are changing around me as a Java programmer. Ever since I remember I had no choice but to use subset of C++ dialect (Java lang) with an extremely rich class library and ecosystem (Java platform).&lt;br /&gt;
&lt;br /&gt;
In last few years there has been a drastic&amp;nbsp;shift in number of languages targeting JVM. For example: dynamic (javascript, jruby, jython, groovy), functional + OO (scala) and a lisp dialect (clojure) and &lt;a href="http://en.wikipedia.org/wiki/List_of_JVM_languages"&gt;so many others&lt;/a&gt;. While I am excited about all the options I have today I don't think a single language will dominate on JVM anymore like Java did so far.&lt;br /&gt;
&lt;br /&gt;
In a way this is a good thing, one tool rarely fits all needs (I couldn't curse Java enough for GUI programming). Like C, Java was never designed to be used for developing dynamic web apps, but we still tried and miserably failed with JSP/JSF and plethora of frameworks against&amp;nbsp;PHP/Rails/Python in terms of productivity. One really good thing Java did was to raise a level of abstractions from platform specific details and memory management. These new languages on top of JVM raise the abstraction level even further for its area of strength.&lt;br /&gt;
&lt;br /&gt;
It is not a remote future when we will see concurrent processes being programmed in clojure and presented with jruby/rails with intermediate code written in Java. Each layer of application is going to be implemented in different programming languages while interfaces being transparent for developers working in each layer. This is a big thing, it has never been envisioned before for Java Platform, the lowest coupling we have seen so far is through remoting (web services et. al.) where clients and servers are on different runtimes and languages.&lt;br /&gt;
&lt;br /&gt;
What this means for a Java developer is&amp;nbsp;if you are&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;A web developer: you are going to learn things which are extremely different from struts/jsf/jsps, no more artificial model1/model2 MVCs.&lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;A non web-developer : you are going to write code which is far more readable and very specific to your business domain via DSL created in any of the languages mentioned above without worrying about accidental complexity Java and its frameworks imposed on you.&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
While I can keep classifying developers on Java platform all day long, these two are major ones whose life (and resumes) are going to change soon, they will be expected to know more than one programming languages rather than frameworks now. Contrary to the cool kids on interwebz, I don't think Java the language is going to die anytime soon not because many of the existing libraries are written in it, but because of the number of programmers on earth who know Java, tooling around it and the native JVM support for it. Java is like C in a way, you can do whatever is supported by underlying implementation.&lt;br /&gt;
&lt;br /&gt;
Many of you who are like me are going to see change around them soon, I am thrilled to see how my career is going to transform as polyglot programmer are you?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11200164-8161252017475363531?l=blog.nirav.name' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=nQnef2IOIKk:5Hw7jg0xFxA:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=nQnef2IOIKk:5Hw7jg0xFxA:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=nQnef2IOIKk:5Hw7jg0xFxA:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=nQnef2IOIKk:5Hw7jg0xFxA:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=nQnef2IOIKk:5Hw7jg0xFxA:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=nQnef2IOIKk:5Hw7jg0xFxA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/nirav/~4/nQnef2IOIKk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nirav.name/feeds/8161252017475363531/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=11200164&amp;postID=8161252017475363531" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/8161252017475363531?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/8161252017475363531?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/nirav/~3/nQnef2IOIKk/future-of-java-programmer.html" title="Future of a Java programmer" /><author><name>Nirav Thaker</name><uri>http://www.blogger.com/profile/07204297663478577248</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_PebfjbIpLKY/SYO5wL9XgUI/AAAAAAAAByY/MhgUWfUq5Hc/S220/DSCN1212+-+Copy.JPG" /></author><thr:total>5</thr:total><feedburner:origLink>http://blog.nirav.name/2010/05/future-of-java-programmer.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0cCSXczeCp7ImA9WxBUGUU.&quot;"><id>tag:blogger.com,1999:blog-11200164.post-5609066850391656326</id><published>2010-03-07T12:58:00.004-05:00</published><updated>2010-03-07T13:04:28.980-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-07T13:04:28.980-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Scala" /><category scheme="http://www.blogger.com/atom/ns#" term="Refactoring" /><category scheme="http://www.blogger.com/atom/ns#" term="Eclipse" /><title>Eclipse Refactoring for legacy code</title><content type="html">&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;It has been quite sometime since I wrote anything on this blog, twitter probably spoiled me. If you are &lt;a href="http://twitter.com/niravn1"&gt;following me&amp;nbsp;on twitter&lt;/a&gt;, you probably noticed announcement of &amp;nbsp;a small eclipse plugin for automated refactoring for Legacy Code.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Before few months, I wrote an LTK refactoring mainly in Scala (yes, eclipse plugin in&amp;nbsp;Scala language) to forward static method calls in a Java method to an instance method in same class. I am not really an expert at Scala (or functional programming for that matter) so the code is more of javaish Scala but I am improving and thats the best thing about Scala. This is also an attempt to prove how easy it is to write eclipse plugins in Scala and how seamlessly it integrates with Java source; Scala is not only a better language, it is much more suitable to deal with Eclipse APIs (you can define views etc. on extremely verbose interfaces like JDT AST).&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Enough about Scala; the real purpose of the refactorings provided in this plugin would be to ease development with Legacy Java code, most of the code generators (think JavaCC) generate ugly Java code which is not only non unit testable but pain to comprehend and is often not usable with concurrent routines. Using this automated refactoring should make such code better. You can read more about the motivation behind the &lt;a href="http://code.google.com/p/java-ext-refactorings/wiki/StaticCallForwardRefactoring"&gt;plugin in wiki&lt;/a&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
For the performance heads who are worried about method chains introduced by this refactoring are encouraged to run their own "sane" micro-benchmarks to be sure JVM is really&amp;nbsp;in-lining&amp;nbsp;the method calls created by this refactoring.&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;The plugin is currently in beta and I am open for any new refactoring proposals. If you have any feedback, you are welcome to comment on this blog post or &lt;a href="http://code.google.com/p/java-ext-refactorings/issues/list"&gt;create a bug&lt;/a&gt;. The &lt;a href="http://java-ext-refactorings.googlecode.com/svn/branches/0.1-beta/name.nirav.refcatoringman.update"&gt;update site is here&lt;/a&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11200164-5609066850391656326?l=blog.nirav.name' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=Mr-DIlQXecg:qO3IoF--ANY:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=Mr-DIlQXecg:qO3IoF--ANY:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=Mr-DIlQXecg:qO3IoF--ANY:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=Mr-DIlQXecg:qO3IoF--ANY:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=Mr-DIlQXecg:qO3IoF--ANY:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=Mr-DIlQXecg:qO3IoF--ANY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/nirav/~4/Mr-DIlQXecg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nirav.name/feeds/5609066850391656326/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=11200164&amp;postID=5609066850391656326" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/5609066850391656326?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/5609066850391656326?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/nirav/~3/Mr-DIlQXecg/eclipse-refactoring-for-legacy-code.html" title="Eclipse Refactoring for legacy code" /><author><name>Nirav Thaker</name><uri>http://www.blogger.com/profile/07204297663478577248</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_PebfjbIpLKY/SYO5wL9XgUI/AAAAAAAAByY/MhgUWfUq5Hc/S220/DSCN1212+-+Copy.JPG" /></author><thr:total>5</thr:total><feedburner:origLink>http://blog.nirav.name/2010/03/eclipse-refactoring-for-legacy-code.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CU8GR3w4eCp7ImA9WxNTEk8.&quot;"><id>tag:blogger.com,1999:blog-11200164.post-4079223988553714376</id><published>2009-08-13T21:00:00.012-04:00</published><updated>2009-08-14T00:23:46.230-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-14T00:23:46.230-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Refactoring" /><category scheme="http://www.blogger.com/atom/ns#" term="Software Development" /><category scheme="http://www.blogger.com/atom/ns#" term="Pragmatic" /><title>Real Refactoring</title><content type="html">A lot of &lt;a href="http://www.refactoring.com/sources.html"&gt;really good material&lt;/a&gt; has been written about &lt;a href="http://en.wikipedia.org/wiki/Code_refactoring"&gt;refactoring&lt;/a&gt;. However, just like a lot of other things in software development, refactoring is also victimized by becoming the buzzword implying 'rewrites' and every other thing that is not refactoring. A lot of people really don't understand what they mean when they refer to 'refactoring', this post aims to provide a systematic explanation of refactoring for such audience.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Refactoring is merely a process of restructuring existing code so that its end result and meaning remains intact. However, this restructuring has a great potential to become far better design than the original one. (It is implied that the refactored design is easier to refactor and hence better) In rest of this post I will try to summarize how to approach and refactor a code in real life application development.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;1. Get familiar with code&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I am assuming here that we are almost always refactoring code written fully or partially by others, refactoring your own code should be much more simple exercise. Primarily you would be dealing with Legacy code or testable code. If you are lucky enough to get the code which is almost covered with unit tests, your job becomes substantially easy and you can start refactoring very fast without a lot of trouble. However if you are working with existing code which just exists and works somehow, you will have to start slowly. The first step is to understand the incomprehensible. There are several ways you can get familiar with code:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Read the code&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Reading code is one of the fundamental activity we developers do most of the time, if any employer is in the illusion that she is paying developers just to write code then they are paying 1/3 of the salary. Reading code is an art which develops over the time, reading good code can make you better developer (with a precondition that one possesses the ability to judge good and bad code for the language). The more you read bad code the more you familiarize yourself with the repeating mistakes in the code (duplication, absolute hostility towards testability, extremely fearful defensive checks and other hilarities). The goal is to grasp the mindset of the original developer(s) who wrote it. You will know it immediately how deeply thought out the code is in a few passes. Use any modern IDEs to navigate through files, ignore the comments which don't make sense.&lt;br /&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;Write test&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Once you have some understanding of inputs/outputs and/or interactions in code's life cycle you can write some tests just so that you can identify if you made some mistake in next step (Step 2). These tests might not be unit-tests (unless the code itself is unit testable). Writing test is incredibly useful way to get familiar with the code base.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;2. Isolate the refactoring hot-spot &lt;/b&gt; (or "The Inflection points" as Michael Feathers calls it)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;There has to be a really good reason why you are refactoring and it certainly can't be a full 'rewrite'. Irony will kill itself when it finds out that the problems in a bad code manifests itself in popular hot-spots. By isolating these hot-spots you should be able to mock out the uninteresting and untestable (or very slow) dependencies. If you have multiple inflection points; deal with them one by one in isolation. Isolation may become tricky because you may have to introduce some inevitable changes before you actually have any unit tests. For example, you might want to eliminate inherently untestable 'statics', extract methods/interfaces which you can stub with NullObjects/mocks. The tests created in earlier step will be valuable to identify any problems you introduced while isolating the code. The goal here is to not concern yourself with trivialities other than the refactoring hot-spots.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;3. Write unit tests&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;Now that you have code which can be isolated, start writing unit tests. If you are working on Java sources I highly recommend using &lt;a href="http://mockito.org/"&gt;Mockito&lt;/a&gt; to mock the dependencies. Don't waste time on accidental complexities of other mock libraries. A reasonable analogy would be: if Agile software development is a good thing than other mocking tools are worse than Waterfall - Mockito is Agile. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Your primary goal is to cover code under refactoring as much as possible, there are no hard numbers on code/branch coverages (but anything beyond 90% should be good enough :)), use common sense and quality metrics like &lt;a href="http://www.artima.com/weblogs/viewpost.jsp?thread=215899"&gt;CRAP&lt;/a&gt;. The more unit tests you will write, more you will learn about the code base. There may be totally unused code for anti-&lt;a href="http://c2.com/xp/YouArentGonnaNeedIt.html"&gt;YAGNI&lt;/a&gt; stronghold, or there might be bugs, Your unit test will reveal these naturally. Depending on the code in question, A good test suit generally reaches the size of the code under test.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;4. Refactor&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Refactoring is particularly painful when it has to be done in an environment with highly volatile code base and for the parts of code which are critical to overall application functionality. Make small changes; make sure all tests pass. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If you are using Eclipse - turn off auto build and add a ANT or Maven builder so that it runs your tests after each compile - you will be running tests a lot. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Use a real source control system, it might be much harder for you to revert the changes otherwise. You might consider using something like &lt;a href="http://git-scm.com/"&gt;git&lt;/a&gt; in between upstream and your local repository if your primary SCM is not good enough. In practice, this becomes a lot more important than what IDE you use, you will need the ability to identify and rollback a commit specifically in code base with many hands. Commit after each change, the smaller the commit the lesser chance of breaking a lot of things together by a long shot.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;With each commit going in repository without external complains (like "You broke my build!"), you will gain confidence to make bigger changes. You should continue writing tests while refactoring because if at this point you are making changes without violating functional contracts you are evolving a new design and doing something good. If you have broken something and your justification involves the word 'refactoring', you are doing it wrong! you either don't have enough tests or you failed to understand the code entrails.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So this is refactoring in real life. For the primary audience, please consider following these simple steps before tossing the word 'refactoring' around. If you disagree, then invent the new word and let me know :).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11200164-4079223988553714376?l=blog.nirav.name' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=Aw2a0QX0Hrs:-ViSe5L5AjY:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=Aw2a0QX0Hrs:-ViSe5L5AjY:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=Aw2a0QX0Hrs:-ViSe5L5AjY:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=Aw2a0QX0Hrs:-ViSe5L5AjY:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=Aw2a0QX0Hrs:-ViSe5L5AjY:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=Aw2a0QX0Hrs:-ViSe5L5AjY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/nirav/~4/Aw2a0QX0Hrs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nirav.name/feeds/4079223988553714376/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=11200164&amp;postID=4079223988553714376" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/4079223988553714376?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/4079223988553714376?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/nirav/~3/Aw2a0QX0Hrs/real-refactoring.html" title="Real Refactoring" /><author><name>Nirav Thaker</name><uri>http://www.blogger.com/profile/07204297663478577248</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_PebfjbIpLKY/SYO5wL9XgUI/AAAAAAAAByY/MhgUWfUq5Hc/S220/DSCN1212+-+Copy.JPG" /></author><thr:total>2</thr:total><feedburner:origLink>http://blog.nirav.name/2009/08/real-refactoring.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkIEQ3o7fSp7ImA9WxJREUU.&quot;"><id>tag:blogger.com,1999:blog-11200164.post-1203632720875867405</id><published>2009-05-12T22:01:00.010-04:00</published><updated>2009-05-13T00:21:42.405-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-13T00:21:42.405-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Scala" /><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><title>Scala v/s Java arrays</title><content type="html">Here's a Java puzzler for the curious (and a good interview question too!). Given a array merge method below, what will be the output of following program?&lt;br /&gt; &lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;&lt;br /&gt;public class Generics {&lt;br /&gt;&lt;br /&gt; static class A {&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; static class B extends A {&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public static void main(String[] args) {&lt;br /&gt;&lt;br /&gt;  A[] copy = merge(new B[] { new B() }, new A[] { new A() }, new B[1]);&lt;br /&gt;  System.out.println(copy.length != 1);&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; static &lt;Z&gt; Z[] merge(Z[] arr1, Z[] arr2, Z[] store) {&lt;br /&gt;  List&lt;Z&gt; list = new ArrayList&lt;Z&gt;();&lt;br /&gt;  list.addAll(Arrays.asList(arr1));&lt;br /&gt;  list.addAll(Arrays.asList(arr2));&lt;br /&gt;  return list.toArray(store);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt; &lt;br /&gt;&lt;br /&gt;If you didn't guess it already, the program above results in a runtime exception (java.lang.ArrayStoreException). &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Exception in thread "main" java.lang.ArrayStoreException&lt;br /&gt; at java.lang.System.arraycopy(Native Method)&lt;br /&gt; at java.util.Arrays.copyOf(Unknown Source)&lt;br /&gt; at java.util.ArrayList.toArray(Unknown Source)&lt;br /&gt; at name.nirav.Generics.merge(Generics.java:23)&lt;br /&gt; at name.nirav.Generics.main(Generics.java:16)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I am not a huge fan of generics in Java because we are left with whatever type safety we get from a half-hearted implementation (and I'm not even criticizing). It is too much to expect from a Java compiler to check that the program above has type safety compromised at call site, mostly because that's how arrays in Java are handled by VM. Arrays are special types of mutable objects with components as anonymous members which are accessed with indices. An array itself isn't a type, it assumes whatever type &lt;a href="http://java.sun.com/docs/books/jvms/second_edition/html/Concepts.doc.html#21035"&gt;its components are&lt;/a&gt;. This is where the problem starts. &lt;br /&gt;&lt;br /&gt;With current generics implementation, generic arrays are treated as covariant by default i.e. an array of component type T is also array of component type S where T is a subclass of S. This introduces type issues such as above where syntactically valid programs are victimized, making Java's "statically typed, type safe language" designation an irony. If arrays were regular objects, compiler will report an error in code without type variance information.&lt;br /&gt;&lt;br /&gt;Arrays are regular objects in Scala, each array is an instance of Scala.Array class. The code below is equivalent to Java program above with some syntactic differences, unlike Java code the Scala code below is not syntactically valid. Scala arrays are non-variant, and Scala compiler uses what is called "conservative approximation" to ensure type safety at compile time.&lt;br /&gt;&lt;br /&gt;&lt;pre class="scala" name="code"&gt;&lt;br /&gt;object App extends Application{&lt;br /&gt;&lt;br /&gt; class A&lt;br /&gt;&lt;br /&gt; class B extends A&lt;br /&gt; &lt;br /&gt; def merge[T](arr1 : Array[T], arr2: Array[T], store: Array[T]) : Array[T] = {&lt;br /&gt;    val list = new ArrayList[T]&lt;br /&gt;    list.addAll(Arrays.asList(arr1:_*)) // :_* is for vararg conversion&lt;br /&gt;    list.addAll(Arrays.asList(arr2:_*))&lt;br /&gt;    list toArray store&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; merge(Array[B](new B), Array[A](new A), new Array[B](1)) //Error, type mismatch &lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The Scala compiler will report an error on "merge" call, complaining about type mismatch. &lt;br /&gt;&lt;br /&gt;Not everyone likes to know about such details until it bites back with million dollar bugs. Why are Java arrays co-variant? Who needs more run time checks?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11200164-1203632720875867405?l=blog.nirav.name' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=k5N35zT7mfs:Up2oO0q5EAU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=k5N35zT7mfs:Up2oO0q5EAU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=k5N35zT7mfs:Up2oO0q5EAU:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=k5N35zT7mfs:Up2oO0q5EAU:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=k5N35zT7mfs:Up2oO0q5EAU:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=k5N35zT7mfs:Up2oO0q5EAU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/nirav/~4/k5N35zT7mfs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nirav.name/feeds/1203632720875867405/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=11200164&amp;postID=1203632720875867405" title="10 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/1203632720875867405?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/1203632720875867405?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/nirav/~3/k5N35zT7mfs/scala-vs-java-arrays.html" title="Scala v/s Java arrays" /><author><name>Nirav Thaker</name><uri>http://www.blogger.com/profile/07204297663478577248</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_PebfjbIpLKY/SYO5wL9XgUI/AAAAAAAAByY/MhgUWfUq5Hc/S220/DSCN1212+-+Copy.JPG" /></author><thr:total>10</thr:total><feedburner:origLink>http://blog.nirav.name/2009/05/scala-vs-java-arrays.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUYFSHg5eCp7ImA9WxJSFEQ.&quot;"><id>tag:blogger.com,1999:blog-11200164.post-3242915400405752701</id><published>2009-05-05T22:23:00.000-04:00</published><updated>2009-05-05T00:18:39.620-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-05T00:18:39.620-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Scala" /><category scheme="http://www.blogger.com/atom/ns#" term="Concurrency" /><category scheme="http://www.blogger.com/atom/ns#" term="Java VM" /><title>Fork/Join Concurrency with Scala Actors</title><content type="html">Have you ever wondered why there are no special  frameworks to address concurrency in a Java based application? Considering Java's rich (NIH) ecosystem, I do wonder why I have to write same old state management code while introducing even a small amount of concurrency in Java application.&lt;br /&gt;&lt;br /&gt;The reason why I think it is almost impossible to consider concurrency as an aspect in arbitrary application is because of JVM's native support for shared memory concurrency. As a result every developer is forced to think in terms of threaded shared state with guarded blocks.  If you have read or written non-trivial piece of code using shared memory concurrency primitives (Mutex, Semaphore etc.) you probably know that the resultant code is hard to visualize and test.&lt;br /&gt;&lt;br /&gt;I have been reading about Scala's Actor library and its share-nothing message passing abstraction built over existing concurrency model of JVM. While it doesn't try to solve the fundamental problem, it provides an alternative to address concurrency in your application from a different perspective which is testable and easier to understand.&lt;br /&gt;&lt;br /&gt;In &lt;a href="http://en.wikipedia.org/wiki/Actor_model"&gt;actor model&lt;/a&gt;,  an Actor is a forkable task which runs independently, something like a serializable+immutable object with its private data and behavior. Each actor can send and receive (or react to) messages asynchronously, very similar to object oriented programming with objects responding to messages, but in a concurrent way. This abstraction can seamlessly be applied to a given application of &lt;a href="http://en.wikipedia.org/wiki/Divide_and_conquer_algorithm"&gt;divide and conquer&lt;/a&gt; nature and can be made concurrent with minimal efforts as compared to adapting to Java's concurrency primitives.&lt;br /&gt;&lt;br /&gt;To explain my point further take a look at classically trivial Producer/Consumer example in Java.&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public class Consumer extends Thread {&lt;br /&gt;private final Buffer buffer;&lt;br /&gt;public Consumer(Buffer buffer) {&lt;br /&gt; super("Consumer");&lt;br /&gt; this.buffer = buffer;&lt;br /&gt;}&lt;br /&gt;@Override&lt;br /&gt;public void run() {&lt;br /&gt; while (true){&lt;br /&gt;  System.out.println(buffer.next());&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;public class Producer extends Thread {&lt;br /&gt;private final Buffer buffer;&lt;br /&gt;public Producer(Buffer buffer) {&lt;br /&gt; this.buffer = buffer;&lt;br /&gt;}&lt;br /&gt;@Override&lt;br /&gt;public void run() {&lt;br /&gt; Random random = new Random(System.nanoTime());&lt;br /&gt; while (true) {&lt;br /&gt;  String num = Integer.toString(random.nextInt());&lt;br /&gt;  System.out.println(getName() + "=putting: " + num);&lt;br /&gt;  buffer.add(num + ": " + getName());&lt;br /&gt;  try {&lt;br /&gt;   sleep(400);&lt;br /&gt;  } catch (InterruptedException e) {&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;public class Buffer {&lt;br /&gt;private String string;&lt;br /&gt;private boolean ready = false;&lt;br /&gt;public synchronized String next() {&lt;br /&gt; if (ready != true)&lt;br /&gt;  try {&lt;br /&gt;   wait();&lt;br /&gt;  } catch (InterruptedException e) {&lt;br /&gt;  }&lt;br /&gt; ready = false;&lt;br /&gt; return string;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public synchronized void add(String string) {&lt;br /&gt; while(ready == true)&lt;br /&gt;  try {&lt;br /&gt;   wait();&lt;br /&gt;  } catch (InterruptedException e) {&lt;br /&gt;  }&lt;br /&gt; this.string = string;&lt;br /&gt; notifyAll();&lt;br /&gt; ready = true;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;public class Test {&lt;br /&gt;public static void main(String[] args) throws Throwable {&lt;br /&gt; Buffer buffer = new Buffer();&lt;br /&gt; new Consumer(buffer).start();&lt;br /&gt; Producer producer = new Producer(buffer);&lt;br /&gt; producer.start();&lt;br /&gt; producer.join();&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;Take a look at Buffer class, we have used some concurrency primitives there since that's the place where state is being manipulated. We didn't declare variable ready as volatile since  primitive assignments are guaranteed to be atomic (&lt;a href="http://java.sun.com/docs/books/jvms/second_edition/html/Threads.doc.html#22244"&gt;except long and double&lt;/a&gt;), Even a simple problem like this involves fair bit of understanding of the underlying threading model. There's no doubt this complexity will extrapolate in non-trivial applications e.g. multi-phase concurrent incremental compiler, SEDA based server etc.&lt;br /&gt;&lt;br /&gt;Now take a look at the equivalent Producer/Consumer example in Scala.&lt;br /&gt;&lt;pre name="code" class="Scala"&gt;&lt;br /&gt;import actors._&lt;br /&gt;import actors.Actor._&lt;br /&gt;import util.Random&lt;br /&gt;&lt;br /&gt;case class SimpleMessage(num: Long)&lt;br /&gt;&lt;br /&gt;class Producer(c: Consumer) extends Actor{&lt;br /&gt;val random = new Random(System nanoTime)&lt;br /&gt;def act = {&lt;br /&gt; loop{&lt;br /&gt;  val num = produce&lt;br /&gt;  println("Sending: " + num )&lt;br /&gt;  c ! SimpleMessage(num)  // asynchronous message passing&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;def produce(): Long = {&lt;br /&gt; Thread sleep 400&lt;br /&gt; return random.nextLong&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;class Consumer() extends Actor{&lt;br /&gt;def act = {&lt;br /&gt;  loop{&lt;br /&gt;   receive{ //blocks here&lt;br /&gt;     case SimpleMessage(num) =&gt; println("Received: " + num);&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;object PCTest {&lt;br /&gt;def main(args : Array[String]) : Unit = {&lt;br /&gt;var c = new Consumer()&lt;br /&gt;var p = new Producer(c)&lt;br /&gt;c.start;p.start&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Even if we don't compare the amount of code, the Scala code above is much more clear in terms of its functionality. In Scala, Actors can be mapped to a single native thread with 'receive' (similar to Thread#wait()) or we can replace 'receive' with 'react' which is event based invocation but doesn't cost a blocked thread. The code within 'react' is executed by any non-blocked thread from a pre-created thread-pool. Just a single change and your application is scalable!&lt;br /&gt;&lt;br /&gt;The Java example code above can be equally trivialized with the util.concurrent BlockingQueue, but the important point to take away is, writing shared memory concurrency code is inherently difficult and error-prone. With JDK1.7 we will get similar &lt;a href="http://gee.cs.oswego.edu/dl/papers/fj.pdf"&gt;fork/join abstraction&lt;/a&gt; in Java itself (JSR166y), which will add new alternative to how we design and write concurrent applications.&lt;br /&gt;&lt;br /&gt;Scala borrowed Actors from Erlang and similar &lt;a href="http://sujitpal.blogspot.com/2009/01/more-java-actor-frameworks-compared.html"&gt;libraries exist for Java&lt;/a&gt; as well. If you are curious about interesting details on Actor based OO concurrency implementation in Java, take a&lt;a href="http://www.jroller.com/sebastianKuebeck/entry/object_orinetned_concurrency_meets_actors"&gt; look at some of&lt;/a&gt; the thoughts&lt;a href="http://www.jroller.com/sebastianKuebeck/entry/object_oriented_concurrency"&gt; Sebastian is sharing with&lt;/a&gt; his ConcurrentObjects library.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11200164-3242915400405752701?l=blog.nirav.name' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=Nc9G63q_1Zg:TnpL3b8-QV4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=Nc9G63q_1Zg:TnpL3b8-QV4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=Nc9G63q_1Zg:TnpL3b8-QV4:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=Nc9G63q_1Zg:TnpL3b8-QV4:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=Nc9G63q_1Zg:TnpL3b8-QV4:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=Nc9G63q_1Zg:TnpL3b8-QV4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/nirav/~4/Nc9G63q_1Zg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nirav.name/feeds/3242915400405752701/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=11200164&amp;postID=3242915400405752701" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/3242915400405752701?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/3242915400405752701?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/nirav/~3/Nc9G63q_1Zg/forkjoin-concurrency-with-scala-actors.html" title="Fork/Join Concurrency with Scala Actors" /><author><name>Nirav Thaker</name><uri>http://www.blogger.com/profile/07204297663478577248</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_PebfjbIpLKY/SYO5wL9XgUI/AAAAAAAAByY/MhgUWfUq5Hc/S220/DSCN1212+-+Copy.JPG" /></author><thr:total>1</thr:total><feedburner:origLink>http://blog.nirav.name/2009/04/forkjoin-concurrency-with-scala-actors.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0EBR3s7fyp7ImA9WxJTFk8.&quot;"><id>tag:blogger.com,1999:blog-11200164.post-2056609480094935089</id><published>2009-04-21T22:29:00.015-04:00</published><updated>2009-04-24T23:20:56.507-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-24T23:20:56.507-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Scala" /><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="Patterns" /><category scheme="http://www.blogger.com/atom/ns#" term="Design" /><title>How Scala's pattern matching can replace Visitors</title><content type="html">The primary motivation of &lt;a href="http://en.wikipedia.org/wiki/Visitor_pattern"&gt;Visitor design pattern&lt;/a&gt; is to separate model traversal from operational logic. A visitable model takes the responsibility of model navigation while the behavior is defined by arbitrary visitors. In this post I will try to explain problems associated with Visitors in general and how &lt;a href="http://www.blogger.com/www.scala-lang.org/node/120"&gt;Scala's pattern matching&lt;/a&gt; feature can eliminate such problems cleanly.&lt;br /&gt;&lt;br /&gt;Consider a simplified Insurance Policy model as follows (In Java):&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;&lt;br /&gt;public class PolicyElement {&lt;br /&gt; static class Quote extends PolicyElement {&lt;br /&gt;  protected final Risk risk;&lt;br /&gt;  public Quote(Risk risk) {&lt;br /&gt;   this.risk = risk;&lt;br /&gt;  }&lt;br /&gt;  public void accept(PolicyVisitor visitor){&lt;br /&gt;   visitor.visit(this);&lt;br /&gt;   visitor.visit(this.risk);&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; static class Risk extends PolicyElement {&lt;br /&gt;  protected Coverage coverage;&lt;br /&gt;  public Risk(Coverage coverage) {&lt;br /&gt;   this.coverage = coverage;&lt;br /&gt;  }&lt;br /&gt;  public void accept(PolicyVisitor visitor){&lt;br /&gt;   visitor.visit(coverage);&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; static class Coverage extends PolicyElement {&lt;br /&gt;  protected final Premium prem;&lt;br /&gt;  public Coverage(Premium prem) {&lt;br /&gt;   this.prem = prem;&lt;br /&gt;  }&lt;br /&gt;  public void accept(PolicyVisitor visitor){&lt;br /&gt;   visitor.visit(prem);&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; static class Premium extends PolicyElement {&lt;br /&gt;  protected final double amt;&lt;br /&gt;  public Premium(double amt) {&lt;br /&gt;   this.amt = amt;&lt;br /&gt;  }&lt;br /&gt;  public void accept(PolicyVisitor visitor){&lt;br /&gt;   visitor.visit(this);&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public interface PolicyVisitor {&lt;br /&gt; public void visit(Quote quote);&lt;br /&gt; public void visit(Risk risk);&lt;br /&gt; public void visit(Coverage cvrg);&lt;br /&gt; public void visit(Premium prem);&lt;br /&gt;}&lt;br /&gt;public class PolicyTest {&lt;br /&gt; static class PremiumCalcVisitor implements PolicyVisitor {&lt;br /&gt;  private double totalPremium;&lt;br /&gt;&lt;br /&gt;  @Override&lt;br /&gt;  public void visit(Premium prem) {&lt;br /&gt;   totalPremium = getTotalPremium() + prem.amt;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  @Override&lt;br /&gt;  public void visit(Coverage cvrg) {&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  @Override&lt;br /&gt;  public void visit(Risk risk) {&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  @Override&lt;br /&gt;  public void visit(Quote quote) {&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public double getTotalPremium() {&lt;br /&gt;   return totalPremium;&lt;br /&gt;  }&lt;br /&gt; };&lt;br /&gt;&lt;br /&gt; public static void main(String[] args) {&lt;br /&gt;  Quote quote1 = new Quote(new Risk(new Coverage(new Premium(10))));&lt;br /&gt;  Quote quote2 = new Quote(new Risk(new Coverage(new Premium(30))));&lt;br /&gt;  PremiumCalcVisitor visitor1 = new PremiumCalcVisitor();&lt;br /&gt;  PremiumCalcVisitor visitor2 = new PremiumCalcVisitor();&lt;br /&gt;  quote1.accept(visitor1);&lt;br /&gt;  quote2.accept(visitor2);&lt;br /&gt;  assert visitor1.getTotalPremium() + visitor2.getTotalPremium() == 40;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;(Generally, we introduce one more abstract class to omit empty implementations in Visitors but I have left it for brevity.)&lt;br /&gt;&lt;br /&gt;Now, not so apparent problem here is that if the object model changes (which is more frequently the case in real life), we have to add one more method to PolicyVisitor interface, all visitor implementations if change is substantial and have new Policy elements implement visitor methods. This invasive nature of Visitor couples it tightly with the model.&lt;br /&gt;&lt;br /&gt;With pattern matching and &lt;a href="http://www.scala-lang.org/node/130"&gt;views&lt;/a&gt; in Scala, you can have alternative implementation which is precise as well as non-invasive unlike visitors.&lt;br /&gt;&lt;pre name="code" class="scala"&gt;&lt;br /&gt;class PolicyElement &lt;br /&gt;case class Quote(risks: Risk) extends PolicyElement&lt;br /&gt;case class Risk(cvrg: Coverage) extends PolicyElement &lt;br /&gt;case class Coverage(limit: Premium) extends PolicyElement &lt;br /&gt;case class Premium(amt: Double) extends PolicyElement&lt;br /&gt;object PremCalcTest {&lt;br /&gt;  class PremCalculator(pol: PolicyElement){&lt;br /&gt; def calcPrem : Double = calcPrem(pol)&lt;br /&gt; &lt;br /&gt;    def calcPrem(policy: PolicyElement): Double = policy match{&lt;br /&gt;   case Quote(risk)   =&gt; calcPrem(risk)&lt;br /&gt;   case Risk(coverage)  =&gt; calcPrem(coverage)&lt;br /&gt;   case Coverage(premium)=&gt; calcPrem(premium)&lt;br /&gt;   case Premium(amt)  =&gt; amt&lt;br /&gt; }&lt;br /&gt;  }&lt;br /&gt; &lt;br /&gt;  implicit def calPremV(pol: PolicyElement)= new PremCalculator(pol)&lt;br /&gt;  &lt;br /&gt;  def main(string: Array[String]){&lt;br /&gt;   val risk1 = Risk(Coverage(Premium(10)))&lt;br /&gt;   val risk2 = Risk(Coverage(Premium(30)))&lt;br /&gt;   println(Quote(risk1).calcPrem + Quote(risk2).calcPrem)&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This code requires some explanation. What we have done here is we labeled domain classes with a 'case' keyword in Scala. If you tag a class with 'case' it can be used for pattern matching in a switch-case like structure as done in method 'calcPrem'. You don't need to create members or setter/getters for them, they are created by compiler for you. A case class can be instantiated without 'new' keyword; So Risk(Coverage(Premium(0)) is translated as new Risk(new Coverage(new Premium(0D))) in equivalent Java code.&lt;br /&gt;&lt;br /&gt;The code in 'calcPrem' function can be assumed to be something similar to instanceOf checks for each possible case in Java, for example:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="scala"&gt;&lt;br /&gt;if(object instanceOf Premium)&lt;br /&gt;return ((Premium)object).amt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;What we also have done silently is added a method 'calcPrem' to PolicyObject class. This is done through implicitly defined function 'calPremV', this will allow us to call 'calcPrem' method on any PolicyObject without actually modifying the domain model code. This type of lexically scoped class extension is known as a View in Scala and is similar to what is available in Ruby as &lt;a href="http://rubylearning.com/satishtalim/ruby_open_classes.html"&gt;open classes&lt;/a&gt; except without scoping.&lt;br /&gt;&lt;br /&gt;In case if the model changes in this case, we just need to modify a single function and we are done. These programming language features of Scala frees us from coupling introduced by inheritance.&lt;br /&gt;&lt;br /&gt;So it is easy to see that Scala's language features can be elegant and far more powerful than  other languages (specifically Java) without sacrificing compiler checks and type safety.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11200164-2056609480094935089?l=blog.nirav.name' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=dH4mYR3Aqqg:kuOy6Ro9oXE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=dH4mYR3Aqqg:kuOy6Ro9oXE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=dH4mYR3Aqqg:kuOy6Ro9oXE:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=dH4mYR3Aqqg:kuOy6Ro9oXE:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=dH4mYR3Aqqg:kuOy6Ro9oXE:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=dH4mYR3Aqqg:kuOy6Ro9oXE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/nirav/~4/dH4mYR3Aqqg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nirav.name/feeds/2056609480094935089/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=11200164&amp;postID=2056609480094935089" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/2056609480094935089?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/2056609480094935089?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/nirav/~3/dH4mYR3Aqqg/how-scalas-pattern-matching-can-replace.html" title="How Scala's pattern matching can replace Visitors" /><author><name>Nirav Thaker</name><uri>http://www.blogger.com/profile/07204297663478577248</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_PebfjbIpLKY/SYO5wL9XgUI/AAAAAAAAByY/MhgUWfUq5Hc/S220/DSCN1212+-+Copy.JPG" /></author><thr:total>1</thr:total><feedburner:origLink>http://blog.nirav.name/2009/04/how-scalas-pattern-matching-can-replace.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEMCRnc_fip7ImA9WxVaGU4.&quot;"><id>tag:blogger.com,1999:blog-11200164.post-8929183270216800599</id><published>2009-04-16T21:38:00.003-04:00</published><updated>2009-04-16T22:47:47.946-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-16T22:47:47.946-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java VM" /><category scheme="http://www.blogger.com/atom/ns#" term="Loud Thinking" /><category scheme="http://www.blogger.com/atom/ns#" term="Opinion" /><title>Your Language is not SLOW!</title><content type="html">Do you really give a thought when you say "Ruby is slow or Python is slow"? Just because Twitter moved their &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_0"&gt;back end&lt;/span&gt; messaging to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;JVM&lt;/span&gt; doesn't necessarily make Ruby any slower than it already was. If a language &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;runtime&lt;/span&gt; can't handle concurrent load or long running processes it is not a limitation of the language!&lt;br /&gt;&lt;br /&gt;This is &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;dejavu&lt;/span&gt; for me as Java was considered "a slow language" back in 1.1 days when &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;HotSpot&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;JVM&lt;/span&gt; was in its poorer life and ISO/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;IEC&lt;/span&gt; C++ was hot girl in town. Now that you realized your pony implementations can't catch up with real life performance expectation you start blaming languages, are you serious?&lt;br /&gt;&lt;br /&gt;Whether it's &lt;a href="http://en.wikipedia.org/wiki/Global_Interpreter_Lock"&gt;global interpreter lock&lt;/a&gt; or &lt;a href="http://en.wikipedia.org/wiki/Green_threads"&gt;lack of native threads&lt;/a&gt; it's the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;runtime&lt;/span&gt; (re-read the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;runtime&lt;/span&gt;) and not the language that is slow. For the love of technology, Stop &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_9"&gt;blaming&lt;/span&gt; languages for poor performance of your &lt;a href="http://unlimitednovelty.com/2009/04/twitter-blaming-ruby-for-their-mistakes.html"&gt;suboptimal reinventions&lt;/a&gt;!&lt;br /&gt;&lt;br /&gt;Every language &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;implementor&lt;/span&gt; should at least consider the host platform support before coming up with their "Not Invented Here" approach, sadly that's what is happening with most modern languages.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11200164-8929183270216800599?l=blog.nirav.name' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=vMP_2DrIpXY:FlIrDYADiPg:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=vMP_2DrIpXY:FlIrDYADiPg:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=vMP_2DrIpXY:FlIrDYADiPg:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=vMP_2DrIpXY:FlIrDYADiPg:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=vMP_2DrIpXY:FlIrDYADiPg:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=vMP_2DrIpXY:FlIrDYADiPg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/nirav/~4/vMP_2DrIpXY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nirav.name/feeds/8929183270216800599/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=11200164&amp;postID=8929183270216800599" title="7 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/8929183270216800599?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/8929183270216800599?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/nirav/~3/vMP_2DrIpXY/your-language-is-not-slow.html" title="Your Language is not SLOW!" /><author><name>Nirav Thaker</name><uri>http://www.blogger.com/profile/07204297663478577248</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_PebfjbIpLKY/SYO5wL9XgUI/AAAAAAAAByY/MhgUWfUq5Hc/S220/DSCN1212+-+Copy.JPG" /></author><thr:total>7</thr:total><feedburner:origLink>http://blog.nirav.name/2009/04/your-language-is-not-slow.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUQEQXw5eCp7ImA9WxVaE04.&quot;"><id>tag:blogger.com,1999:blog-11200164.post-9052335280081205316</id><published>2009-04-09T22:21:00.004-04:00</published><updated>2009-04-10T00:21:40.220-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-10T00:21:40.220-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Scala" /><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="Opinion" /><title>Scala: First impression</title><content type="html">If you are curious enough about programming languages then you probably have  heard about Scala - the  'statically typed' functional and object oriented language. &lt;a href="http://www.scala-lang.org/"&gt;Scala&lt;/a&gt; is the new sun rising to balance 'the burn factor' between functional and object oriented schools of thoughts.&lt;br /&gt;&lt;br /&gt;Unlike what &lt;a href="http://www.scala-lang.org/sites/default/files/linuxsoft_archives/docu/files/ScalaOverview.pdf"&gt;this paper suggests&lt;/a&gt;[pdf], The reason why I think Scala exists is because functional v/s object oriented groups are moving in opposite directions, which is not only inefficient but they can't leverage achievements of one another. If you read about functional v/s object oriented programming comparison, every argument boils down to productivity, tooling and maintainability of code. While functional languages (Lisp, Haskell, Python etc.) offer excellent productivity compared to OO languages (Java, C++ etc.), Object oriented languages offer excellent tooling and are relatively maintainable. The reason why I think OO languages have been so popular is due to its easier to understand concept which is easy to map in real life, so for most people who have never took computer science course OO is still easier to grasp  compared to Functional programming methods like list comprehension, closures or the higher order functions which are rooted from the formal systems of mathematics.&lt;br /&gt;&lt;br /&gt;Scala tries to satisfy both of the groups by providing grammar and a type system which seamlessly integrates with mainstream platforms (Java, .NET) and offers powerful functional abstractions only available in dynamic languages. What this means is, Java developers can write their code in same fashion they write in Java using existing libraries and frameworks but with an added advantage of functional programming techniques wherever they feel it might be productive. Functional programming language enthusiast get access to rich class libraries and powerful tooling (eventually).&lt;br /&gt;&lt;br /&gt;If you take a look at the Scala language &lt;a href="http://www.scala-lang.org/docu/files/ScalaReference.pdf"&gt;grammar&lt;/a&gt;[pdf] you will notice that &lt;a href="http://debasishg.blogspot.com/2008/05/designing-internal-dsls-in-scala.html"&gt;what you can create&lt;/a&gt; with Scala is limited by &lt;a href="http://blog.fogus.me/2009/03/26/baysick-a-scala-dsl-implementing-basic/"&gt;your creativity&lt;/a&gt;. Based on what I have learned so far, I find Scala much more refreshing than Java, Scala feels a lot more like a programming language of the 21st century! Scala compiler itself is pluggable so you can do heck of a stuff you can only dream with javac, ecj. What is missing is tooling, the existing tooling is scrap but that will improve hopefully with an active community.&lt;br /&gt;&lt;br /&gt;Bill Venners of &lt;a href="http://www.artima.com/"&gt;Artima&lt;/a&gt; has presented Scala wonderfully, take a &lt;a href="http://www.parleys.com/display/PARLEYS/Home#slide=1;title=The%20Feel%20Of%20Scala;talk=27131945"&gt;look at the presentation&lt;/a&gt;[requires flash] on 'The feel of Scala'.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11200164-9052335280081205316?l=blog.nirav.name' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=psGlXJIggXc:OU74563L2VQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=psGlXJIggXc:OU74563L2VQ:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=psGlXJIggXc:OU74563L2VQ:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=psGlXJIggXc:OU74563L2VQ:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=psGlXJIggXc:OU74563L2VQ:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=psGlXJIggXc:OU74563L2VQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/nirav/~4/psGlXJIggXc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nirav.name/feeds/9052335280081205316/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=11200164&amp;postID=9052335280081205316" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/9052335280081205316?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/9052335280081205316?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/nirav/~3/psGlXJIggXc/scala-first-impression.html" title="Scala: First impression" /><author><name>Nirav Thaker</name><uri>http://www.blogger.com/profile/07204297663478577248</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_PebfjbIpLKY/SYO5wL9XgUI/AAAAAAAAByY/MhgUWfUq5Hc/S220/DSCN1212+-+Copy.JPG" /></author><thr:total>1</thr:total><feedburner:origLink>http://blog.nirav.name/2009/04/scala-first-impression.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUYERn0_eip7ImA9WxVbEE4.&quot;"><id>tag:blogger.com,1999:blog-11200164.post-6651224569871712906</id><published>2009-03-24T23:04:00.010-04:00</published><updated>2009-03-25T23:11:47.342-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-25T23:11:47.342-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="OPath" /><title>OPath ported for Java object model</title><content type="html">I have been thinking about alternate uses of OPath I created for EVars plug-in.  And it occurred to me that I can very well use it for my unit testing (which involves pretty complex insurance object model) and for things like JSPs where I really hate to write ten lines of Java code just to display some value.&lt;br /&gt;&lt;br /&gt;So I wrote a &lt;a href="http://code.google.com/p/evars/source/browse/#svn/trunk/name.nirav.opath.reflect"&gt;port of OPath for Java object model&lt;/a&gt; (less than 200 lines of real code). Following example should explain how it can add some value to your development efforts:&lt;br /&gt;&lt;br /&gt;Consider an example of code for simple &lt;a href="http://java.sun.com/developer/technicalArticles/GUI/accessibility2/#code5"&gt;Accessible Swing Table&lt;/a&gt; :&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://java.sun.com/developer/technicalArticles/GUI/accessibility2/SimpleTable.gif"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 515px; height: 121px;" src="http://java.sun.com/developer/technicalArticles/GUI/accessibility2/SimpleTable.gif" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;If you are writing a UI test to see specific table's column heading, you just write following&lt;br /&gt;&lt;br /&gt;&lt;pre style="background:  none repeat scroll 0% 0%; color: rgb(0, 0, 0); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;Collection&amp;lt;Object&gt; findAll = OPathReflectiveInterpreter.findAll(frame, "&lt;span style="color: rgb(63, 127, 89);"&gt;//dataModel//@val\\$column.*");&lt;/span&gt;&lt;br /&gt;assertEquals("First Name",((Object[])findAll.toArray()[0])[0]);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This is very trivial test, of course. But it is sufficient to express the power of OPath micro-scripting.&lt;br /&gt;&lt;br /&gt;If you like to try it out for unit-testing or templating check-out the download &lt;a href="http://evars.googlecode.com/files/opath-jom_1.0.0.jar"&gt;here&lt;/a&gt; (You will also need &lt;a href="http://evars.googlecode.com/svn/tags/b32209_01/name.nirav.evariablesview/lib/opath.jar"&gt;opath.jar&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;Disclaimer: This is experimental work at best, it might be slow and it might have bugs at this time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11200164-6651224569871712906?l=blog.nirav.name' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=lFAJGxH922k:YwofiMigKZw:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=lFAJGxH922k:YwofiMigKZw:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=lFAJGxH922k:YwofiMigKZw:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=lFAJGxH922k:YwofiMigKZw:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=lFAJGxH922k:YwofiMigKZw:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=lFAJGxH922k:YwofiMigKZw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/nirav/~4/lFAJGxH922k" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nirav.name/feeds/6651224569871712906/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=11200164&amp;postID=6651224569871712906" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/6651224569871712906?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/6651224569871712906?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/nirav/~3/lFAJGxH922k/opath-port-for-java-object-model.html" title="OPath ported for Java object model" /><author><name>Nirav Thaker</name><uri>http://www.blogger.com/profile/07204297663478577248</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_PebfjbIpLKY/SYO5wL9XgUI/AAAAAAAAByY/MhgUWfUq5Hc/S220/DSCN1212+-+Copy.JPG" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.nirav.name/2009/03/opath-port-for-java-object-model.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak4NR3c4fyp7ImA9WxVUF0o.&quot;"><id>tag:blogger.com,1999:blog-11200164.post-9137207996289952548</id><published>2009-03-22T22:58:00.005-04:00</published><updated>2009-03-22T23:29:56.937-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-22T23:29:56.937-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Evars" /><category scheme="http://www.blogger.com/atom/ns#" term="Debug" /><category scheme="http://www.blogger.com/atom/ns#" term="Eclipse" /><category scheme="http://www.blogger.com/atom/ns#" term="OPath" /><title>EVars Update</title><content type="html">Based on the awesome feedback, I have been &lt;a href="http://code.google.com/p/evars/updates/list"&gt;doing some offline development&lt;/a&gt; on &lt;a href="http://code.google.com/p/evars/"&gt;EVars&lt;/a&gt; plug-in lately. I have added some basic documentation on &lt;a href="http://code.google.com/p/evars/w/list"&gt;wiki&lt;/a&gt;. Installation is now easy, let P2 do the work to &lt;a href="http://evars.googlecode.com/svn/evars-update"&gt;install/update&lt;/a&gt; the plug-in (it's a struggle to host update-site with google code).&lt;br /&gt;&lt;br /&gt;One of the most exciting feature (Which I can't stop talking about) is value based filtering. Now you can have all the powers of predicate expression, how about searching a map like map//key['@user.*']/.. to select entries matching regular expression user.* ? This update also includes support for relational operators so you can search exactly you want like this //value[count &gt; n] .&lt;br /&gt;&lt;br /&gt;I have uploaded &lt;a href="http://code.google.com/p/evars/wiki/OPathGrammar"&gt;OPath grammar&lt;/a&gt; for the language enthusiasts (left factored, left recursion free). One feedback was 'experiencing some unresponsive behavior for huge graphs' I have addressed that to some extent by integrating progress monitoring and asynchronous interpretation job.&lt;br /&gt;&lt;br /&gt;Thanks for the feedback! Also, for those at &lt;a href="http://www.eclipsecon.org/2009/"&gt;EclipseCon&lt;/a&gt; have fun with your sessions!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11200164-9137207996289952548?l=blog.nirav.name' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=iTf0_P46CPw:h68tzoXEP1U:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=iTf0_P46CPw:h68tzoXEP1U:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=iTf0_P46CPw:h68tzoXEP1U:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=iTf0_P46CPw:h68tzoXEP1U:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=iTf0_P46CPw:h68tzoXEP1U:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=iTf0_P46CPw:h68tzoXEP1U:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/nirav/~4/iTf0_P46CPw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nirav.name/feeds/9137207996289952548/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=11200164&amp;postID=9137207996289952548" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/9137207996289952548?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/9137207996289952548?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/nirav/~3/iTf0_P46CPw/evars-update.html" title="EVars Update" /><author><name>Nirav Thaker</name><uri>http://www.blogger.com/profile/07204297663478577248</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_PebfjbIpLKY/SYO5wL9XgUI/AAAAAAAAByY/MhgUWfUq5Hc/S220/DSCN1212+-+Copy.JPG" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.nirav.name/2009/03/evars-update.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0QGQX86fyp7ImA9WxVVGEw.&quot;"><id>tag:blogger.com,1999:blog-11200164.post-4319881878720535329</id><published>2009-03-10T19:37:00.012-04:00</published><updated>2009-03-11T20:55:20.117-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-11T20:55:20.117-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Evars" /><category scheme="http://www.blogger.com/atom/ns#" term="Debug" /><category scheme="http://www.blogger.com/atom/ns#" term="Eclipse" /><title>Improve your debugging speed with EVars Eclipse plugin</title><content type="html">Update: Added alternate link to screen-cast. Workaround to start plug-in&lt;br /&gt;&lt;br /&gt;I have been debugging a lot lately which included open source libraries, closed source web-service engine and parts of closed source application server (WebLogic). During this painful debug-fest I felt a strong need for several features missing in Eclipse (NetBeans as well, for that matter) . Debugging closed applications is a pain beyond imagination, even with IDE integrated decompilers, it takes incredible amount of patience and time to debug.&lt;br /&gt;&lt;br /&gt;To improve productivity (or prevent burnout), I jotted down a plugin to export/import live variables, filter variables view  with a xpath like expressions etc. The plugin, called &lt;a href="http://code.google.com/p/evars"&gt;'evars'&lt;/a&gt;, features a small expression interpreter (similar to xpath) which can do a wonderful job of filtering variables on current stackframe. It also allows you to export variables to a file and reload them at a later point.&lt;br /&gt;&lt;br /&gt;For the first time, I have attempted to create a screencast to explain its usefulness. &lt;a href="http://nirav.thaker.googlepages.com/evars.htm" target="_blank"&gt;You may watch it over here&lt;/a&gt; [10mb non-streaming, 1275x860], &lt;a href="http://evars.googlecode.com/files/evars.swf" target="_blank"&gt;alternate link&lt;/a&gt; (open with your browser).&lt;br /&gt;&lt;br /&gt;I have also created a beta release to see if it finds any interest which you can &lt;a href="http://evars.googlecode.com/files/name.nirav.evariablesview_1.0.0.jar"&gt;download it from here&lt;/a&gt; [JAR ~800kb, Jdk6] (&lt;a href="http://evars.googlecode.com/files/name.nirav.evariablesview_1.0.0-1.5.jar"&gt;Click here for Java 5 version&lt;/a&gt;) and drop it in dropins folder [Eclipse 3.4+]&lt;br /&gt;&lt;br /&gt;If you find it interesting, please leave feedback here.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11200164-4319881878720535329?l=blog.nirav.name' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=LThatxY3V_s:AM3w8fEvNcU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=LThatxY3V_s:AM3w8fEvNcU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=LThatxY3V_s:AM3w8fEvNcU:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=LThatxY3V_s:AM3w8fEvNcU:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=LThatxY3V_s:AM3w8fEvNcU:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=LThatxY3V_s:AM3w8fEvNcU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/nirav/~4/LThatxY3V_s" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nirav.name/feeds/4319881878720535329/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=11200164&amp;postID=4319881878720535329" title="11 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/4319881878720535329?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/4319881878720535329?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/nirav/~3/LThatxY3V_s/improve-your-debugging-speed-with-evars.html" title="Improve your debugging speed with EVars Eclipse plugin" /><author><name>Nirav Thaker</name><uri>http://www.blogger.com/profile/07204297663478577248</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_PebfjbIpLKY/SYO5wL9XgUI/AAAAAAAAByY/MhgUWfUq5Hc/S220/DSCN1212+-+Copy.JPG" /></author><thr:total>11</thr:total><feedburner:origLink>http://blog.nirav.name/2009/03/improve-your-debugging-speed-with-evars.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkcMQ30zeyp7ImA9WxVVFkg.&quot;"><id>tag:blogger.com,1999:blog-11200164.post-4940222218178113666</id><published>2009-03-09T20:05:00.000-04:00</published><updated>2009-03-10T00:08:02.383-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-10T00:08:02.383-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Pragmatic" /><category scheme="http://www.blogger.com/atom/ns#" term="Loud Thinking" /><title>Two types of Architects</title><content type="html">I am amused by these creatures called 'Architects' in software development. In recent phenomena, They are available under numerous headings such as 'Software architect', 'Solution architect', 'Front end architect', 'Enterprise architect' and so on. To me, in what they really do, there are only two broad types of architects. My brain timed out while guessing fancy names for them so their description is in order with uninteresting machine generated type names, it is up to you to decide what to call them.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;The Type1 Architect:&lt;/span&gt;&lt;br /&gt;A Type1 architect lives near 'The well of Eternal dreams' in his tranquility. He speaks high of latest technologies, buzzwords from internet meme. He actively attends all expensive technology conferences, management meetings, and is excellent at presenting management with summaries of what he may possibly be capable of.&lt;br /&gt;The ideal Type1 architect rarely talks to developer and/or QA teams, he doesn't really waste his time for trivial details and is religious about development-by-exception (don't stop coding/testing till you hit the roadblock); he would rather express his greatness with another Type1 architect who can really appreciate him. He is a huge fan of his super-mega automated, ultra-modern cloud-based, universally-ultimate end-of-the-world web 9000.0 ready architecture, which he thoughtfully insists in applying wherever it's not needed. His thinking is beyond languages, frameworks, platforms and business needs, no mortal can grasp what he thinks. He usually masters the skill of overkill and is full of without-the-box ideas. I can really go on for next few weeks talking about this type of architects but I need to talk about the other type so I will stop here.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;The Type2 Architect:&lt;/span&gt;&lt;br /&gt;This type of dude is a very simple earthliving guy, he lives by the belief that success of software development efforts is dependent only on the people who are involved in it rather than tools and technologies. He holds the shared vision of what the end product is likely to be and thrives at driving the team efforts in that direction &lt;span style="font-style: italic;"&gt;without managing &lt;/span&gt;them. He doesn't fear coding (more like the existing code fears for its life when he starts coding), testing or training whenever he needs to do it. He believes in pleasing management with frequent stable releases than presentation of the obvious. He communicates with everyone, right from tester to business analysts and managers frequently, this guy is often found roaming around discussing with different team members.&lt;br /&gt;&lt;br /&gt;So if you are an architect, what type are you?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11200164-4940222218178113666?l=blog.nirav.name' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=72BXKwyrL4M:DDnl8YMUUt4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=72BXKwyrL4M:DDnl8YMUUt4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=72BXKwyrL4M:DDnl8YMUUt4:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=72BXKwyrL4M:DDnl8YMUUt4:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=72BXKwyrL4M:DDnl8YMUUt4:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=72BXKwyrL4M:DDnl8YMUUt4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/nirav/~4/72BXKwyrL4M" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nirav.name/feeds/4940222218178113666/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=11200164&amp;postID=4940222218178113666" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/4940222218178113666?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/4940222218178113666?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/nirav/~3/72BXKwyrL4M/two-types-of-architects.html" title="Two types of Architects" /><author><name>Nirav Thaker</name><uri>http://www.blogger.com/profile/07204297663478577248</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_PebfjbIpLKY/SYO5wL9XgUI/AAAAAAAAByY/MhgUWfUq5Hc/S220/DSCN1212+-+Copy.JPG" /></author><thr:total>2</thr:total><feedburner:origLink>http://blog.nirav.name/2009/03/two-types-of-architects.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE4CRX49cCp7ImA9WxVQE0o.&quot;"><id>tag:blogger.com,1999:blog-11200164.post-7284279705953595576</id><published>2009-01-30T18:49:00.015-05:00</published><updated>2009-01-30T22:36:04.068-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-01-30T22:36:04.068-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Parsing" /><title>Formal grammars, parsing etc. for dummies</title><content type="html">I thought it may be useful to post summaries of what I have &lt;a href="http://books.google.com/books?id=4yVQFVvsBNAC&amp;amp;dq=engineering+a+compiler&amp;amp;printsec=frontcover&amp;amp;source=bl&amp;amp;ots=rbgQ1OvQHy&amp;amp;sig=CrE6Ecva7LK6uhBf1Mu_nL5ocpk&amp;amp;hl=en&amp;amp;ei=b7ODSYC7DIqhtwfzq5jICQ&amp;amp;sa=X&amp;amp;oi=book_result&amp;amp;resnum=6&amp;amp;ct=result"&gt;been reading recently&lt;/a&gt;. In this post, I will try to explain some basic grammar and parsing stuff in as simple way as I can (omitting all the academic complacency) .&lt;br /&gt;&lt;br /&gt;A grammar defines a language with a set of rules of type x -&gt; y, where x is left hand side of the rule and y is right hand side of the rule. x and y can be either expandable or literals depending on grammar type (math zealot? read terminals and non-terminals).&lt;br /&gt;&lt;br /&gt;Chomsky hierarchy defines four levels of grammar (although these are &lt;a href="http://en.wikipedia.org/wiki/Template:Formal_languages_and_grammars"&gt;not the only grammar types&lt;/a&gt; in literature but &lt;a href="http://web.mit.edu/linguistics/people/faculty/chomsky/index.html"&gt;Chomsky&lt;/a&gt; is cool dude in linguistic literature, hence the list):&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;0. Unrestricted grammar:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Languages based on such grammar can have any rule for derivation (which usually means any text can belong to a possible unrestricted grammar like 'yo dawg', where 'yo dawg -&gt; u'). However, it is possible to define a language with unrestricted grammar which is also Turing complete. A language based on unrestricted grammar is extremely difficult to parse, but not completely impossible. Such language doesn't necessarily make sense, e.g. It is possible to create a math expression such as this 1++1=1--*1=1 in an unrestricted language, as well as an unrestricted English statement such as this: "all your bases are belong to us".&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;1. Context sensitive grammar:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A language defined with CSG may represent all the natural languages. Such grammar is defined with a set of rules where both sides may have expandable symbols (e.g. "a" B "c" -&gt; "a" "x" "c"). It is very difficult to build a parser which can parse CSG.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;2. Context free grammar:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;All programming language grammars are context free grammars. It can have only one expandable symbol on left hand side of a grammar rule and is very easy to parse. E.g. X -&gt; "if" (y) z | "if" (y) z "else" (X), where y and z can be represented as other statements of the same grammar. There are several well known parsing techniques to parse CFGs such as:&lt;br /&gt;&lt;br /&gt;- LL(1)-LL(k) with a recursive descent parser (top down parsers with look-aheads 1 to k) and,&lt;br /&gt;- Bottom up parsers such as LR(1)  and LALR which can parse more CFGs than LL parsers (generally shift reduce parsers).&lt;br /&gt;&lt;br /&gt;LL parser starts with &lt;span style="color: rgb(255, 0, 0);"&gt;L&lt;/span&gt;eft to right and always expands &lt;span style="color: rgb(255, 0, 0);"&gt;L&lt;/span&gt;eft expandable symbol first (think of queue) where as LR starts with &lt;span style="color: rgb(255, 0, 0);"&gt;L&lt;/span&gt;eft to right but expands &lt;span style="color: rgb(255, 0, 0);"&gt;R&lt;/span&gt;ight symbol first (think of stack).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;3. Regular grammar:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A regular expression is a language defined by a regular grammar. It is represented as X -&gt; "t" | "t" Y, where Y represents expandable symbol and always follows literal (if it exists). E.g. ab*, where * may be an expandable symbol defined to mean one or more occurrence of the literal it followed as a grammar rule.&lt;br /&gt;&lt;br /&gt;Each grammar type above is a subset of previous grammar type, meaning every regular grammar is context free grammar, every context free grammar is also context sensitive grammar and so on.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11200164-7284279705953595576?l=blog.nirav.name' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=esYh2YqHXiA:6yKe7yiZcdM:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=esYh2YqHXiA:6yKe7yiZcdM:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=esYh2YqHXiA:6yKe7yiZcdM:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=esYh2YqHXiA:6yKe7yiZcdM:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=esYh2YqHXiA:6yKe7yiZcdM:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=esYh2YqHXiA:6yKe7yiZcdM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/nirav/~4/esYh2YqHXiA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nirav.name/feeds/7284279705953595576/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=11200164&amp;postID=7284279705953595576" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/7284279705953595576?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/7284279705953595576?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/nirav/~3/esYh2YqHXiA/formal-grammars-parsing-etc-for-dummies.html" title="Formal grammars, parsing etc. for dummies" /><author><name>Nirav Thaker</name><uri>http://www.blogger.com/profile/07204297663478577248</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_PebfjbIpLKY/SYO5wL9XgUI/AAAAAAAAByY/MhgUWfUq5Hc/S220/DSCN1212+-+Copy.JPG" /></author><thr:total>1</thr:total><feedburner:origLink>http://blog.nirav.name/2009/01/formal-grammars-parsing-etc-for-dummies.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU4MRHY4eip7ImA9WxVRFUU.&quot;"><id>tag:blogger.com,1999:blog-11200164.post-2921994332252923070</id><published>2009-01-21T19:22:00.012-05:00</published><updated>2009-01-21T20:33:05.832-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-01-21T20:33:05.832-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Debug" /><category scheme="http://www.blogger.com/atom/ns#" term="Eclipse" /><title>Mutual recursion fun with Eclipse Debug model</title><content type="html">&lt;style type="text/css"&gt;  &lt;!--   @page { margin: 0.79in }   P { margin-bottom: 0.08in }  --&gt;  &lt;/style&gt; &lt;p style="margin-bottom: 0in;"&gt;I rarely come across real-world data structures which are inherently mutually recursive (a.k.a. Daisy chain recursion in CS literature). Recently, while writing a plug-in related to eclipse.debug, I came across this interesting data structure.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.eclipse.org/articles/Article-Debugger/images/debug_model.gif"&gt;&lt;img style="cursor: pointer; width: 408px; height: 608px;" src="http://www.eclipse.org/articles/Article-Debugger/images/debug_model.gif" alt="" border="0" /&gt;&lt;/a&gt; &lt;a href="http://www.eclipse.org/articles/Article-Debugger/how-to.html"&gt;Source Eclipse.org&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p style="margin-bottom: 0in;"&gt;Observe the IVariable ←→  IValue  relationship (although most relationships in this object-model is mutually recursive), given an implementation of this model (say JDI) how do you clone an object-tree representing variables on a stack-frame?&lt;/p&gt;  &lt;p style="margin-bottom: 0in;"&gt;The answer is simple: assuming implementation classes Variable and Value just write a simple function to clone variables one by one:&lt;/p&gt;&lt;br /&gt;&lt;pre style="background: none repeat scroll 0% 0%; color: rgb(0, 0, 0); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;&lt;span style="color: rgb(127, 0, 85); font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: rgb(127, 0, 85); font-weight: bold;"&gt;class&lt;/span&gt; Variable {&lt;br /&gt;…&lt;br /&gt;&lt;span style="color: rgb(127, 0, 85); font-weight: bold;"&gt;private&lt;/span&gt; Value value;&lt;br /&gt;…&lt;br /&gt;&lt;span style="color: rgb(127, 0, 85); font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: rgb(127, 0, 85); font-weight: bold;"&gt;static&lt;/span&gt; Variable create(IVariable var) {&lt;br /&gt;  Variable v = &lt;span style="color: rgb(127, 0, 85); font-weight: bold;"&gt;new&lt;/span&gt; Variable() ;&lt;br /&gt;  &lt;span style="color: rgb(127, 0, 85); font-weight: bold;"&gt;try&lt;/span&gt; {&lt;br /&gt;      v.setName(var.getName());&lt;br /&gt;      v.setType(var.getReferenceTypeName());&lt;br /&gt;      v.setValue(Value.create(var.getValue()));&lt;br /&gt;      &lt;span style="color: rgb(127, 0, 85); font-weight: bold;"&gt;return&lt;/span&gt; v;&lt;br /&gt;  } &lt;span style="color: rgb(127, 0, 85); font-weight: bold;"&gt;catch&lt;/span&gt; (DebugException e) {&lt;br /&gt;      ..&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Similarly for Value class:&lt;br /&gt;&lt;br /&gt;&lt;pre style="background:  none repeat scroll 0% 0%; color: rgb(0, 0, 0); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;&lt;span style="color: rgb(127, 0, 85); font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: rgb(127, 0, 85); font-weight: bold;"&gt;class&lt;/span&gt; Value {&lt;br /&gt;…&lt;br /&gt;&lt;span style="color: rgb(127, 0, 85); font-weight: bold;"&gt;private&lt;/span&gt;  Variable[] variables;&lt;br /&gt;…&lt;br /&gt;&lt;span style="color: rgb(127, 0, 85); font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: rgb(127, 0, 85); font-weight: bold;"&gt;static&lt;/span&gt; Value create(IValue var) {&lt;br /&gt;    Value v = &lt;span style="color: rgb(127, 0, 85); font-weight: bold;"&gt;new&lt;/span&gt; Value() ;&lt;br /&gt;    &lt;span style="color: rgb(127, 0, 85); font-weight: bold;"&gt;try&lt;/span&gt; {&lt;br /&gt;        v.setType(var.getReferenceTypeName());&lt;br /&gt;        v.setValue(...);&lt;br /&gt;        IVariable[] variables = value.getVariables();&lt;br /&gt;        &lt;span style="color: rgb(127, 0, 85); font-weight: bold;"&gt;if&lt;/span&gt; (variables != &lt;span style="color: rgb(127, 0, 85); font-weight: bold;"&gt;null&lt;/span&gt;) {&lt;br /&gt;            &lt;span style="color: rgb(127, 0, 85); font-weight: bold;"&gt;for&lt;/span&gt; (IVariable variable : variables)&lt;br /&gt;                v.add(Variable.create(variable));&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color: rgb(127, 0, 85); font-weight: bold;"&gt;return&lt;/span&gt; v;&lt;br /&gt;    } &lt;span style="color: rgb(127, 0, 85); font-weight: bold;"&gt;catch&lt;/span&gt; (DebugException e) {&lt;br /&gt;        ..&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p style="margin-bottom: 0in;"&gt;Statement 'Variable.create(yourJDIVariable);'  clones entire JDI object. This is one of those intuitive recursion examples which  you die to find out IRL. Interesting, isn't it?&lt;/p&gt;&lt;p style="margin-bottom: 0in;"&gt;This is how your regular stack-frame looks (Variables view):&lt;/p&gt;&lt;p style="margin-bottom: 0in;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_PebfjbIpLKY/SXfHIJkpH_I/AAAAAAAABxM/aCOz9U1TSFA/s1600-h/first.jpg"&gt;&lt;img style="cursor: pointer; width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_PebfjbIpLKY/SXfHIJkpH_I/AAAAAAAABxM/aCOz9U1TSFA/s320/first.jpg" alt="" id="BLOGGER_PHOTO_ID_5293918829819797490" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p style="margin-bottom: 0in;"&gt;&lt;br /&gt;&lt;/p&gt;And this is how it looks when you represent it using an example debug model :&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_PebfjbIpLKY/SXfHYpoLjXI/AAAAAAAABxU/armRDekUPZI/s1600-h/second.jpg"&gt;&lt;img style="cursor: pointer; width: 320px; height: 248px;" src="http://3.bp.blogspot.com/_PebfjbIpLKY/SXfHYpoLjXI/AAAAAAAABxU/armRDekUPZI/s320/second.jpg" alt="" id="BLOGGER_PHOTO_ID_5293919113302478194" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11200164-2921994332252923070?l=blog.nirav.name' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=t7O1YA0SyNE:1HbDrJ43Kzg:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=t7O1YA0SyNE:1HbDrJ43Kzg:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=t7O1YA0SyNE:1HbDrJ43Kzg:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=t7O1YA0SyNE:1HbDrJ43Kzg:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=t7O1YA0SyNE:1HbDrJ43Kzg:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=t7O1YA0SyNE:1HbDrJ43Kzg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/nirav/~4/t7O1YA0SyNE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nirav.name/feeds/2921994332252923070/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=11200164&amp;postID=2921994332252923070" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/2921994332252923070?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/2921994332252923070?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/nirav/~3/t7O1YA0SyNE/mutual-recursion-fun-with-eclipse-debug.html" title="Mutual recursion fun with Eclipse Debug model" /><author><name>Nirav Thaker</name><uri>http://www.blogger.com/profile/07204297663478577248</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_PebfjbIpLKY/SYO5wL9XgUI/AAAAAAAAByY/MhgUWfUq5Hc/S220/DSCN1212+-+Copy.JPG" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_PebfjbIpLKY/SXfHIJkpH_I/AAAAAAAABxM/aCOz9U1TSFA/s72-c/first.jpg" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://blog.nirav.name/2009/01/mutual-recursion-fun-with-eclipse-debug.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Dk8MRnY5eSp7ImA9WxRaEUk.&quot;"><id>tag:blogger.com,1999:blog-11200164.post-4507697987575822798</id><published>2008-12-05T23:37:00.004-05:00</published><updated>2008-12-13T00:08:07.821-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-12-13T00:08:07.821-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Tooling" /><category scheme="http://www.blogger.com/atom/ns#" term="PyConsole" /><category scheme="http://www.blogger.com/atom/ns#" term="Open Source" /><category scheme="http://www.blogger.com/atom/ns#" term="Eclipse" /><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><title>Introducing PyConsole!</title><content type="html">I have been pretty inactive this year, unlike what I &lt;a href="http://blog.nirav.name/2007/11/what-am-i-upto-this-year.html"&gt;planned&lt;/a&gt; (yawn, haven't heard from &lt;a href="http://www.eclipse.org/dltk/"&gt;DLTK &lt;/a&gt;since June either) . I started learning Python earlier this year and felt the need of an embedded python shell inside Eclipse. This was something &lt;a href="http://pydev.sourceforge.net/"&gt;PyDev&lt;/a&gt; is missing [Edit: &lt;a style="font-style: italic;" href="https://www.blogger.com/comment.g?blogID=11200164&amp;amp;postID=4507697987575822798"&gt;Simone&lt;/a&gt;&lt;span style="font-style: italic;"&gt; pointed out that PyDev already has &lt;a href="http://pydev.sourceforge.net/console.html"&gt;this neat feature&lt;/a&gt;, I was late to discover it&lt;/span&gt;] as compared to other &lt;a href="http://blog.nirav.name/2008/02/state-of-eclipse-based-python.html"&gt;python tools&lt;/a&gt; in Linux such as &lt;a href="http://www.die-offenbachs.de/eric/index.html"&gt;Eric&lt;/a&gt;. So I decided to write one.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://pyconsole.sf.net/"&gt;PyConsole&lt;/a&gt; is direct result of my irregular and intermittent Eclipse development (lately), it's very simple plug-in with a basic exploit of &lt;a href="http://wiki.eclipse.org/FAQ_How_do_I_write_to_the_console_from_a_plug-in%3F"&gt;Eclipse Console View&lt;/a&gt; and manages two way synchronized I/O from the python interpreter process controlled by a background Eclipse job. It provides few basic features anyone might expect from a shell such as syntax highlighting, command history etc.&lt;br /&gt;&lt;br /&gt;Here's the &lt;a href="http://pyconsole.svn.sourceforge.net/viewvc/pyconsole/trunk/"&gt;code repository&lt;/a&gt; if anyone would like to check it out. If you have suggestions or feedback please write to me or &lt;a href="http://sourceforge.net/tracker/?group_id=216852&amp;amp;atid=1039896"&gt;create a bug&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11200164-4507697987575822798?l=blog.nirav.name' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=RTtJL_zyD3g:lAuhNiua_SA:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=RTtJL_zyD3g:lAuhNiua_SA:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=RTtJL_zyD3g:lAuhNiua_SA:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=RTtJL_zyD3g:lAuhNiua_SA:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=RTtJL_zyD3g:lAuhNiua_SA:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=RTtJL_zyD3g:lAuhNiua_SA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/nirav/~4/RTtJL_zyD3g" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nirav.name/feeds/4507697987575822798/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=11200164&amp;postID=4507697987575822798" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/4507697987575822798?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/4507697987575822798?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/nirav/~3/RTtJL_zyD3g/introducing-pyconsole.html" title="Introducing PyConsole!" /><author><name>Nirav Thaker</name><uri>http://www.blogger.com/profile/07204297663478577248</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_PebfjbIpLKY/SYO5wL9XgUI/AAAAAAAAByY/MhgUWfUq5Hc/S220/DSCN1212+-+Copy.JPG" /></author><thr:total>4</thr:total><feedburner:origLink>http://blog.nirav.name/2008/12/introducing-pyconsole.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D08FSX08eSp7ImA9WxVSGEQ.&quot;"><id>tag:blogger.com,1999:blog-11200164.post-8530473775346689807</id><published>2008-08-16T14:35:00.008-04:00</published><updated>2009-01-13T20:16:58.371-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-01-13T20:16:58.371-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Eclipse" /><title>Productive keyboard shortcuts for Eclipse Editors</title><content type="html">I've seen very few developers using true power of Eclipse editors, so I thought of listing few very handy shortcuts that can significantly improve your source editing and navigation speed with Eclipse.&lt;br /&gt;&lt;br /&gt;1. Ctrl + J / Ctrl + Shift + J : Inline search, meaning you can type on the fly to search text in current editor. You can use Up/Down arrow keys to navigate between matching text fragment in forward/reverse direction. This is one of the most powerful features you will find in advanced editors like Vim or Emacs.&lt;br /&gt;&lt;br /&gt;2. Ctrl + K/ Ctrl + Shift + K : Search text in forward or reverse direction.&lt;br /&gt;&lt;br /&gt;3. Ctrl + L : Go to line.&lt;br /&gt;&lt;br /&gt;4. Ctrl + Alt + Up/Down : Duplicate current line above/below. Very useful in repeatative assignment statements (Java code, eh?).&lt;br /&gt;&lt;br /&gt;5. Alt + Up/Down : Move current line up or down. Also, very handy to select current line.&lt;br /&gt;&lt;br /&gt;6. Ctrl + . OR , : This is contextual and may be specific to Java editors: if you have error or warnings in current file in editor it will navigate to them.&lt;br /&gt;&lt;br /&gt;All of these except for no. 6 are generic text editor features which are inherited by all eclipse text editors. You will realize that you will work much faster than average user if you start using these key bindings.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11200164-8530473775346689807?l=blog.nirav.name' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=I9nWKWAW-AU:qhraW3i7M8o:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=I9nWKWAW-AU:qhraW3i7M8o:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=I9nWKWAW-AU:qhraW3i7M8o:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=I9nWKWAW-AU:qhraW3i7M8o:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=I9nWKWAW-AU:qhraW3i7M8o:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=I9nWKWAW-AU:qhraW3i7M8o:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/nirav/~4/I9nWKWAW-AU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nirav.name/feeds/8530473775346689807/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=11200164&amp;postID=8530473775346689807" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/8530473775346689807?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/8530473775346689807?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/nirav/~3/I9nWKWAW-AU/productive-keyboard-shortcuts-for.html" title="Productive keyboard shortcuts for Eclipse Editors" /><author><name>Nirav Thaker</name><uri>http://www.blogger.com/profile/07204297663478577248</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_PebfjbIpLKY/SYO5wL9XgUI/AAAAAAAAByY/MhgUWfUq5Hc/S220/DSCN1212+-+Copy.JPG" /></author><thr:total>6</thr:total><feedburner:origLink>http://blog.nirav.name/2008/08/productive-keyboard-shortcuts-for.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEUHQ344fyp7ImA9WxdbEEg.&quot;"><id>tag:blogger.com,1999:blog-11200164.post-1299188962363284607</id><published>2008-08-06T11:08:00.005-04:00</published><updated>2008-08-06T15:50:32.037-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-08-06T15:50:32.037-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="AJAX" /><category scheme="http://www.blogger.com/atom/ns#" term="Opinion" /><title>Synchronizing client requests using Ajax</title><content type="html">Before few months I was dealing with a problem where I needed to synchronize the server call sequence on browser. The problem was something like this: Client code will open new window navigating to a different page, but that should happen only after post on current page. The link that new window was opening needed to be server synchronized because of database updates etc. on server.
&lt;br /&gt;
&lt;br /&gt;Being ignorant java-script developer I went ahead and put 'window.open' in onsubmit event of submit button, hoping it will be executed before form is submitted; Apparently, it failed. The event handling/dispatching/capturing in java-script is in &lt;a href="http://dev.opera.com/articles/view/timing-and-synchronization-in-javascript/"&gt;sad state&lt;/a&gt; - it's specific to browser and I must make it work for IE so the pain is obvious. To reveal some more ignorance, I thought of putting 'window.open' in onmousedown event assuming form will not be submitted till the code in onmousedown is executed
&lt;br /&gt;fully, that too failed. Then, it was clear that 'window.open' was essentially a thread fork and will execute in parallel so this event capturing is not going to work here.
&lt;br /&gt;
&lt;br /&gt;Since there was no obvious fix to my problem, I thought of using XMLHTTP for asynchronous wait to synchronize the request. I created new page which will open in a new window with javascript that handles form post in parent window, looks like following:
&lt;br /&gt;&lt;pre&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;&lt;/span&gt;&lt;span style="color: rgb(32, 64, 160);"&gt;html&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&gt;&lt;/span&gt;
&lt;br /&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;&lt;/span&gt;&lt;span style="color: rgb(32, 64, 160);"&gt;body&lt;/span&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;onload&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;"postParentWindow()"&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&gt;&lt;/span&gt;
&lt;br /&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;%&lt;/span&gt;
&lt;br /&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;out&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;print&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;"Loading Print Preview, Please wait..."&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;;&lt;/span&gt;
&lt;br /&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;%&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&gt;&lt;/span&gt;
&lt;br /&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;&lt;/span&gt;/&lt;span style="color: rgb(32, 64, 160);"&gt;body&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&gt;&lt;/span&gt;
&lt;br /&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;&lt;/span&gt;/&lt;span style="color: rgb(32, 64, 160);"&gt;html&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&gt;&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;/span&gt;
&lt;br /&gt;&lt;pre&gt;&lt;span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;script language="javascript"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;function&lt;span style="color:#ff0000;"&gt; postParentWindow&lt;/span&gt;&lt;span style="color:#2040a0;"&gt;()&lt;/span&gt;{&lt;br /&gt;  url &lt;span style="color:#4444ff;"&gt;=&lt;/span&gt; &lt;span style="color:#2040a0;"&gt;window&lt;/span&gt;.&lt;span style="color:#2040a0;"&gt;opener&lt;/span&gt;.&lt;span style="color:#2040a0;"&gt;document&lt;/span&gt;.&lt;span style="color:#2040a0;"&gt;forms&lt;/span&gt;[&lt;span style="color:#008000;"&gt;'form'&lt;/span&gt;].&lt;span style="color:#2040a0;"&gt;action&lt;/span&gt;&lt;br /&gt;  params &lt;span style="color:#4444ff;"&gt;=&lt;/span&gt; getFormInputValues(&lt;span style="color:#2040a0;"&gt;window&lt;/span&gt;.&lt;span style="color:#2040a0;"&gt;opener&lt;/span&gt;.&lt;span style="color:#2040a0;"&gt;document&lt;/span&gt;.&lt;span style="color:#2040a0;"&gt;forms&lt;/span&gt;[&lt;span style="color:#008000;"&gt;'form'&lt;/span&gt;]) + &lt;span style="color:#008000;"&gt;"&amp;amp;form:Submit=Save Page"&lt;/span&gt;&lt;span style="color:#4444ff;"&gt;;&lt;/span&gt;&lt;br /&gt;  makePOSTRequest(url, params)&lt;span style="color:#4444ff;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#4444ff;"&gt;}&lt;br /&gt;&lt;/script&gt;
&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;/pre&gt;getFormValues is a function which concatenates all the input's selected values and makes a request string. More interesting things are done in makePOSTRequest method:
&lt;br /&gt;&lt;pre&gt;&lt;blockquote&gt;var http_request &lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt; false&lt;span style="color: rgb(68, 68, 255);"&gt;;&lt;/span&gt;
&lt;br /&gt;function&lt;span style="color: rgb(255, 0, 0);"&gt; makePOSTRequest&lt;/span&gt;&lt;span style="color: rgb(32, 64, 160);"&gt;(url, parameters)&lt;/span&gt; {
&lt;br /&gt;http_request &lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt; false&lt;span style="color: rgb(68, 68, 255);"&gt;;&lt;/span&gt;
&lt;br /&gt;try &lt;span style="color: rgb(68, 68, 255);"&gt;{&lt;/span&gt;
&lt;br /&gt;     http_request &lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt; newActiveXObject(&lt;span style="color: rgb(0, 128, 0);"&gt;"Msxml2.XMLHTTP"&lt;/span&gt;)&lt;span style="color: rgb(68, 68, 255);"&gt;;&lt;/span&gt;
&lt;br /&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;}&lt;/span&gt; catch (e) &lt;span style="color: rgb(68, 68, 255);"&gt;{&lt;/span&gt;
&lt;br /&gt;      try &lt;span style="color: rgb(68, 68, 255);"&gt;{&lt;/span&gt;
&lt;br /&gt;          http_request &lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt; new ActiveXObject(&lt;span style="color: rgb(0, 128, 0);"&gt;"Microsoft.XMLHTTP"&lt;/span&gt;)&lt;span style="color: rgb(68, 68, 255);"&gt;;&lt;/span&gt;
&lt;br /&gt;      &lt;span style="color: rgb(68, 68, 255);"&gt;}&lt;/span&gt; catch (e) &lt;span style="color: rgb(68, 68, 255);"&gt;{&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;}&lt;/span&gt;
&lt;br /&gt;   &lt;span style="color: rgb(68, 68, 255);"&gt;}&lt;/span&gt;
&lt;br /&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;}&lt;/span&gt;
&lt;br /&gt;http_request.onreadystatechange &lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt; navigateToOtherPage&lt;span style="color: rgb(68, 68, 255);"&gt;;&lt;/span&gt;
&lt;br /&gt;http_request.&lt;span style="color: rgb(165, 42, 42);"&gt;open&lt;/span&gt;(&lt;span style="color: rgb(0, 128, 0);"&gt;'POST'&lt;/span&gt;, url, true)&lt;span style="color: rgb(68, 68, 255);"&gt;;&lt;/span&gt;
&lt;br /&gt;http_request.setRequestHeader(&lt;span style="color: rgb(0, 128, 0);"&gt;"Content-type"&lt;/span&gt;, &lt;span style="color: rgb(0, 128, 0);"&gt;"application/x-www-form-urlencoded"&lt;/span&gt;)&lt;span style="color: rgb(68, 68, 255);"&gt;;&lt;/span&gt;
&lt;br /&gt;http_request.setRequestHeader(&lt;span style="color: rgb(0, 128, 0);"&gt;"Content-length"&lt;/span&gt;, parameters.&lt;span style="color: rgb(32, 64, 160);"&gt;length&lt;/strong&gt;&lt;/span&gt;)&lt;span style="color: rgb(68, 68, 255);"&gt;;&lt;/span&gt;
&lt;br /&gt;http_request.setRequestHeader(&lt;span style="color: rgb(0, 128, 0);"&gt;"Connection"&lt;/span&gt;, &lt;span style="color: rgb(0, 128, 0);"&gt;"close"&lt;/span&gt;)&lt;span style="color: rgb(68, 68, 255);"&gt;;&lt;/span&gt;
&lt;br /&gt;http_request.send(parameters)&lt;span style="color: rgb(68, 68, 255);"&gt;;&lt;/span&gt;
&lt;br /&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;}&lt;/span&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;strong&gt;function&lt;span style="color: rgb(255, 0, 0);"&gt; navigateToOtherPage&lt;/span&gt;&lt;span style="color: rgb(32, 64, 160);"&gt;()&lt;/span&gt; {&lt;/strong&gt;
&lt;br /&gt;&lt;strong&gt;if&lt;/strong&gt; (http_request.readyState &lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;4&lt;/span&gt;) &lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt;
&lt;br /&gt;  &lt;strong&gt;if&lt;/strong&gt; (http_request.&lt;span style="color: rgb(32, 64, 160);"&gt;&lt;strong&gt;status&lt;/strong&gt;&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;200&lt;/span&gt;) &lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt;
&lt;br /&gt;    &lt;span style="color: rgb(32, 64, 160);"&gt;&lt;strong&gt;window&lt;/strong&gt;&lt;/span&gt;.navigate(&lt;span style="color: rgb(0, 128, 0);"&gt;'newpage.jsf'&lt;/span&gt;)&lt;span style="color: rgb(68, 68, 255);"&gt;;&lt;/span&gt;
&lt;br /&gt;  &lt;span style="color: rgb(68, 68, 255);"&gt;}&lt;/span&gt; else &lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt;
&lt;br /&gt;    &lt;span style="color: rgb(165, 42, 42);"&gt;alert&lt;/span&gt;(&lt;span style="color: rgb(0, 128, 0);"&gt;'There was a problem with the request.'&lt;/span&gt;)&lt;span style="color: rgb(68, 68, 255);"&gt;;&lt;/span&gt;
&lt;br /&gt;  &lt;span style="color: rgb(68, 68, 255);"&gt;&lt;/span&gt;
&lt;br /&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;}&lt;/span&gt;
&lt;br /&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;}&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;/span&gt;
&lt;br /&gt;&lt;/pre&gt;(Note: This code completely disregards browser compatibility and good error handling etc.) The important thing here is, we can assign a function to XMLHTTP object that will be executed after server response is received so that serves my purpose of synchronizing the request. I find this use of AJAX pretty useful in building stateful web-applications. The code might look very crude but powerful abstractions can be built over it to make a nice utility framework for such use-cases.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11200164-1299188962363284607?l=blog.nirav.name' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=3Kf6oCJ0Cl8:K58i7dCDDk0:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=3Kf6oCJ0Cl8:K58i7dCDDk0:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=3Kf6oCJ0Cl8:K58i7dCDDk0:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=3Kf6oCJ0Cl8:K58i7dCDDk0:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=3Kf6oCJ0Cl8:K58i7dCDDk0:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=3Kf6oCJ0Cl8:K58i7dCDDk0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/nirav/~4/3Kf6oCJ0Cl8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nirav.name/feeds/1299188962363284607/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=11200164&amp;postID=1299188962363284607" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/1299188962363284607?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/1299188962363284607?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/nirav/~3/3Kf6oCJ0Cl8/synchronizing-client-requests-using.html" title="Synchronizing client requests using Ajax" /><author><name>Nirav Thaker</name><uri>http://www.blogger.com/profile/07204297663478577248</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_PebfjbIpLKY/SYO5wL9XgUI/AAAAAAAAByY/MhgUWfUq5Hc/S220/DSCN1212+-+Copy.JPG" /></author><thr:total>2</thr:total><feedburner:origLink>http://blog.nirav.name/2008/08/synchronizing-client-requests-using.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEUCRnYzeyp7ImA9WxVSGEQ.&quot;"><id>tag:blogger.com,1999:blog-11200164.post-773264659314821129</id><published>2008-08-05T17:00:00.006-04:00</published><updated>2009-01-13T20:24:27.883-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-01-13T20:24:27.883-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Frustrations" /><title>What's wrong with HP Quality Center?</title><content type="html">This entry is rant so you might just want to skip it.&lt;br /&gt;&lt;br /&gt;HP Quality Center (formerly Mercury) is a,  how so amusingly called, web-based test management tool. You will find a lot of marketing information if you ask &lt;a href="http://www.google.com/search?q=HP%20Quality%20Center"&gt;Google&lt;/a&gt;, most of which is irrelevant and may only have 1-800 number for support; because they know when you are looking for it on web, you are in trouble and no one can help you. Unfortunately, I've to spend a good amount of time on this tool these days and it inspired me a great deal to write my inexpressible ovation for this tool here.&lt;br /&gt;&lt;br /&gt;As a programmer, HP Quality center is one of the worst and most annoying tools you may have to work with (some may compare it with Lotus notes though).&lt;br /&gt;&lt;br /&gt;This tool is implemented as a giant Active X; Apparently, they didn't want to make it web-based but when sales team threatened their developers, they some how adjusted their extra-thick client to web by (evil) means of Active-X(TM) technology. It only takes one or two more minutes to load than my Eclipse instance does, in Intra-net i.e.. It  works only on lame Internet Explorer, in a sense that makes it 70% less web based. To add to the insult of using this tool, you have no option but use god-forsaken IE6 (or 7 if you are slightly lucky).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;HP Quality center crashes at will, each crash is designed scientifically so that you waste a few hours to get back to normal work before it crashes again. For example, I add attachment to a defect; next, I go and try to add comment on it and it crashes - right on time. I open new IE window; browse it and wait for it to load, log-in again (this special web based tool doesn't have feature to remember your password in an enterprise-wide SSO environment). After recalling what I was doing last, I go to the defect where it crashed and try to add comment again; only to discover that it still thinks I'm working on it. 'The object is locked by user: [my userid]'. You will praise arcane brilliance imbued in this tool because these problems disappears randomly once it pisses you off - it knows when.&lt;br /&gt;&lt;br /&gt;Some more praise on it's resource utilization, so one can't wonder why it  is rightfully web-based. HP Quality Center uses ~120mb of your core if you have no defects in your view. This amazing tool can make your wish to see memory usage on crack come true, have 50-40 defects in your view and see the difference.&lt;br /&gt;&lt;br /&gt;This is only the tip of the iceberg but gives you bigger picture and idea why companies make more money in support, there's always room for new version, patch, hotfix etc. Why in the world people pay for such crap? there are ton of free alternatives which are hundred times better and are totally free. And the other day someone was complaining about open-source tool usability...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11200164-773264659314821129?l=blog.nirav.name' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=g5H597kxKUc:cvFMcJZ_uwU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=g5H597kxKUc:cvFMcJZ_uwU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=g5H597kxKUc:cvFMcJZ_uwU:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=g5H597kxKUc:cvFMcJZ_uwU:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=g5H597kxKUc:cvFMcJZ_uwU:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=g5H597kxKUc:cvFMcJZ_uwU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/nirav/~4/g5H597kxKUc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nirav.name/feeds/773264659314821129/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=11200164&amp;postID=773264659314821129" title="31 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/773264659314821129?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/773264659314821129?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/nirav/~3/g5H597kxKUc/whats-wrong-with-hp-quality-center.html" title="What's wrong with HP Quality Center?" /><author><name>Nirav Thaker</name><uri>http://www.blogger.com/profile/07204297663478577248</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_PebfjbIpLKY/SYO5wL9XgUI/AAAAAAAAByY/MhgUWfUq5Hc/S220/DSCN1212+-+Copy.JPG" /></author><thr:total>31</thr:total><feedburner:origLink>http://blog.nirav.name/2008/08/whats-wrong-with-hp-quality-center.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkUARHk_cCp7ImA9WxZaEEs.&quot;"><id>tag:blogger.com,1999:blog-11200164.post-4572657121733935396</id><published>2008-04-24T15:40:00.007-04:00</published><updated>2008-04-24T16:17:25.748-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-04-24T16:17:25.748-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="How-to" /><category scheme="http://www.blogger.com/atom/ns#" term="Hibernate" /><title>How to: Always eagerly load objects from database with Hibernate 3 (without changing configuration xmls)</title><content type="html">So it was getting annoying to debug my app. with Hibernate 3 for it's '&lt;span style="font-style: italic;"&gt;lazy load everything by default&lt;/span&gt;' feature. Every time I wanted to see what's the value of some collection I will see these weird CGLIB proxy members lurking in debug views.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span style="color: rgb(32, 64, 160);"&gt;CGLIB&lt;/span&gt;$&lt;span style="color: rgb(32, 64, 160);"&gt;CALLBACK_0&lt;/span&gt;    &lt;span style="color: rgb(32, 64, 160);"&gt;org&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;hibernate&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;proxy&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;pojo&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;cglib&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;CGLIBLazyInitializer&lt;/span&gt;@9be3aa&lt;br /&gt;&lt;strong&gt;class&lt;/strong&gt;$&lt;span style="color: rgb(32, 64, 160);"&gt;net&lt;/span&gt;$&lt;span style="color: rgb(32, 64, 160);"&gt;sf&lt;/span&gt;$&lt;span style="color: rgb(32, 64, 160);"&gt;cglib&lt;/span&gt;$&lt;span style="color: rgb(32, 64, 160);"&gt;proxy&lt;/span&gt;$&lt;span style="color: rgb(32, 64, 160);"&gt;InvocationHandler&lt;/span&gt;    &lt;strong&gt;interface&lt;/strong&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;net&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;sf&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;cglib&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;proxy&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;InvocationHandler&lt;/span&gt;&lt;br /&gt;&lt;strong&gt;class&lt;/strong&gt;$&lt;span style="color: rgb(32, 64, 160);"&gt;net&lt;/span&gt;$&lt;span style="color: rgb(32, 64, 160);"&gt;sf&lt;/span&gt;$&lt;span style="color: rgb(32, 64, 160);"&gt;cglib&lt;/span&gt;$&lt;span style="color: rgb(32, 64, 160);"&gt;proxy&lt;/span&gt;$&lt;span style="color: rgb(32, 64, 160);"&gt;NoOp&lt;/span&gt;    &lt;strong&gt;interface&lt;/strong&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;net&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;sf&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;cglib&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;proxy&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;NoOp&lt;/span&gt;&lt;br /&gt;&lt;strong&gt;class&lt;/strong&gt;$&lt;span style="color: rgb(32, 64, 160);"&gt;org&lt;/span&gt;$&lt;span style="color: rgb(32, 64, 160);"&gt;hibernate&lt;/span&gt;$&lt;span style="color: rgb(32, 64, 160);"&gt;proxy&lt;/span&gt;$&lt;span style="color: rgb(32, 64, 160);"&gt;pojo&lt;/span&gt;$&lt;span style="color: rgb(32, 64, 160);"&gt;BasicLazyInitializer&lt;/span&gt;    &lt;strong&gt;null&lt;/strong&gt;&lt;br /&gt;&lt;span style="color: rgb(32, 64, 160);"&gt;componentIdType&lt;/span&gt;    &lt;strong&gt;null&lt;/strong&gt;&lt;br /&gt;&lt;span style="color: rgb(32, 64, 160);"&gt;constructed&lt;/span&gt;    &lt;strong&gt;true&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;For every association I would either evaluate the code or create expressions to see what's coming from DB. Lazy loading makes debugging more slower than it already is. What's the big deal?, you will say, Just go ahead and change configuration to lazy-load = "false". Well, I can do it but changing more than five hundred .hbm.xml files will help me more with retiring early than fixing the problem at hand.&lt;br /&gt;&lt;br /&gt;So before it becomes nightmare for me I thought of hacking hibernate to make it eagerly load entire object from database. I'm saying hacking because there's no API in Session or SessionFactory interfaces that would allow you to unwrap these un-dead proxies automatically.&lt;br /&gt;&lt;br /&gt;Here's how you can hack hibernate to prevent lazy loading:&lt;br /&gt;&lt;br /&gt;The basic idea of making hibernate do what you want is to invert it's assumption, i.e. make everything load eager by default, we'll plug ourself to Mappings class and will force eager load implicitely. Follow these steps:&lt;br /&gt;&lt;br /&gt;1. First create a class in &lt;span style="font-weight: bold;"&gt;org.hibernate.cfg&lt;/span&gt; package which extends Mappings:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;strong&gt;package org.hibernate.cfg;&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;strong&gt;import java.util.List;&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;strong&gt;import java.util.Map;&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;strong&gt;import org.hibernate.MappingException;&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;strong&gt;import org.hibernate.mapping.PersistentClass;&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;public&lt;/strong&gt; &lt;strong&gt;class&lt;/strong&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;MyMapping&lt;/span&gt; &lt;strong&gt;extends&lt;/strong&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;Mappings&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;public&lt;/strong&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;MyMapping&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(32, 64, 160);"&gt;Map&lt;/span&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;classes&lt;/span&gt;, &lt;span style="color: rgb(32, 64, 160);"&gt;Map&lt;/span&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;collections&lt;/span&gt;, &lt;span style="color: rgb(32, 64, 160);"&gt;Map&lt;/span&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;tables&lt;/span&gt;, &lt;span style="color: rgb(32, 64, 160);"&gt;Map&lt;/span&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;queries&lt;/span&gt;, &lt;span style="color: rgb(32, 64, 160);"&gt;Map&lt;/span&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;sqlqueries&lt;/span&gt;, &lt;span style="color: rgb(32, 64, 160);"&gt;Map&lt;/span&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;sqlResultSetMappings&lt;/span&gt;,&lt;br /&gt;                &lt;span style="color: rgb(32, 64, 160);"&gt;Map&lt;/span&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;imports&lt;/span&gt;, &lt;span style="color: rgb(32, 64, 160);"&gt;List&lt;/span&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;secondPasses&lt;/span&gt;, &lt;span style="color: rgb(32, 64, 160);"&gt;List&lt;/span&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;propertyReferences&lt;/span&gt;, &lt;span style="color: rgb(32, 64, 160);"&gt;NamingStrategy&lt;/span&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;namingStrategy&lt;/span&gt;,&lt;br /&gt;                &lt;span style="color: rgb(32, 64, 160);"&gt;Map&lt;/span&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;typeDefs&lt;/span&gt;, &lt;span style="color: rgb(32, 64, 160);"&gt;Map&lt;/span&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;filterDefinitions&lt;/span&gt;, &lt;span style="color: rgb(32, 64, 160);"&gt;Map&lt;/span&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;extendsQueue&lt;/span&gt;, &lt;span style="color: rgb(32, 64, 160);"&gt;List&lt;/span&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;auxiliaryDatabaseObjects&lt;/span&gt;,&lt;br /&gt;                &lt;span style="color: rgb(32, 64, 160);"&gt;Map&lt;/span&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;tableNamebinding&lt;/span&gt;, &lt;span style="color: rgb(32, 64, 160);"&gt;Map&lt;/span&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;columnNameBindingPerTable&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;   &lt;strong&gt;super&lt;/strong&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(32, 64, 160);"&gt;classes&lt;/span&gt;, &lt;span style="color: rgb(32, 64, 160);"&gt;collections&lt;/span&gt;, &lt;span style="color: rgb(32, 64, 160);"&gt;tables&lt;/span&gt;, &lt;span style="color: rgb(32, 64, 160);"&gt;queries&lt;/span&gt;, &lt;span style="color: rgb(32, 64, 160);"&gt;sqlqueries&lt;/span&gt;, &lt;span style="color: rgb(32, 64, 160);"&gt;sqlResultSetMappings&lt;/span&gt;, &lt;span style="color: rgb(32, 64, 160);"&gt;imports&lt;/span&gt;, &lt;span style="color: rgb(32, 64, 160);"&gt;secondPasses&lt;/span&gt;,&lt;br /&gt;         &lt;span style="color: rgb(32, 64, 160);"&gt;propertyReferences&lt;/span&gt;, &lt;span style="color: rgb(32, 64, 160);"&gt;namingStrategy&lt;/span&gt;, &lt;span style="color: rgb(32, 64, 160);"&gt;typeDefs&lt;/span&gt;, &lt;span style="color: rgb(32, 64, 160);"&gt;filterDefinitions&lt;/span&gt;, &lt;span style="color: rgb(32, 64, 160);"&gt;extendsQueue&lt;/span&gt;, &lt;span style="color: rgb(32, 64, 160);"&gt;auxiliaryDatabaseObjects&lt;/span&gt;,&lt;br /&gt;         &lt;span style="color: rgb(32, 64, 160);"&gt;tableNamebinding&lt;/span&gt;, &lt;span style="color: rgb(32, 64, 160);"&gt;columnNameBindingPerTable&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;@&lt;span style="color: rgb(32, 64, 160);"&gt;Override&lt;/span&gt;&lt;br /&gt;&lt;strong&gt;public&lt;/strong&gt; &lt;strong&gt;void&lt;/strong&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;addClass&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(32, 64, 160);"&gt;PersistentClass&lt;/span&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;persistentClass&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt; &lt;strong&gt;throws&lt;/strong&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;MappingException&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;   &lt;span style="color: rgb(32, 64, 160);"&gt;persistentClass&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;setLazy&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;strong&gt;false&lt;/strong&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;;&lt;/span&gt; &lt;span style="color: rgb(68, 68, 68);"&gt;// No Proxies, load everything in one shot&lt;/span&gt;&lt;br /&gt;   &lt;strong&gt;super&lt;/strong&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;addClass&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(32, 64, 160);"&gt;persistentClass&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The 'addClass' method achieves all we need, just make persistenceClass non-lazy, it would be lazy by default.&lt;br /&gt;&lt;br /&gt;2. Now hook this class with Configuration class.&lt;br /&gt;&lt;pre&gt;    &lt;strong&gt;public&lt;/strong&gt; &lt;strong&gt;class&lt;/strong&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;MyConfiguration&lt;/span&gt; &lt;strong&gt;extends&lt;/strong&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;Configuration&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;    @&lt;span style="color: rgb(32, 64, 160);"&gt;Override&lt;/span&gt;&lt;br /&gt;    &lt;strong&gt;public&lt;/strong&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;Mappings&lt;/span&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;createMappings&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt; &lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;        &lt;strong&gt;return&lt;/strong&gt; &lt;strong&gt;new&lt;/strong&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;MyMapping&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(32, 64, 160);"&gt;classes&lt;/span&gt;, &lt;span style="color: rgb(32, 64, 160);"&gt;collections&lt;/span&gt;, &lt;span style="color: rgb(32, 64, 160);"&gt;tables&lt;/span&gt;, &lt;span style="color: rgb(32, 64, 160);"&gt;namedQueries&lt;/span&gt;, &lt;span style="color: rgb(32, 64, 160);"&gt;namedSqlQueries&lt;/span&gt;, &lt;span style="color: rgb(32, 64, 160);"&gt;sqlResultSetMappings&lt;/span&gt;,&lt;br /&gt;                             &lt;span style="color: rgb(32, 64, 160);"&gt;imports&lt;/span&gt;, &lt;span style="color: rgb(32, 64, 160);"&gt;secondPasses&lt;/span&gt;, &lt;span style="color: rgb(32, 64, 160);"&gt;propertyReferences&lt;/span&gt;, &lt;span style="color: rgb(32, 64, 160);"&gt;namingStrategy&lt;/span&gt;, &lt;span style="color: rgb(32, 64, 160);"&gt;typeDefs&lt;/span&gt;,&lt;br /&gt;                             &lt;span style="color: rgb(32, 64, 160);"&gt;filterDefinitions&lt;/span&gt;, &lt;span style="color: rgb(32, 64, 160);"&gt;extendsQueue&lt;/span&gt;, &lt;span style="color: rgb(32, 64, 160);"&gt;auxiliaryDatabaseObjects&lt;/span&gt;, &lt;span style="color: rgb(32, 64, 160);"&gt;tableNameBinding&lt;/span&gt;,&lt;br /&gt;                             &lt;span style="color: rgb(32, 64, 160);"&gt;columnNameBindingPerTable&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt; &lt;br /&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;There you go, You can now create session factory out of it and you will get fully debug-compatible Java objects loaded from db.&lt;br /&gt;&lt;br /&gt;This was way easier to achieve than I could think hooking hairy SessionImpl beast and making org.hibernate.event.LoadEventListener.LoadType INTERNAL_LOAD_EAGER from INTERNAL_LOAD_LAZY without changing SessionImpl itself.&lt;br /&gt;&lt;br /&gt;Other than that, I found some talking about lazy loading being problematic with XStream serialization. Threre's a &lt;a href="http://jira.codehaus.org/browse/XSTR-359"&gt;JIRA defect for XStream&lt;/a&gt; relating to this as well. I faced the same few weeks before when I thought of removing hibernate from test cases, XStream basically throws up when it finds a confusing CGLIB proxy like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span style="color: rgb(32, 64, 160);"&gt;com&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;thoughtworks&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;xstream&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;converters&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;ConversionException&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;Cannot&lt;/span&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;handle&lt;/span&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;CGLIB&lt;/span&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;enhanced&lt;/span&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;proxies&lt;/span&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;with&lt;/span&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;multiple&lt;/span&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;callbacks&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;at&lt;/span&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;com&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;thoughtworks&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;xstream&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;converters&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;reflection&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;CGLIBEnhancedConverter&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;marshal&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(32, 64, 160);"&gt;CGLIBEnhancedConverter&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;java&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;85&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;at&lt;/span&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;com&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;thoughtworks&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;xstream&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;core&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;AbstractReferenceMarshaller&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;convert&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(32, 64, 160);"&gt;AbstractReferenceMarshaller&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;java&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;55&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;at&lt;/span&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;com&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;thoughtworks&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;xstream&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;core&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;TreeMarshaller&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;convertAnother&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(32, 64, 160);"&gt;TreeMarshaller&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;java&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;50&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;at&lt;/span&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;com&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;thoughtworks&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;xstream&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;core&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;TreeMarshaller&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;start&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(32, 64, 160);"&gt;TreeMarshaller&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;java&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;73&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;at&lt;/span&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;com&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;thoughtworks&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;xstream&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;core&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;ReferenceByXPathMarshallingStrategy&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;marshal&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(32, 64, 160);"&gt;ReferenceByXPathMarshallingStrategy&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;java&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;34&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;at&lt;/span&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;com&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;thoughtworks&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;xstream&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;XStream&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;marshal&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(32, 64, 160);"&gt;XStream&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;java&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;765&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;at&lt;/span&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;com&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;thoughtworks&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;xstream&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;XStream&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;marshal&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(32, 64, 160);"&gt;XStream&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;java&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;754&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;at&lt;/span&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;com&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;thoughtworks&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;xstream&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;XStream&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;toXML&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(32, 64, 160);"&gt;XStream&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;java&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;735&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;at&lt;/span&gt; &lt;span style="color: rgb(32, 64, 160);"&gt;com&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;thoughtworks&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;xstream&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;XStream&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;toXML&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: rgb(32, 64, 160);"&gt;XStream&lt;/span&gt;.&lt;span style="color: rgb(32, 64, 160);"&gt;java&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;:&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;725&lt;/span&gt;&lt;span style="color: rgb(68, 68, 255);"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;I faced this problem before as well and now I don't have to worry about it anymore. You guys can probably just go ahead and load your objects as I described above and your serialization would work fine.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11200164-4572657121733935396?l=blog.nirav.name' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=5lBD2yoT7TI:oCP9qKyCYJc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=5lBD2yoT7TI:oCP9qKyCYJc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=5lBD2yoT7TI:oCP9qKyCYJc:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=5lBD2yoT7TI:oCP9qKyCYJc:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?i=5lBD2yoT7TI:oCP9qKyCYJc:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/blogspot/nirav?a=5lBD2yoT7TI:oCP9qKyCYJc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/blogspot/nirav?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/nirav/~4/5lBD2yoT7TI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nirav.name/feeds/4572657121733935396/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=11200164&amp;postID=4572657121733935396" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/4572657121733935396?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/11200164/posts/default/4572657121733935396?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/nirav/~3/5lBD2yoT7TI/how-to-always-eagerly-load-objects-from.html" title="How to: Always eagerly load objects from database with Hibernate 3 (without changing configuration xmls)" /><author><name>Nirav Thaker</name><uri>http://www.blogger.com/profile/07204297663478577248</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="29" height="32" src="http://1.bp.blogspot.com/_PebfjbIpLKY/SYO5wL9XgUI/AAAAAAAAByY/MhgUWfUq5Hc/S220/DSCN1212+-+Copy.JPG" /></author><thr:total>3</thr:total><feedburner:origLink>http://blog.nirav.name/2008/04/how-to-always-eagerly-load-objects-from.html</feedburner:origLink></entry></feed>

