<?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:thr="http://purl.org/syndication/thread/1.0" xmlns:gd="http://schemas.google.com/g/2005" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;A0YNSHs9cCp7ImA9WxFVEUk.&quot;"><id>tag:blogger.com,1999:blog-2010391136868522221</id><updated>2010-06-10T11:23:19.568+05:30</updated><title>Thoughts on Java, Java EE and web services development</title><subtitle type="html" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://thoughts.bharathganesh.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://thoughts.bharathganesh.com/" /><author><name>Bharath Ganesh</name><uri>http://www.blogger.com/profile/09439245318320080949</uri><email>noreply@blogger.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>10</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/ThoughtsOnJavaJavaEeAndWebServicesDevelopment" /><feedburner:info uri="thoughtsonjavajavaeeandwebservicesdevelopment" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;DEQHQ3gzfCp7ImA9WxNbEU8.&quot;"><id>tag:blogger.com,1999:blog-2010391136868522221.post-5120887992812088503</id><published>2009-11-13T17:24:00.010+05:30</published><updated>2009-11-13T21:02:12.684+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-13T21:02:12.684+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Concurrency" /><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><title>Do your Iterators always fail-fast?</title><content type="html">&lt;div style="text-align: justify;"&gt;&lt;span style="font-family:verdana;"&gt;The iterators of the Collection implementations of the Java runtime throw a &lt;span style="font-style: italic;"&gt;ConcurrentModificationException&lt;/span&gt;&lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/ConcurrentModificationException.html"&gt;[1]&lt;/a&gt; when they detect that another thread has modified the Collection while a thread is iterating over it. Such iterators are generally called &lt;span style="font-style: italic;"&gt;fail-fast&lt;/span&gt; iterators.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;Looking at the implementation one can see how this has been made possible.&lt;/span&gt;&lt;span style="font-family:verdana;"&gt; The Collection subclass maintains an integer &lt;span style="font-style: italic;"&gt;modCount&lt;/span&gt; that is incremented on every operation that structurally modifies the collection (like add, remove, clear). The fail-fast iterators also contain an integer field &lt;span style="font-style: italic;"&gt;expectedModCount&lt;/span&gt; which is initialized to the &lt;span style="font-style: italic;"&gt;modCount&lt;/span&gt; while the iterator is created. Later on, during every iteration, the iterator verifies if the &lt;span style="font-style: italic;"&gt;expectedModCount&lt;/span&gt; is same as the &lt;span style="font-style: italic;"&gt;modCount &lt;/span&gt;of the collection it is iterating over. A mismatch means that the collection has been modified during the life cycle of the iterator and a &lt;span style="font-style: italic;"&gt;ConcurrentModificationException&lt;/span&gt; is thrown.&lt;/span&gt; &lt;span style="font-family:verdana;"&gt;The same happens during the collection serialization process. The modification count prior to writing to the stream should be same as the count after writing to the stream.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;But is this behavior guaranteed? Are these iterators always &lt;span style="font-style: italic;"&gt;fail-fast&lt;/span&gt;? I used to think so, until I saw the declaration of the &lt;span style="font-style: italic;"&gt;modCount&lt;/span&gt; field in the Collection implementations.&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-style: italic;"&gt;modCount&lt;/span&gt; field is not marked as volatile. This would mean - while a thread makes structural changes to the collection and increments the &lt;span style="font-style: italic;"&gt;modCount&lt;/span&gt; field, the other thread that performs the iteration or serialization might not see the incremented value of the &lt;span style="font-style: italic;"&gt;modCount&lt;/span&gt; field. It might end up doing a comparison with the stale &lt;span style="font-style: italic;"&gt;modCount&lt;/span&gt; that is visible to it. This might cause the fail-fast iterators to behave in a different way and failing at a later point.&lt;/span&gt;&lt;span style="font-family:verdana;"&gt; The field is non-volatile in Apache Harmony too.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;A bug&lt;a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6625725"&gt;[2]&lt;/a&gt; in Sun Java explains this. It says the &lt;span style="font-style: italic;"&gt;modCount&lt;/span&gt; was intentionally made non-volatile. Making it volatile would have added contention at every collection modification operation because of the memory fencing that’s required. &lt;/span&gt;&lt;span style="font-family:verdana;"&gt;&lt;br /&gt;&lt;br /&gt;Also the Javadoc clearly says &lt;span style="font-style: italic;"&gt;“fail-fast behavior cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification”.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;This behavior would be the same even on the Synchronized wrapper's of these collections.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;[1]&lt;a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6625725"&gt; http://java.sun.com/j2se/1.5.0/docs/api/java/util/ConcurrentModificationException.html&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;[2] &lt;a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6625725"&gt;http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6625725&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2010391136868522221-5120887992812088503?l=thoughts.bharathganesh.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/8cOaLMa5QGYQrxdylXPKMDZQcuY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/8cOaLMa5QGYQrxdylXPKMDZQcuY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/8cOaLMa5QGYQrxdylXPKMDZQcuY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/8cOaLMa5QGYQrxdylXPKMDZQcuY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsOnJavaJavaEeAndWebServicesDevelopment/~4/Rk9uCU8iwAw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thoughts.bharathganesh.com/feeds/5120887992812088503/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2010391136868522221&amp;postID=5120887992812088503" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2010391136868522221/posts/default/5120887992812088503?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2010391136868522221/posts/default/5120887992812088503?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThoughtsOnJavaJavaEeAndWebServicesDevelopment/~3/Rk9uCU8iwAw/do-your-iterators-always-fail-fast.html" title="Do your Iterators always fail-fast?" /><author><name>Bharath Ganesh</name><uri>http://www.blogger.com/profile/09439245318320080949</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="09026372015492934929" /></author><thr:total>5</thr:total><feedburner:origLink>http://thoughts.bharathganesh.com/2009/11/do-your-iterators-always-fail-fast.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ck4GRX4_cSp7ImA9WxJUFkg.&quot;"><id>tag:blogger.com,1999:blog-2010391136868522221.post-3682249979065333647</id><published>2009-07-15T14:51:00.003+05:30</published><updated>2009-07-15T15:12:04.049+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-15T15:12:04.049+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Server-Side" /><category scheme="http://www.blogger.com/atom/ns#" term="Logging" /><category scheme="http://www.blogger.com/atom/ns#" term="Debugging" /><category scheme="http://www.blogger.com/atom/ns#" term="Frameworks" /><title>Before You Say "It's Not Working"</title><content type="html">&lt;p style="font-family: verdana;"&gt;&lt;span style="font-size:100%;"&gt;A few days back a couple of interns working in my office came up to me and said "It's not working". They were talking about a part of an application they had built. Their application was invoking an API given out by my team and it was throwing an error. They were invoking one of our Web Services through a client side Java API provided by us. Their app was running on Tomcat and that was accessing our product that runs on another Tomcat server. So they have access to both these servers. After we exchanged a few IM messages we solved the issue - but I am sure that if they once again face any issue, they would not immediately ping and ask "Why is it not working?". &lt;/span&gt;&lt;/p&gt;&lt;p style="font-family: verdana;"&gt;&lt;span style="font-size:100%;"&gt;After we figured out the issue, I was thinking of sending a note to the interns on the first step they need to do when they face any such issue and I ended up writing this.&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt; &lt;h3 style="font-family: verdana;"&gt;&lt;span style="font-size:100%;"&gt;&lt;strong&gt;Check the Logs. Repeat- Check the Logs. &lt;/strong&gt;&lt;/span&gt;&lt;/h3&gt; &lt;p style="font-family: verdana;"&gt;&lt;span style="font-size:100%;"&gt;From what I have seen 99.99% issues get solved the moment you Check the Logs. And Yes, many people don't do that before they report the issue. In the present case, the WS client in the SDK was throwing an exception and it said &lt;em&gt;"An Error occurred with the client".&lt;/em&gt; So when they were seeing this, they actually could not make out anything. But that was at the client side. The first thing anyone should do is check the server logs. Server logs in this case would mean the Application logs on the App Server where the service is hosted and the Application server's own logs.&lt;br /&gt;&lt;br /&gt;Many times you see that the logs are way too much to deduce anything. They run into pages. And I have seen, this very fact demotivates any newbie who looks at it. In that case, If the issue can be replicated I suggest - &lt;/span&gt;&lt;/p&gt; &lt;ul style="font-family: verdana;"&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Shutdown the server and client&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Backup your logs&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Cleanup the logs directory&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Restart the servers and reproduce the issue&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style="font-family: verdana;"&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;Now the logs are much lesser and comfortable to read. Also it would be helpful if you can clearly separate the server start-up logs from the subsequent logging that happened during the issue replication. Now read that line by line and most of the times the issue would be solved. If not, read every line of the logs few more times. &lt;em&gt;Yes, Few more times. &lt;/em&gt;&lt;br /&gt;&lt;br /&gt;Still unable to figure out?&lt;/span&gt;&lt;/p&gt; &lt;h3 style="font-family: verdana;"&gt;&lt;span style="font-size:100%;"&gt;&lt;strong&gt;Check the logging level&lt;/strong&gt;&lt;/span&gt;&lt;/h3&gt; &lt;p style="font-family: verdana;"&gt;&lt;span style="font-size:100%;"&gt;Every logging framework provides you various logging levels, that you can configure. Most of them have a "debug" logging mode, which when enabled- logs the most granular details. Enable this level of logging on the application and the server. Well written applications log their code flow on to the debug level. Hence with this level of logging set, there is a very high chance that you get to reach the root of the problem.&lt;br /&gt;Even if you are not able to figure out the issue even after looking at the debug level logs, you still have helped the person who has to take a look at them. You have reduced the turnaround time. These debug logs will definitely help the API/Service developer who is going to look at your issue. He now has most of the information with him. &lt;/span&gt;&lt;/p&gt; &lt;h3 style="font-family: verdana;"&gt;&lt;span style="font-size:100%;"&gt;&lt;strong&gt;Not everything on the Server - There's client too&lt;/strong&gt;&lt;/span&gt;&lt;/h3&gt; &lt;p style="font-family: verdana;"&gt;&lt;span style="font-size:100%;"&gt;Most Apps are like this - You write a client program that accesses a service running on a server. The Application that runs on the server would also provide client side API's that would do the task of marshalling your arguments and passing it on the wire through SOAP/RMI etc. A whole lot of things happen between the time you invoke the client API and the time the message is sent on the wire (Goes out of this VM). The same is the case when you get the return message - from the time the message comes through the wire and till the time it's handed over to your client program, in the format it accepts.  Typically these are marshalling/unmarshalling tasks carried out by the client side API's. Now the concern is - what happens if something goes wrong here?&lt;br /&gt;&lt;br /&gt;Most times we ignore the logging/trace on the client side. Yes, on the client side too you could configure the logging level. The way you do this depends on the logging framework that the API you are accessing uses. Most times you would have to place a logging config properties file in the client classpath. The logging framework on the client API that you use, loads this file and determines the level of logging and the appender/handler to which logs have to be written.&lt;br /&gt;So once you have the client side logs, you would be able to figure out what really was sent from the client, what it received and other info related to marshalling/unmarshalling etc. One suggestion that I have here  - In case you have access to both the client and server ensure that both of them have the same system time. With this, you could easily track the flow from client to server and the way back with respect to time.&lt;br /&gt;&lt;br /&gt;All these really help even if you are debugging an issue on something that you have developed or are developing - Something that can be done before debugging your code by placing breakpoints or even worse - by adding those &lt;em&gt;System.out &lt;/em&gt;statements. &lt;/span&gt;&lt;/p&gt; &lt;h3 style="font-family: verdana;"&gt;&lt;span style="font-size:100%;"&gt;&lt;strong&gt;Too many threads?&lt;/strong&gt;&lt;/span&gt;&lt;/h3&gt; &lt;p style="font-family: verdana;"&gt;&lt;span style="font-size:100%;"&gt;Imagine the case where you have too many threads in your application that are doing their work simultaneously. The log records might be jumbled together. In such a scenario, to be able to uniquely identify and track the flow of one particular thread, you could have an identifier in the log record that contains the thread name. &lt;/span&gt;&lt;/p&gt; &lt;h3 style="font-family: verdana;"&gt;&lt;span style="font-size:100%;"&gt;&lt;strong&gt;Logging only failures?&lt;/strong&gt;&lt;/span&gt;&lt;/h3&gt; &lt;p style="font-family: verdana;"&gt;&lt;span style="font-size:100%;"&gt;A lot of times when your application is running on production, it would not be a very good idea to log all of the threads on the server side. You would be interested in logging only the failures. In such a case, what you typically do is - Accumulate the log records for each thread and at a later point of time depending on the success or failure of that thread, you decide whether to write its records to the log files or not. Note that these records are in the memory for the whole duration of the operation - and that could be quite expensive. &lt;/span&gt;&lt;/p&gt; &lt;h3 style="font-family: verdana;"&gt;&lt;span style="font-size:100%;"&gt;&lt;strong&gt;Beware&lt;/strong&gt;&lt;/span&gt;&lt;/h3&gt; &lt;p style="font-family: verdana;"&gt;&lt;span style="font-size:100%;"&gt;Most application servers would have their own logging framework which logs the tasks performed by the server. In certain logging frameworks you need to tell the framework when to start and stop logging on a thread. So when the server assigns a particular thread from a pool to your request it would do the job of telling the framework to start the logging. So If you explicitly create threads on an application server, these threads might not be logging information at all, though your code might have log statements.&lt;br /&gt;&lt;br /&gt;Another important thing to note is not all issues that you encounter will get replicated even &lt;em&gt;one more time&lt;/em&gt;. A lot of times I have seen that the moment you change the logging level or add a new log statement the issue goes away. Often this the case with issues related to multi-threaded programs, where even one new instruction would change the code dynamics or timing.&lt;/span&gt;&lt;/p&gt; &lt;h3 style="font-family: verdana;"&gt;&lt;span style="font-size:100%;"&gt;&lt;strong&gt;Solved. What should I do?&lt;/strong&gt;&lt;/span&gt;&lt;/h3&gt; &lt;p style="font-family: verdana;"&gt;&lt;span style="font-size:100%;"&gt; If a log information really helped you to better understand an issue, you then have a very important learning. You too should "Log" in your application. Many times I end up spending more time determining what should be logged and at what levels than the time I take to write the code. After all, logging is an &lt;em&gt;art&lt;/em&gt;.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="font-family: verdana;"&gt;&lt;span style="font-size:100%;"&gt;Update: Also appeared at &lt;a href="http://java.dzone.com/articles/its-not-working-first-steps"&gt;http://java.dzone.com/articles/its-not-working-first-steps&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2010391136868522221-3682249979065333647?l=thoughts.bharathganesh.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/cLWwJOfMdRSM9DaR-vLhft4GMFc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/cLWwJOfMdRSM9DaR-vLhft4GMFc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/cLWwJOfMdRSM9DaR-vLhft4GMFc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/cLWwJOfMdRSM9DaR-vLhft4GMFc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsOnJavaJavaEeAndWebServicesDevelopment/~4/-o15ogj7wis" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thoughts.bharathganesh.com/feeds/3682249979065333647/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2010391136868522221&amp;postID=3682249979065333647" title="9 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2010391136868522221/posts/default/3682249979065333647?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2010391136868522221/posts/default/3682249979065333647?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThoughtsOnJavaJavaEeAndWebServicesDevelopment/~3/-o15ogj7wis/before-you-say-its-not-working.html" title="Before You Say &quot;It's Not Working&quot;" /><author><name>Bharath Ganesh</name><uri>http://www.blogger.com/profile/09439245318320080949</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="09026372015492934929" /></author><thr:total>9</thr:total><feedburner:origLink>http://thoughts.bharathganesh.com/2009/07/before-you-say-its-not-working.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkYFQns-eyp7ImA9WxJRGU0.&quot;"><id>tag:blogger.com,1999:blog-2010391136868522221.post-8432696953789214549</id><published>2009-05-21T17:14:00.008+05:30</published><updated>2009-05-21T17:45:13.553+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-21T17:45:13.553+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Google" /><title>"My Location" feature on Non GPS-Enabled devices</title><content type="html">&lt;span style="font-family:verdana;"&gt;These days I often use the routing and "Get Directions" of Google Maps on my Window Mobile. And Yes, It works in India too to a great extent. One feature that always surprises me is "My Location" - Auto-detecting my geographic location. Simply because my mobile does no have a GPS receiver.&lt;br /&gt;&lt;br /&gt;So how does Google find out my location to a precision of 500 metres (sometimes 5KM when I go for a drive outside the city)? When I used to talk to people about this the unanimous answer was "Google finds it from your mobile signal". &lt;/span&gt;&lt;span style="font-family:verdana;"&gt;I too was under the assumption that Google Maps, through your handset asks your mobile phone operator the geographical co-ordinates of the tower from where it's catching the signal. &lt;/span&gt;&lt;span style="font-family:verdana;"&gt;Simple huh? But not. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt; On reading I found out that the Mobile operator does not say anything about the location coordinates of your cell tower or your device. Google does a trick here. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;Each mobile coverage cellular area (remember the &lt;a href="http://www.privateline.com/mt_cellbasics/2006/01/cell_and_sectorterminology.html"&gt;Hexagon shaped cell&lt;/a&gt;)  has a number attached to it (Some kind of serial number to uniquely identify that hexagon shaped cell). &lt;/span&gt;&lt;span style="font-family:verdana;"&gt;Google then uses a database that maps this cell number to geographical coordinates.&lt;br /&gt;&lt;br /&gt;But how does Google get the coordinates that fall under that cell?&lt;br /&gt;&lt;br /&gt;To do that, Google uses other &lt;span style="font-style: italic;"&gt;GPS-enabled&lt;/span&gt; devices that are active in your cell area. It collects data like geographical location and service cell ID from these anonymous devices.  At the end what Google has is an expanding database of service cell ID (Vs) set of coordinates that fall under that cell. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt; So that's how the "My Location" in a Non-GPS enabled device is a bigger circle and Google says its your location approximated to some specific metres. It also explains why Google does not show it at all at some remote places when I travel on the highway outside the city. Looks like nobody has gone there and activated their GPS reciever and "helped" Google :-D&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2010391136868522221-8432696953789214549?l=thoughts.bharathganesh.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/lFF-EtNmdILk7sUZU6lkoG_X7PA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/lFF-EtNmdILk7sUZU6lkoG_X7PA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/lFF-EtNmdILk7sUZU6lkoG_X7PA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/lFF-EtNmdILk7sUZU6lkoG_X7PA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsOnJavaJavaEeAndWebServicesDevelopment/~4/l6d-bh48eVk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thoughts.bharathganesh.com/feeds/8432696953789214549/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2010391136868522221&amp;postID=8432696953789214549" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2010391136868522221/posts/default/8432696953789214549?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2010391136868522221/posts/default/8432696953789214549?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThoughtsOnJavaJavaEeAndWebServicesDevelopment/~3/l6d-bh48eVk/my-location-in-non-gps-enabled-devices.html" title="&quot;My Location&quot; feature on Non GPS-Enabled devices" /><author><name>Bharath Ganesh</name><uri>http://www.blogger.com/profile/09439245318320080949</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="09026372015492934929" /></author><thr:total>1</thr:total><feedburner:origLink>http://thoughts.bharathganesh.com/2009/05/my-location-in-non-gps-enabled-devices.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0ANQH87eCp7ImA9WxVXF0o.&quot;"><id>tag:blogger.com,1999:blog-2010391136868522221.post-2860133365752117840</id><published>2009-02-16T13:15:00.004+05:30</published><updated>2009-02-16T13:39:51.100+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-02-16T13:39:51.100+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="desktop" /><category scheme="http://www.blogger.com/atom/ns#" term="Google" /><category scheme="http://www.blogger.com/atom/ns#" term="IM" /><category scheme="http://www.blogger.com/atom/ns#" term="browser" /><title>Browser - The new desktop?</title><content type="html">&lt;div  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:100%;"&gt;&lt;span class="Apple-style-span"&gt;Everyday as I use &lt;a href="http://www.google.com/talk/"&gt;Google talk&lt;/a&gt;, I wonder "Why are they not coming up with a new version? It's been almost two years now and every month they add something new to the &lt;a href="http://mail.google.com/videochat"&gt;web based talk&lt;/a&gt;." Be it invisible mode, conference chat, video chat or even emoticons - the web gadget has it all. &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:100%;"&gt;&lt;br /&gt;Whenever I read about a new feature in the web version, I make up my mind to start using the talk gadget or Gmail chat. I login through the gadget, start chatting with people, in parallel do my work, and at some point when I do an &lt;i&gt;alt+tab&lt;/i&gt; to bring the browser to focus, I see my friends irritated - I have not seen their messages for the past 30 minutes :-(  &lt;span class="Apple-style-span"&gt;&lt;br /&gt;Yes, those notifications are something I miss the most in the web version. If you minimize the browser, while a different tab was on focus, you would not be able to see the blinking Google talk tab, when someone messages you. &lt;/span&gt;For me, when it comes to an instant messenggers, the usability is much higher when it sits on the desktop.&lt;/span&gt;&lt;/div&gt;&lt;div  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:100%;"&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:100%;"&gt;And the need to use Google talk - All my friends have moved to it.&lt;i&gt; &lt;/i&gt;Otherwise I still prefer Yahoo! Messenger. &lt;i&gt;Thank God&lt;/i&gt; I am not a Linux user - they don't even have the desktop version on Linux. &lt;span class="Apple-style-span" style="font-style: italic;"&gt;Sigh.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:100%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:100%;"&gt;&lt;span class="Apple-style-span"&gt;After seeing Google Chrome, my doubts of Google never again releasing a new desktop GTalk version has gone up steeply. The new home page, the new tab page, the very idea of application shortcuts, the browser task manager etc. look a lot like Google's attempt to make the browser the new home of the PC. &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:100%;"&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:100%;"&gt;&lt;span class="Apple-style-span"&gt;Does Google consider browser to be the next desktop? Sometimes it looks like; but remember - Microsoft Sells and would continue to.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2010391136868522221-2860133365752117840?l=thoughts.bharathganesh.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/TjixiiEQ8AMoERe5oAluaQQYIag/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/TjixiiEQ8AMoERe5oAluaQQYIag/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/TjixiiEQ8AMoERe5oAluaQQYIag/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/TjixiiEQ8AMoERe5oAluaQQYIag/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsOnJavaJavaEeAndWebServicesDevelopment/~4/aa9OlJVt2Pg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thoughts.bharathganesh.com/feeds/2860133365752117840/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2010391136868522221&amp;postID=2860133365752117840" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2010391136868522221/posts/default/2860133365752117840?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2010391136868522221/posts/default/2860133365752117840?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThoughtsOnJavaJavaEeAndWebServicesDevelopment/~3/aa9OlJVt2Pg/browser-new-desktop.html" title="Browser - The new desktop?" /><author><name>Bharath Ganesh</name><uri>http://www.blogger.com/profile/09439245318320080949</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="09026372015492934929" /></author><thr:total>1</thr:total><feedburner:origLink>http://thoughts.bharathganesh.com/2009/02/browser-new-desktop.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcBQnszeCp7ImA9WxdXFEU.&quot;"><id>tag:blogger.com,1999:blog-2010391136868522221.post-7785703173654012132</id><published>2008-06-26T17:33:00.006+05:30</published><updated>2008-06-26T17:54:13.580+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-06-26T17:54:13.580+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><title>The Interesting Leak - Now at Javalobby</title><content type="html">&lt;span style="font-family:verdana;"&gt;My last two posts have been published as an &lt;a href="http://java.dzone.com/articles/the-interesting-leak"&gt;article&lt;/a&gt; at &lt;/span&gt;&lt;a style="font-family: verdana;" href="http://java.dzone.com/"&gt;Javalobby&lt;/a&gt;&lt;span style="font-family:verdana;"&gt;. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;Link: &lt;/span&gt;&lt;a style="font-family: verdana;" href="http://java.dzone.com/articles/the-interesting-leak"&gt;http://java.dzone.com/articles/the-interesting-leak&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2010391136868522221-7785703173654012132?l=thoughts.bharathganesh.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/v-cUGvq4niQzJfUooD59xaXlWVE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/v-cUGvq4niQzJfUooD59xaXlWVE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/v-cUGvq4niQzJfUooD59xaXlWVE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/v-cUGvq4niQzJfUooD59xaXlWVE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsOnJavaJavaEeAndWebServicesDevelopment/~4/kTGobl9Vi3c" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thoughts.bharathganesh.com/feeds/7785703173654012132/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2010391136868522221&amp;postID=7785703173654012132" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2010391136868522221/posts/default/7785703173654012132?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2010391136868522221/posts/default/7785703173654012132?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThoughtsOnJavaJavaEeAndWebServicesDevelopment/~3/kTGobl9Vi3c/interesting-leak-now-at-javalobby.html" title="The Interesting Leak - Now at Javalobby" /><author><name>Bharath Ganesh</name><uri>http://www.blogger.com/profile/09439245318320080949</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="09026372015492934929" /></author><thr:total>0</thr:total><feedburner:origLink>http://thoughts.bharathganesh.com/2008/06/interesting-leak-now-at-javalobby.html</feedburner:origLink><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="enclosure" href="http://feedproxy.google.com/~r/ThoughtsOnJavaJavaEeAndWebServicesDevelopment/~5/HzRkUaCUhYk/the-interesting-leak" length="0" /><feedburner:origEnclosureLink>http://java.dzone.com/articles/the-interesting-leak</feedburner:origEnclosureLink></entry><entry gd:etag="W/&quot;A0YHRXg5fip7ImA9WxdXEUQ.&quot;"><id>tag:blogger.com,1999:blog-2010391136868522221.post-3279124510123372418</id><published>2008-06-22T02:31:00.010+05:30</published><updated>2008-06-23T11:02:14.626+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-06-23T11:02:14.626+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="Garbage Collection" /><title>The leak continues..</title><content type="html">&lt;div style="text-align: justify;"&gt;&lt;span style="font-family:verdana;"&gt;This again is a follow up of my previous post - &lt;/span&gt;&lt;a style="font-family: verdana;" href="http://thoughts.bharathganesh.com/2008/06/interesting-leak.html"&gt;The Interesting Leak&lt;/a&gt;&lt;span style="font-family:verdana;"&gt;.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;I was quite amused after reading Markus' follow-up post &lt;/span&gt;&lt;a style="font-family: verdana;" href="http://kohlerm.blogspot.com/2008/06/interesting-leak-when-using.html"&gt;An interesting leak when using WeakHashMaps. &lt;/a&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;What surprised me most was If you put &lt;/span&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: verdana; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;("abc" + "def").intern();&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style="font-family:verdana;"&gt; as key in the WeakHashMap, it doesn't get GC'd whereas&lt;/span&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: verdana; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;(new String("abc") + "def").intern()&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style="font-family:verdana;"&gt;as key leads to the entry being garbage collected.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;Huh!&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;Tried all combinations. No clarity. Last resort - Pinged &lt;/span&gt;&lt;a style="font-family: verdana;" href="http://0xcafefeed.com/"&gt;Rajiv&lt;/a&gt;&lt;span style="font-family:verdana;"&gt;.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;And so went the conversation -&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;Me : If you put &lt;/span&gt;&lt;span style="font-style: italic;font-family:verdana;" &gt;("abc" + "def").intern();&lt;/span&gt;&lt;span style="font-family:verdana;"&gt; as key, it doesnt get GC'd but if you put &lt;/span&gt;&lt;span style="font-style: italic;font-family:verdana;" &gt;(new String("abc") + "def").intern()&lt;/span&gt;&lt;span style="font-family:verdana;"&gt; it gets GC'd&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;Rajiv : Decompile and see if &lt;/span&gt;&lt;span style="font-style: italic;font-family:verdana;" &gt;"abc"+"def"&lt;/span&gt;&lt;span style="font-family:verdana;"&gt; is being converted to &lt;/span&gt;&lt;span style="font-style: italic;font-family:verdana;" &gt;"abcdef"&lt;/span&gt;&lt;span style="font-family:verdana;"&gt; by javac&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;Me: Yes it is. So?&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;[This could be the clue. Am still thinking.. &lt;/span&gt;&lt;span style="font-style: italic;font-family:verdana;" &gt;tick tick tick&lt;/span&gt;]&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;Rajiv: Check if &lt;/span&gt;&lt;span style="font-style: italic;font-family:verdana;" &gt;"abcdef"== (new String("abc") + "def").intern()&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;Me: It is... printed the identitity hashcodes.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;Rajiv: In the class you have both &lt;/span&gt;&lt;span style="font-style: italic;font-family:verdana;" &gt;"abcdef"&lt;/span&gt;&lt;span style="font-family:verdana;"&gt; and &lt;/span&gt;&lt;span style="font-style: italic;font-family:verdana;" &gt;(new String("abc") + "def").intern()&lt;/span&gt;&lt;span style="font-family:verdana;"&gt; and still &lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;font-family:verdana;" &gt;(new String("abc") + "def").intern()&lt;/span&gt;&lt;span style="font-family:verdana;"&gt; gets gc'ed?&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;Me: God! Then it doesn't get gc'd.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;[Now Rajiv cracks it -&lt;/span&gt;]&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;Rajiv:&lt;/span&gt;&lt;span style="font-weight: bold;font-family:verdana;" &gt; &lt;/span&gt;&lt;span style="font-family:verdana;"&gt;"I think intern is weak map and constant pool has a strong ref&lt;/span&gt;"&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;Me: ohh!&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;Me: In that case &lt;/span&gt;&lt;span style="font-style: italic;font-family:verdana;" &gt;(new String("abc") ).intern()&lt;/span&gt;&lt;span style="font-family:verdana;"&gt;; should get GC'd right? But we saw it doesn't. The maya happens only when someString is &lt;/span&gt;&lt;span style="font-style: italic;font-family:verdana;" &gt;'+'&lt;/span&gt;&lt;span style="font-family:verdana;"&gt;d to &lt;/span&gt;&lt;span style="font-style: italic;font-family:verdana;" &gt;(new String("abc")) &lt;/span&gt;&lt;span style="font-family:verdana;"&gt;and then the resultant String is interned.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;Me: Just &lt;/span&gt;&lt;span style="font-style: italic;font-family:verdana;" &gt;(new String("abc")).intern()&lt;/span&gt;&lt;span style="font-family:verdana;"&gt; doesnt get GC'd.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;Rajiv: When you say &lt;/span&gt;&lt;span style="font-style: italic;font-family:verdana;" &gt;(new String("abc")).intern() &lt;/span&gt;&lt;span style="font-family:verdana;"&gt;there is a string "abc" in constant pool.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;Me: Yes "abc" in constant pool would be the literal we created and passed as argument to the String constructor.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;Rajiv: &lt;/span&gt;&lt;span style="font-style: italic;font-family:verdana;" &gt;(new String("abc")).intern()&lt;/span&gt;&lt;span style="font-family:verdana;"&gt; returns that string. So wont get gc'ed&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;Me: Oh yeah. Got it!&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;Me: So only when you do a "+" you get a String which is not there in constant pool and hence it gets GC'd ...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;Rajiv: ya right.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;I had earlier thought of intern pool and constant pool to be the same. But Rajiv 's prediction of intern being a weak map and constant pool holding a strong ref looks quite convincing.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;Oo la.. That solved our mystery. Thanks Rajiv:-)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2010391136868522221-3279124510123372418?l=thoughts.bharathganesh.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/G6lAsZtSNe-mQQ_jaBC03EaONCA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/G6lAsZtSNe-mQQ_jaBC03EaONCA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/G6lAsZtSNe-mQQ_jaBC03EaONCA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/G6lAsZtSNe-mQQ_jaBC03EaONCA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsOnJavaJavaEeAndWebServicesDevelopment/~4/EBZAgx29H-I" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thoughts.bharathganesh.com/feeds/3279124510123372418/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2010391136868522221&amp;postID=3279124510123372418" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2010391136868522221/posts/default/3279124510123372418?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2010391136868522221/posts/default/3279124510123372418?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThoughtsOnJavaJavaEeAndWebServicesDevelopment/~3/EBZAgx29H-I/leak-continues.html" title="The leak continues.." /><author><name>Bharath Ganesh</name><uri>http://www.blogger.com/profile/09439245318320080949</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="09026372015492934929" /></author><thr:total>0</thr:total><feedburner:origLink>http://thoughts.bharathganesh.com/2008/06/leak-continues.html</feedburner:origLink><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="enclosure" href="http://feedproxy.google.com/~r/ThoughtsOnJavaJavaEeAndWebServicesDevelopment/~5/UykeJ1vSBFk/" length="0" /><feedburner:origEnclosureLink>http://0xcafefeed.com</feedburner:origEnclosureLink></entry><entry gd:etag="W/&quot;AkQHRn0yeCp7ImA9WxdRFEU.&quot;"><id>tag:blogger.com,1999:blog-2010391136868522221.post-4032672209810433812</id><published>2008-06-04T04:20:00.000+05:30</published><updated>2008-06-03T15:48:57.390+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-06-03T15:48:57.390+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="Garbage Collection" /><title>The interesting leak</title><content type="html">&lt;span style=";font-family:verdana;font-size:100%;"  &gt;This again is one of those &lt;a href="http://www.nabble.com/Memory-Leak-at-WSDLManagerImpl-td17579537.html"&gt;interesting observations&lt;/a&gt; I ran into during some memory optimizations &lt;a href="http://cxf.apache.org/"&gt;CXF&lt;/a&gt;. Coincidently here also its a &lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/WeakHashMap.html"&gt;WeakHashMap&lt;/a&gt;.&lt;br /&gt;Consider the code snippet below.&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;public class TestWeakHashMap&lt;br /&gt;{&lt;br /&gt;   private String str1 = new String("newString1");&lt;br /&gt;   private String str2 = "literalString2";&lt;br /&gt;   private String str3 = "literalString3";&lt;br /&gt;   private String str4 = new String("newString4");&lt;br /&gt;   private Map map = new WeakHashMap();&lt;br /&gt;&lt;br /&gt;   private void testGC() throws IOException&lt;br /&gt;   {&lt;br /&gt;       map.put(str1, new Object());&lt;br /&gt;       map.put(str2, new Object());&lt;br /&gt;       map.put(str3, new Object());&lt;br /&gt;       map.put(str4, new Object());&lt;br /&gt;&lt;br /&gt;       /**&lt;br /&gt;        * Discard the strong reference to all the keys&lt;br /&gt;        */&lt;br /&gt;       str1 = null;&lt;br /&gt;       str2 = null;&lt;br /&gt;       str3 = null;&lt;br /&gt;       str4 = null;&lt;br /&gt;&lt;br /&gt;       while (true) {&lt;br /&gt;           System.gc();&lt;br /&gt;           /**&lt;br /&gt;            * Verify Full GC with the -verbose:gc option&lt;br /&gt;            * We expect the map to be emptied as the strong references to&lt;br /&gt;            * all the keys are discarded.&lt;br /&gt;            */&lt;br /&gt;           System.out.println("map.size(); = " + map.size() + "  " + map);&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;What do we expect the size of the map to be after full GC? I initially thought it should be empty. But it turned out to be 2.&lt;br /&gt;&lt;br /&gt;Look at the way the four Strings are initialized. Two of them are defined using the '&lt;span style="font-weight: bold;"&gt;new'&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;&lt;/span&gt;operator, whereas the other two are defined as literals. The Strings defined using the '&lt;span style="font-weight: bold;"&gt;new&lt;/span&gt;' operator would be allocated in the Java heap, but the Strings defined defined as literals would be in the literal pool.&lt;br /&gt;The Strings allocated in the literal pool (Perm Space) would never be garbage collected.&lt;br /&gt;This would mean that String 'str2' and 'str3' would always be strongly referenced and the corresponding entry would never be removed from the WeakHashMap.&lt;br /&gt;&lt;br /&gt;So next time you create a '&lt;span style="font-weight: bold;"&gt;new String()&lt;/span&gt;'&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;, put it as a key in a WeakHashMap, and later intern() the String, beware - Your key will always be strongly referenced. [Invoking intern() method on a String will add your String to the literal pool if some other String equal to this String does not exist in the pool]&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2010391136868522221-4032672209810433812?l=thoughts.bharathganesh.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/XxBbSP2nsT4Eucv5c4dZCt0V-84/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/XxBbSP2nsT4Eucv5c4dZCt0V-84/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/XxBbSP2nsT4Eucv5c4dZCt0V-84/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/XxBbSP2nsT4Eucv5c4dZCt0V-84/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsOnJavaJavaEeAndWebServicesDevelopment/~4/Mg6haJeNw5Q" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thoughts.bharathganesh.com/feeds/4032672209810433812/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2010391136868522221&amp;postID=4032672209810433812" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2010391136868522221/posts/default/4032672209810433812?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2010391136868522221/posts/default/4032672209810433812?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThoughtsOnJavaJavaEeAndWebServicesDevelopment/~3/Mg6haJeNw5Q/interesting-leak.html" title="The interesting leak" /><author><name>Bharath Ganesh</name><uri>http://www.blogger.com/profile/09439245318320080949</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="09026372015492934929" /></author><thr:total>6</thr:total><feedburner:origLink>http://thoughts.bharathganesh.com/2008/06/interesting-leak.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C04CSX47eCp7ImA9WxdRFEU.&quot;"><id>tag:blogger.com,1999:blog-2010391136868522221.post-4570646127735577109</id><published>2008-06-03T12:49:00.000+05:30</published><updated>2008-06-03T14:02:48.000+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-06-03T14:02:48.000+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="Garbage Collection" /><title>Some more play with WeakHashMap</title><content type="html">&lt;span style="font-family: verdana;font-size:100%;" &gt;Last couple of days, I ran into some &lt;a href="http://www.nabble.com/Memory-Leak-at-WSDLManagerImpl-td17579537.html"&gt;interesting observations &lt;/a&gt;while doing some memory optimizations &lt;a href="http://cxf.apache.org/"&gt;CXF&lt;/a&gt;.&lt;br /&gt;Consider the below snippet. &lt;/span&gt;&lt;span style="font-family: verdana;font-size:100%;" &gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;import java.util.Map;&lt;br /&gt;import java.util.WeakHashMap;&lt;br /&gt;&lt;br /&gt;public class TestWeakHeakHashMap&lt;br /&gt;{&lt;br /&gt; private String name = new String("java");&lt;br /&gt; private Map cache = new WeakHashMap&amp;lt;String, ComplexDO&amp;gt;();&lt;br /&gt;&lt;br /&gt; public void testMethod()&lt;br /&gt; {&lt;br /&gt;     cache.put(name, new ComplexDO("1", name));&lt;br /&gt;&lt;br /&gt;     //Discard the strong reference to the key&lt;br /&gt;     name = null;&lt;br /&gt;     while (true) {&lt;br /&gt;         System.gc();&lt;br /&gt;         /**&lt;br /&gt;          * Verify Full GC with the -verbose:gc option&lt;br /&gt;            Since there is no strong reference to the key, it is assumed that the&lt;br /&gt;            entry has been removed from the WeakHashMap&lt;br /&gt;          */&lt;br /&gt;         System.out.println(cache.size());&lt;br /&gt;     }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private class ComplexDO&lt;br /&gt; {&lt;br /&gt;     private String id;&lt;br /&gt;     private String name;&lt;br /&gt;&lt;br /&gt;     public ComplexDO(String id, String name)&lt;br /&gt;     {&lt;br /&gt;         this.id = id;&lt;br /&gt;         this.name = name;&lt;br /&gt;     }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Now when the testMethod() is run what do you expect the output to be? Since the strong reference to key is discarded, we assume that the entry from the map would be removed, and map would be empty after a full GC.&lt;br /&gt;But that does not happen though.&lt;br /&gt;&lt;br /&gt;Let us see what was the put operation on the WeakHashMap.&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;cache.put(name, new ComplexDO("1", name));&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;span style="font-family: verdana;font-size:100%;" &gt;&lt;span style=""&gt;Here the value &lt;span style="font-style: italic;"&gt;ComplexDO&lt;/span&gt; was holding the key &lt;span style="font-style: italic;"&gt;name&lt;/span&gt;. This would mean that the value always strongly refers to the key, and hence the key would never be garbage collected. The entry would always remain the map.&lt;br /&gt;&lt;br /&gt;This is what WeakHashMap API says - &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: verdana;font-size:100%;" &gt;"T&lt;/span&gt;&lt;span style="font-family: verdana;font-size:100%;" &gt;he value objects in a WeakHashMap are held by ordinary strong references.  Thus care should be taken to ensure that value objects do not strongly refer to their own keys, either directly or indirectly, since that will prevent the keys from being discarded."&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2010391136868522221-4570646127735577109?l=thoughts.bharathganesh.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/kk0vnr7Hhf1GpVHzf7PpQrRrpmQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/kk0vnr7Hhf1GpVHzf7PpQrRrpmQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/kk0vnr7Hhf1GpVHzf7PpQrRrpmQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/kk0vnr7Hhf1GpVHzf7PpQrRrpmQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsOnJavaJavaEeAndWebServicesDevelopment/~4/6Ylf8GbovTI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thoughts.bharathganesh.com/feeds/4570646127735577109/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2010391136868522221&amp;postID=4570646127735577109" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2010391136868522221/posts/default/4570646127735577109?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2010391136868522221/posts/default/4570646127735577109?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThoughtsOnJavaJavaEeAndWebServicesDevelopment/~3/6Ylf8GbovTI/some-more-play-with-weakhashmap.html" title="Some more play with WeakHashMap" /><author><name>Bharath Ganesh</name><uri>http://www.blogger.com/profile/09439245318320080949</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="09026372015492934929" /></author><thr:total>4</thr:total><feedburner:origLink>http://thoughts.bharathganesh.com/2008/06/some-more-play-with-weakhashmap.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE4MQng9eyp7ImA9WxdRFEU.&quot;"><id>tag:blogger.com,1999:blog-2010391136868522221.post-5437992036393375935</id><published>2008-06-02T16:36:00.000+05:30</published><updated>2008-06-03T15:26:23.663+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-06-03T15:26:23.663+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><title>WeakHashMap : An Observation</title><content type="html">&lt;p&gt;&lt;span style="font-family:Verdana;"&gt;Consider the following code snippet.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;1 public class TestWeakHashMap {&lt;br /&gt;2   public static void main(String[] args) {&lt;br /&gt;3     WeakHashMap map=new WeakHashMap();&lt;br /&gt;&lt;br /&gt;4     String s1=new String("java");&lt;br /&gt;5     map.put(s1, "good");&lt;br /&gt;&lt;br /&gt;6     String s2=new String("java");&lt;br /&gt;7     map.put(s2,"ok");&lt;br /&gt;&lt;br /&gt;   //Since s1.equals(s2) is true and hash is same, the earlier value&lt;br /&gt;   //against key s1 ("good") in the map is replaced by the new one. ("ok")&lt;br /&gt;&lt;br /&gt;8     s1=null;&lt;br /&gt;&lt;br /&gt;9     System.gc();&lt;br /&gt;     //Verify Full GC with the -verbose:gc option&lt;br /&gt;&lt;br /&gt;10    System.out.println(map.size());&lt;br /&gt;11  }&lt;br /&gt;12 }&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;&lt;span style="font-family:Verdana;"&gt;What do we expect the output to be?  1?  No, Not exactly.&lt;/span&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Verdana;"&gt;Here s1 and s2 are two different objects on the heap. So in line 5, a new (key,value) pair with key s1 is put into the map. Later when a (key,value) with key s2 is being put into the map, it checks for equals on s1 and s2 and their hashcode. When it finds the equals returns true and hashcde is same, it replaces the value of the earlier entry with the new value. But the issue(?) here is, WeakHashMap/HashMap does not replace the earlier key while adding a (key, value) pair whose key is actually a duplicate key in the map.&lt;br /&gt;So even after putting an entry with key s2, the WeakHashMap has only one entry whose key refers to the object refered by s1 and not s2.&lt;br /&gt;Now the object on the heap refered by s1, has one strong reference(through s1) and one weak reference through the WeakHashMap.&lt;br /&gt;Later when I say s1=null, the object on the heap refered to by s1 lost the strong reference and when gc happens, the entry is removed from the map. &lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Verdana;"&gt;So thats how it works. &lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Verdana;"&gt;Also note WeakHashMap is only a wrapper over HashMap and the HashMap's put api says " &lt;/span&gt;&lt;em&gt;&lt;span style="font-family:Verdana;"&gt;If the map previously contained a mapping for &lt;strong&gt;this key&lt;/strong&gt;, the old value is replaced by the specified value." &lt;/span&gt;&lt;/em&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="font-family:Verdana;"&gt;So just be careful when you use WeakHashMap and your usage scenario is similar to the above.&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2010391136868522221-5437992036393375935?l=thoughts.bharathganesh.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/SSHbrTVs3n4fW1-22cPaXsoc4cQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/SSHbrTVs3n4fW1-22cPaXsoc4cQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/SSHbrTVs3n4fW1-22cPaXsoc4cQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/SSHbrTVs3n4fW1-22cPaXsoc4cQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsOnJavaJavaEeAndWebServicesDevelopment/~4/-bXBRvn-0zs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thoughts.bharathganesh.com/feeds/5437992036393375935/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2010391136868522221&amp;postID=5437992036393375935" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2010391136868522221/posts/default/5437992036393375935?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2010391136868522221/posts/default/5437992036393375935?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThoughtsOnJavaJavaEeAndWebServicesDevelopment/~3/-bXBRvn-0zs/weakhashmap-observation.html" title="WeakHashMap : An Observation" /><author><name>Bharath Ganesh</name><uri>http://www.blogger.com/profile/09439245318320080949</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="09026372015492934929" /></author><thr:total>2</thr:total><feedburner:origLink>http://thoughts.bharathganesh.com/2008/06/weakhashmap-observation.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkADSHoyeip7ImA9WxdRFE0.&quot;"><id>tag:blogger.com,1999:blog-2010391136868522221.post-6397799454954556218</id><published>2008-06-02T16:35:00.000+05:30</published><updated>2008-06-02T16:36:19.492+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-06-02T16:36:19.492+05:30</app:edited><title>Moved from JRoller</title><content type="html">&lt;a style="font-family: verdana;" href="http://jroller.com/page/bharath"&gt;http://jroller.com/page/bharath&lt;br /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2010391136868522221-6397799454954556218?l=thoughts.bharathganesh.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/x7GdnuD-CBQxA8fwovcBw9ZMDKc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/x7GdnuD-CBQxA8fwovcBw9ZMDKc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/x7GdnuD-CBQxA8fwovcBw9ZMDKc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/x7GdnuD-CBQxA8fwovcBw9ZMDKc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ThoughtsOnJavaJavaEeAndWebServicesDevelopment/~4/bs75KGMg4CY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thoughts.bharathganesh.com/feeds/6397799454954556218/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2010391136868522221&amp;postID=6397799454954556218" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2010391136868522221/posts/default/6397799454954556218?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2010391136868522221/posts/default/6397799454954556218?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThoughtsOnJavaJavaEeAndWebServicesDevelopment/~3/bs75KGMg4CY/moved-from-jroller.html" title="Moved from JRoller" /><author><name>Bharath Ganesh</name><uri>http://www.blogger.com/profile/09439245318320080949</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="09026372015492934929" /></author><thr:total>4</thr:total><feedburner:origLink>http://thoughts.bharathganesh.com/2008/06/moved-from-jroller.html</feedburner:origLink></entry></feed>
