<?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:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;D0QNSH06fCp7ImA9WxNUF0U.&quot;"><id>tag:blogger.com,1999:blog-3745660400968632543</id><updated>2009-11-09T08:49:59.314-08:00</updated><title>Srikanth's Blog</title><subtitle type="html" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://blog.srikanths.net/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://blog.srikanths.net/" /><link rel="hub" href="http://pubsubhubbub.appspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Srikanth</name><uri>http://www.blogger.com/profile/15033538359169947653</uri><email>noreply@blogger.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>29</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><link rel="self" href="http://feeds.feedburner.com/SrikanthS" type="application/atom+xml" /><feedburner:emailServiceId>SrikanthS</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><entry gd:etag="W/&quot;Dk4MSHs8eip7ImA9WxNTEUs.&quot;"><id>tag:blogger.com,1999:blog-3745660400968632543.post-2771408957180017720</id><published>2009-08-13T05:03:00.000-07:00</published><updated>2009-08-13T05:03:09.572-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-13T05:03:09.572-07:00</app:edited><title>Curiosity</title><content type="html">After I started blogging, I learned one thing: The same topic has been already blogged by someone else, better. As I try to strictly follow the first rule of programming - &lt;a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself"&gt;DRY&lt;/a&gt; - I will have to not repeat myself.&lt;br /&gt;
&lt;br /&gt;
So, I started a new blog called &lt;a href="http://curiosity.srikanths.net/"&gt;curiosity.srikanths.net&lt;/a&gt; where I will just post the links to the answers of my curious questions and have all my questions at one place as an archive. If you're interested, here's the FeedBurner link: &lt;a href="http://feeds.feedburner.com/SrikanthS/Curiosity"&gt;feeds.feedburner.com/SrikanthS/Curiosity&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3745660400968632543-2771408957180017720?l=blog.srikanths.net'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=gGcXqpWY1VI:_r8NEZZGWqE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=gGcXqpWY1VI:_r8NEZZGWqE:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?i=gGcXqpWY1VI:_r8NEZZGWqE:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=gGcXqpWY1VI:_r8NEZZGWqE:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=gGcXqpWY1VI:_r8NEZZGWqE:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/SrikanthS/~4/gGcXqpWY1VI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.srikanths.net/feeds/2771408957180017720/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.srikanths.net/2009/08/curiosity.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/2771408957180017720?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/2771408957180017720?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SrikanthS/~3/gGcXqpWY1VI/curiosity.html" title="Curiosity" /><author><name>Srikanth</name><uri>http://www.blogger.com/profile/15033538359169947653</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15249198309624625418" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://blog.srikanths.net/2009/08/curiosity.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUUERX8-cCp7ImA9WxJWF0Q.&quot;"><id>tag:blogger.com,1999:blog-3745660400968632543.post-7181618919290031815</id><published>2009-06-23T14:40:00.000-07:00</published><updated>2009-06-23T14:40:04.158-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-23T14:40:04.158-07:00</app:edited><title>My Ubuntu Desktop with Compiz and Mac4Lin</title><content type="html">I recently tried &lt;a href="http://sourceforge.net/projects/mac4lin"&gt;Mac4Lin&lt;/a&gt;, and followed some of the &lt;a href="http://www.howtoforge.com/mac4lin_make_linux_look_like_a_mac"&gt;instructions found here on Howto Forge&lt;/a&gt; (which is a bit outdated but good enough). Well, this was the result and I'm loving it!&lt;br /&gt;
&lt;br /&gt;
(You've to click on the image to see the original maximized version.)&lt;br /&gt;
&lt;br /&gt;
Plain Desktop:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://farm4.static.flickr.com/3416/3654552447_386d5b14e8_b.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="262" src="http://farm4.static.flickr.com/3416/3654552447_386d5b14e8_b.jpg" width="420" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Win + Tab:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://farm4.static.flickr.com/3364/3655346586_43843122e5_b.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="262" src="http://farm4.static.flickr.com/3364/3655346586_43843122e5_b.jpg" width="420" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Exposé:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://farm4.static.flickr.com/3648/3655355020_488f774a94_b.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="262" src="http://farm4.static.flickr.com/3648/3655355020_488f774a94_b.jpg" width="420" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Cube:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://farm4.static.flickr.com/3283/3654555543_c1a0d51f49_b.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="262" src="http://farm4.static.flickr.com/3283/3654555543_c1a0d51f49_b.jpg" width="420" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Ctrl + Alt + Down:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://farm3.static.flickr.com/2426/3654553987_5372995d56_b.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="262" src="http://farm3.static.flickr.com/2426/3654553987_5372995d56_b.jpg" width="420" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Crowded Desktop:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://farm3.static.flickr.com/2428/3654558939_7577b48169_b.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="262" src="http://farm3.static.flickr.com/2428/3654558939_7577b48169_b.jpg" width="420" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Now, I'm really confused if I should give a shot at installing a Hackintosh.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3745660400968632543-7181618919290031815?l=blog.srikanths.net'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=MDg8ZJIxdPo:JbRc0m3x0Vs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=MDg8ZJIxdPo:JbRc0m3x0Vs:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?i=MDg8ZJIxdPo:JbRc0m3x0Vs:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=MDg8ZJIxdPo:JbRc0m3x0Vs:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=MDg8ZJIxdPo:JbRc0m3x0Vs:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/SrikanthS/~4/MDg8ZJIxdPo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.srikanths.net/feeds/7181618919290031815/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.srikanths.net/2009/06/my-ubuntu-desktop-with-compiz-and.html#comment-form" title="7 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/7181618919290031815?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/7181618919290031815?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SrikanthS/~3/MDg8ZJIxdPo/my-ubuntu-desktop-with-compiz-and.html" title="My Ubuntu Desktop with Compiz and Mac4Lin" /><author><name>Srikanth</name><uri>http://www.blogger.com/profile/15033538359169947653</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15249198309624625418" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">7</thr:total><feedburner:origLink>http://blog.srikanths.net/2009/06/my-ubuntu-desktop-with-compiz-and.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUAERHs5eCp7ImA9WxJSEEw.&quot;"><id>tag:blogger.com,1999:blog-3745660400968632543.post-5056812326037931974</id><published>2009-04-29T07:01:00.000-07:00</published><updated>2009-04-29T07:01:45.520-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-29T07:01:45.520-07:00</app:edited><title>Keep Your Head above Water</title><content type="html">&lt;a href="http://waterhyderabad.wordpress.com/"&gt;Water Hyderabad&lt;/a&gt;: A plea to not waste water.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3745660400968632543-5056812326037931974?l=blog.srikanths.net'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=K07vlYUTkuw:UPoObdCVcoI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=K07vlYUTkuw:UPoObdCVcoI:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?i=K07vlYUTkuw:UPoObdCVcoI:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=K07vlYUTkuw:UPoObdCVcoI:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=K07vlYUTkuw:UPoObdCVcoI:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/SrikanthS/~4/K07vlYUTkuw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.srikanths.net/feeds/5056812326037931974/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.srikanths.net/2009/04/keep-your-head-above-water.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/5056812326037931974?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/5056812326037931974?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SrikanthS/~3/K07vlYUTkuw/keep-your-head-above-water.html" title="Keep Your Head above Water" /><author><name>Srikanth</name><uri>http://www.blogger.com/profile/15033538359169947653</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15249198309624625418" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.srikanths.net/2009/04/keep-your-head-above-water.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0cDRHY7fyp7ImA9WxVSGU4.&quot;"><id>tag:blogger.com,1999:blog-3745660400968632543.post-8233263508291450840</id><published>2009-01-09T05:44:00.000-08:00</published><updated>2009-01-14T05:17:55.807-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-01-14T05:17:55.807-08:00</app:edited><title>On Never Using System.exit()</title><content type="html">In one of the code reviews, I got a feedback to not use &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/System.html#exit%28int%29"&gt;System.exit()&lt;/a&gt; function call at all. This was a little surprising for me but the explanation for that rule was very simple and made total sense. It's because there may be some worker thread is doing some important job (like committing a database transaction) and System.exit() will abruptly kill those threads leading to nasty bugs as you already might know.&lt;br /&gt;
&lt;br /&gt;
The scenario is roughly as follows:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="code"&gt;&lt;b&gt;// A program that uses System.exit().&lt;/b&gt;

// MainUsingSystemExit.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class MainUsingSystemExit {
  public static void main(String[] args)
      throws IOException { // You should never do this, I'm doing here for the
                           // sake of brevity of the example in the blog.
    DatabaseThread dbThread = new DatabaseThread();
    dbThread.start();

    BufferedReader reader
        = new BufferedReader(new InputStreamReader(System.in));
    while (true) {
      // TIP: In the code below, the letter 'N' is uppercase, you know why? It's
      // because that's the default answer if you don't enter anything. This is
      // a very common convention in CLI apps.
      System.out.print("Do you want to terminate? [y/N]: ");
      String userInput = reader.readLine();

      if ("y".equalsIgnoreCase(userInput)) {
        // The problem with the System.exit() below is simple, the
        // DatabaseThread is killed and that's very bad as you know.
        System.exit(0);
      }
    }
  }
}

// DatabaseThread.java
public class DatabaseThread extends Thread {
  public void run() {
    // Some db related operation.
    while (true) {
      try {
        Thread.sleep(5000);
      } catch (InterruptedException e) {}

      System.out.println("Database thread is still alive.");
    }
  }
}
&lt;/pre&gt;&lt;br /&gt;
So, how do we deal with such a code, in a clean way from the design point of view too? Solution: &lt;b&gt;Observer pattern to the rescue!&lt;/b&gt; &lt;br /&gt;
&lt;br /&gt;
We'll create a listener interface called ShutdownListener which will have a single method called shutdown() which is invoked when the system is about to go down. Those who'd like to clean-up stuff before shutdown can implement the interface and do their clean-up in the shutdown() method.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="code"&gt;&lt;b&gt;// A program that DOES NOT use System.exit().&lt;/b&gt;
&lt;/pre&gt;&lt;pre class="code"&gt;public interface ShutdownListener {
  // Called when it's time to shutdown.
  public void shutdown();
}
&lt;/pre&gt;&lt;br /&gt;
And the DatabaseThread is one such class that should implement the ShutdownListener interface.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="code"&gt;// DatabaseThread.java (modified)
public class DatabaseThread
    extends Thread
&lt;b&gt;    implements ShutdownListener {
&lt;/b&gt;  private boolean shutdown;

  public void run() {
    // Some db related operation.
&lt;b&gt;    while (!shutdown) {&lt;/b&gt;
      try {
        Thread.sleep(5000);
      } catch (InterruptedException e) {}

      System.out.println("Database thread is still alive.");
    }

    System.out.println("Database thread going down.");
  }

&lt;b&gt;  public void shutdown() {
    shutdown = true;
    this.interrupt();
  }&lt;/b&gt;
}
&lt;/pre&gt;&lt;br /&gt;
The synchronization issues aren't handled here to not clutter the code in the blog but should be taken care.&lt;br /&gt;
&lt;br /&gt;
We'll have a ShutdownHandler class where all the listeners will be registered. It can also register a &lt;a href="http://java.sun.com/j2se/1.5.0/docs/guide/lang/hook-design.html"&gt;shutdown hook&lt;/a&gt;* which does nothing but calls its own initiateShutdown() method which goes and calls the shutdown() method of all the registered ShutdownListeners.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="code"&gt;import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class ShutdownHandler {
  private List shutdownListeners;

  public ShutdownHandler() {
    shutdownListeners = new ArrayList();

    // For handling TERM, INT signals.
    Runtime.getRuntime().addShutdownHook(new Thread() {
      public void run() {
        ShutdownHandler.this.initiateShutdown();
      }
    });
  }

  public void registerShutdownListener(ShutdownListener listener) {
    shutdownListeners.add(listener);
  }

  public void initiateShutdown() {
    Iterator iterator = shutdownListeners.iterator();

    while (iterator.hasNext()) {
      ShutdownListener listener = (ShutdownListener) iterator.next();
      listener.shutdown();
    }
  }
}
&lt;/pre&gt;&lt;br /&gt;
And finally, the new main():&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="code"&gt;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class MainWithoutSystemExit {
  public static void main(String[] args) throws IOException {
    DatabaseThread dbThread = new DatabaseThread();
    dbThread.start();

&lt;b&gt;    ShutdownHandler shutdownHandler = new ShutdownHandler();
    shutdownHandler.registerShutdownListener(dbThread);

&lt;/b&gt;    BufferedReader reader
        = new BufferedReader(new InputStreamReader(System.in));
    while (true) {
      System.out.print("Do you want to terminate? [y/N]: ");
      String userInput = reader.readLine();

      if ("y".equalsIgnoreCase(userInput)) {
        // Calling the ShutdownHandler's shutdown() method
        // instead of System.exit()
&lt;b&gt;        shutdownHandler.initiateShutdown();
        return;
&lt;/b&gt;      }
    }
  }
}
&lt;/pre&gt;&lt;br /&gt;
As you can see, the ShutdownHandler's initiateShutdown() is called instead of System.exit() in the new main() method. Now if we've a new SocketThread or some other thread that needs a graceful exit, all we've to do is implement ShutdownListener and register it with the ShutdownHandler.&lt;br /&gt;
&lt;br /&gt;
Now, go look in your code and see how you can eliminate System.exit() calls altogether. See if that brings out a better design. Or do you think this idea of not using System.exit() is just crazy?&lt;br /&gt;
&lt;br /&gt;
* Thanks to &lt;a href="http://www.ajeya.net/"&gt;Ajeya&lt;/a&gt; for reminding me about shutdown hooks.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3745660400968632543-8233263508291450840?l=blog.srikanths.net'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=YBMy68sjOrs:tVXJSV8QLaA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=YBMy68sjOrs:tVXJSV8QLaA:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?i=YBMy68sjOrs:tVXJSV8QLaA:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=YBMy68sjOrs:tVXJSV8QLaA:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=YBMy68sjOrs:tVXJSV8QLaA:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/SrikanthS/~4/YBMy68sjOrs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.srikanths.net/feeds/8233263508291450840/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.srikanths.net/2009/01/on-never-using-systemexit.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/8233263508291450840?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/8233263508291450840?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SrikanthS/~3/YBMy68sjOrs/on-never-using-systemexit.html" title="On Never Using System.exit()" /><author><name>Srikanth</name><uri>http://www.blogger.com/profile/15033538359169947653</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15249198309624625418" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://blog.srikanths.net/2009/01/on-never-using-systemexit.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEcFSHg7cCp7ImA9WxVSFU0.&quot;"><id>tag:blogger.com,1999:blog-3745660400968632543.post-6593105719120604522</id><published>2009-01-09T03:09:00.000-08:00</published><updated>2009-01-09T03:53:39.608-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-01-09T03:53:39.608-08:00</app:edited><title>Make Sure to Return the Right Exit Codes</title><content type="html">Every process that finished its execution can return an integer value back to the parent process indicating its result. Often an exit code of '0' means the child process was executed successfully and a value greater than '0' indicates failure.&lt;br /&gt;
&lt;br /&gt;
On a *NIX machine, the variable '$?' has the exit code returned by the last executed process. For example:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="code"&gt;srikanth@workstation - [~]
$ find . -nam "*.c"              # Intentionally trying a wrong option
find: invalid predicate `-nam'

srikanth@workstation - [~]
$ echo $?
1                                # &amp;gt;0, process failed

srikanth@workstation - [~]
$ find . -name "*.c"
./test.c

srikanth@workstation - [~]
$ echo $?
0                                # Process execution successful

srikanth@workstation - [~]
$
&lt;/pre&gt;&lt;br /&gt;
But too often I've seen programmers not taking care of the exit codes for the applications or some small-time utility programs they write. I've done it myself when I started out programming partly because I didn't know the significance of the exit codes. But they are very helpful.&lt;br /&gt;
&lt;br /&gt;
Sometimes you've to &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Runtime.html#exec%28java.lang.String%29"&gt;spawn a new process&lt;/a&gt; from your program to accomplish something 'cause you don't have an API exposed for it in your language. At these times, the &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Process.html#exitValue%28%29"&gt;exit code returned by the child process&lt;/a&gt; can be extremely useful.&lt;br /&gt;
&lt;br /&gt;
So, when writing some new command line utility or an application, remember to:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;b&gt;Always return an exit code&lt;/b&gt;: 0 for success; 1 &amp;lt;= exit_code &amp;lt;= 255 for failure&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Don't return negative exit codes&lt;/b&gt;: I've seen this in some code; I didn't know it was invalid till someone had an issue with it. At least on UNIX, the &lt;a href="http://en.wikipedia.org/wiki/Exit_status#Unix"&gt;valid exit codes are from 0 to 255&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Document the exit codes&lt;/b&gt;: Like 1 for database failure, 2 for mis-configuration, etc.&lt;/li&gt;
&lt;/ul&gt;That's it, happy coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3745660400968632543-6593105719120604522?l=blog.srikanths.net'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=QDiYEWCoILw:AZPZr463eFY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=QDiYEWCoILw:AZPZr463eFY:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?i=QDiYEWCoILw:AZPZr463eFY:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=QDiYEWCoILw:AZPZr463eFY:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=QDiYEWCoILw:AZPZr463eFY:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/SrikanthS/~4/QDiYEWCoILw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.srikanths.net/feeds/6593105719120604522/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.srikanths.net/2009/01/make-sure-to-return-right-exit-codes.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/6593105719120604522?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/6593105719120604522?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SrikanthS/~3/QDiYEWCoILw/make-sure-to-return-right-exit-codes.html" title="Make Sure to Return the Right Exit Codes" /><author><name>Srikanth</name><uri>http://www.blogger.com/profile/15033538359169947653</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15249198309624625418" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://blog.srikanths.net/2009/01/make-sure-to-return-right-exit-codes.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0INQHw7eip7ImA9WxVTGEQ.&quot;"><id>tag:blogger.com,1999:blog-3745660400968632543.post-4388125990357224487</id><published>2009-01-02T01:03:00.000-08:00</published><updated>2009-01-02T02:19:51.202-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-01-02T02:19:51.202-08:00</app:edited><title>My Simple New Year Resolutions for 2009</title><content type="html">I never took new year resolutions but in the previous year at some point I decided to create a &lt;a href="http://blog.srikanths.net/2008/04/what-is-your-to-learn-list-for-this.html"&gt;list of things I wanted to learn&lt;/a&gt; and published it in my blog. It worked very well, I received a lot of invaluable comments, I kept coming back to the same post to keep myself on track. It really helps, you should write one too.&lt;br /&gt;
&lt;br /&gt;
So this year I decided to broaden the scope of my resolutions from just technology to my life as a whole. These are my simple resolutions:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;Do As Less As Possible&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Sometimes I feel like doing everything, I mean at once. Like learning C++, completing a networking-related certification, mastering Python, doing an Open Source project, going for gym, learning Emacs, participating in Mumbai marathon, photography and watching falling stars.&lt;br /&gt;
&lt;br /&gt;
And the problem I have is, when I'm doing something I would want to do something else. So this year, I decided to do only 3 things:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;C++&lt;/li&gt;
&lt;li&gt;Algorithms and Data Structures&lt;/li&gt;
&lt;li&gt;Gymming&lt;/li&gt;
&lt;/ul&gt;The picky professor in you may say that "Algorithms and Data Structures" are 2 things, but... it's okay, they're a bit related.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;Take It Easy&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
There's something in me that's absolutely restless (I guess that's there in everyone). It constantly screams at you to do something great and significant in life but it doesn't have the patience to wait for you to complete. It wants us to do many things. From now on, I'll refuse to listen to that voice. I've heard it enough, now I want to concentrate on doing it.&lt;br /&gt;
&lt;br /&gt;
It's OK to fail sometimes. It's OK to not achieve some of your goals. It's absolutely fine to do nothing productive on weekends. It's perfectly cool to watch a crappy Hindi movie with coworkers. It's nice to chill out and feel good. It's in fact re-energizing. It's nice to visit places. It's good to pass time chit-chatting with friends on weekends. All work and no play will only make Srikanth a dull boy. But dull no more :)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;b&gt;Be Mr.Fit&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
I wanted to run like &lt;a href="http://www.imdb.com/name/nm0000354/"&gt;Matt Damon&lt;/a&gt; in &lt;a href="http://www.imdb.com/title/tt0372183/"&gt;The Bourne Supremacy&lt;/a&gt; today morning. I don't know why. Just wanted to run like there's no ending. That's when I realized I didn't run since I left college. I didn't play any outdoor games too. It's time to do all that, again. And it's also the time to hit the gym to keep me fit.&lt;br /&gt;
&lt;br /&gt;
My friend &lt;a href="http://techmaddy.blogspot.com/"&gt;Ranganathan&lt;/a&gt; told me a few inspiring words when I met him recently, it was roughly: "When you lose everything in life, such as money and power, and if you're still alive, the only thing remaining is your body."&lt;br /&gt;
&lt;br /&gt;
So, what are your new year resolutions?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3745660400968632543-4388125990357224487?l=blog.srikanths.net'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=LTmWSakGTFY:R5y34EMbNSc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=LTmWSakGTFY:R5y34EMbNSc:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?i=LTmWSakGTFY:R5y34EMbNSc:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=LTmWSakGTFY:R5y34EMbNSc:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=LTmWSakGTFY:R5y34EMbNSc:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/SrikanthS/~4/LTmWSakGTFY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.srikanths.net/feeds/4388125990357224487/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.srikanths.net/2009/01/my-simple-new-year-resolutions-for-2009.html#comment-form" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/4388125990357224487?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/4388125990357224487?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SrikanthS/~3/LTmWSakGTFY/my-simple-new-year-resolutions-for-2009.html" title="My Simple New Year Resolutions for 2009" /><author><name>Srikanth</name><uri>http://www.blogger.com/profile/15033538359169947653</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15249198309624625418" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://blog.srikanths.net/2009/01/my-simple-new-year-resolutions-for-2009.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUMMSXY8cSp7ImA9WxRUGUs.&quot;"><id>tag:blogger.com,1999:blog-3745660400968632543.post-4514907016619700419</id><published>2008-11-29T03:18:00.000-08:00</published><updated>2008-11-29T04:58:08.879-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-11-29T04:58:08.879-08:00</app:edited><title>Srikanth's Favorite Firefox Add-ons</title><content type="html">After Google Chrome came out, I haven't been using Firefox a lot. And it's for a very simple reason: &lt;i&gt;speed&lt;/i&gt;. Especially the start-up speed. I'm a speed freak and I don't like to keep my browsers opened when I'm working. I'd like to open, search for whatever I was looking for and close the damn window as soon as possible and get back to work. I came to know that Minefield is very fast, but for some reason I like Chrome for quick searching. But on weekends I do full-time browsing. And for that, I use Firefox because I miss one thing in Chrome: &lt;i&gt;add-ons&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
I've a few favorite Firefox add-ons and I'm finding browsing irritating and difficult without them in Chrome. These are the my favorites. These may not be in your favorites-list, but hey, I'm me and you're you.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: medium;"&gt;&lt;a href="http://draft.blogger.com/post-edit.g?blogID=3745660400968632543&amp;amp;postID=4514907016619700419"&gt;Adblock&lt;/a&gt; &lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Ads can be very annoying, especially when they're embedded in the middle of the contents. Adblock Plus is a must-have plugin if you don't want to see those shining ads that distract you.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: medium;"&gt;&lt;a href="http://flashblock.mozdev.org/"&gt;Flashblock&lt;/a&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
This is my next favorite add-on. Flash can consume a lot of bandwidth and slow down the rendering of the other page elements. I find it better to block those flash contents when the page loads and then play it if necessary.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: medium;"&gt;&lt;b&gt;&lt;a href="http://getfirebug.com/"&gt;Firebug&lt;/a&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
I'm not a web-developer, still I find this add-on extremely useful. A couple of my usages are:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Tweaking any page and removing unwanted elements before printing&lt;/li&gt;
&lt;li&gt;Learning CSS and HTML (a better way to view the source)&lt;/li&gt;
&lt;/ul&gt;When I take printouts, I'd like to have the fonts set to my favorite ones. I love to read if the fonts happen to please my eye. Firebug provides me the easy way to change the fonts used by the web-page to whatever I like. And it can also remove the unwanted elements from the page. If you haven't tried Firebug, it's high time you do it.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: medium;"&gt;&lt;b&gt;&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/710"&gt;Menu Editor&lt;/a&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Chrome and Firefox place "Open Link in New Tab" menu item at different positions in their context menus. And "Open Link in New Window" is something I never use. Menu Editor add-on helps me customize my Firefox menus (Duh!). I remove all the useless links (useless to me) like Back, Forward, Stop, Refresh, etc. And this add-on also helps me in having the "Open Link in New Tab" menu item's position at the same place in both the browsers I use.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: medium;"&gt;&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/3415"&gt;Direct Link&lt;/a&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
I love this add-on. You can select text, right-click to open it as a link in a new tab (if it's a URL), or as an article in Wikipedia or to do an I'm Feeling Lucky Google search.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: medium;"&gt;&lt;b&gt;&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/7163"&gt;Paste to Tab and Go &lt;/a&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Unfortunately, &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/3035"&gt;Paste and Go&lt;/a&gt; add-on is not available for Firefox 3. So the next best thing I could find was this one. I realized this is extremely useful when I started using Chrome. It felt stupid to paste the URL and then click on the Go button to start loading.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: medium;"&gt;&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/1419"&gt;IE Tab&lt;/a&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Useful when that stupid government site refuses to load in any browser other than IE.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: medium;"&gt;&lt;b&gt;&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/748"&gt;Greasemonkey&lt;/a&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
People love this but for some reason, I rarely use it. I have "Textarea Resize" script installed but even that I've only used it a very few times. I think this feature (Textarea Resize) should be an out of the box feature in Firefox. Anyway, I like that monkey in its icon but I'm gonna remove this now. &lt;b&gt;Do you think I'm missing some amazing script?&lt;/b&gt; Please leave your suggestion in the comments if I'm doing so.&lt;br /&gt;
&lt;br /&gt;
I also have "Customize Google" installed but most of what it does is already incorporated as out of the box features, but I'll let it stay. Some other minor tweaks I do and I don't are:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Disable plugins like Acrobat Reader, Google Update&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt; No themes, just the default&lt;/li&gt;
&lt;li&gt;Monospace font as Consolas (I love Consolas)&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;So, what's your favorite add-on and why? What are the tweakings you do after installing Firefox?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3745660400968632543-4514907016619700419?l=blog.srikanths.net'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=DMBdsVqSmhs:FOPmfobDXe0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=DMBdsVqSmhs:FOPmfobDXe0:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?i=DMBdsVqSmhs:FOPmfobDXe0:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=DMBdsVqSmhs:FOPmfobDXe0:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=DMBdsVqSmhs:FOPmfobDXe0:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/SrikanthS/~4/DMBdsVqSmhs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.srikanths.net/feeds/4514907016619700419/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.srikanths.net/2008/11/srikanths-favorite-firefox-add-ons.html#comment-form" title="8 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/4514907016619700419?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/4514907016619700419?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SrikanthS/~3/DMBdsVqSmhs/srikanths-favorite-firefox-add-ons.html" title="Srikanth's Favorite Firefox Add-ons" /><author><name>Srikanth</name><uri>http://www.blogger.com/profile/15033538359169947653</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15249198309624625418" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">8</thr:total><feedburner:origLink>http://blog.srikanths.net/2008/11/srikanths-favorite-firefox-add-ons.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkMCRng_eip7ImA9WxRXEUU.&quot;"><id>tag:blogger.com,1999:blog-3745660400968632543.post-7262771172795887124</id><published>2008-10-16T10:22:00.000-07:00</published><updated>2008-10-16T11:07:47.642-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-10-16T11:07:47.642-07:00</app:edited><title>trim() for C</title><content type="html">I was very surprised when I found out that there's no trim(char *) function in standard C library. Anyways, I wrote my own by stealing, er, looking at java.lang.String.trim() method (and reinvented the wheel just for my silly pleasure), and here it is if you should ever need. Take it, it's for you, *free of charge 'cause I like you so much :)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="code"&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;string.h&amp;gt;

void trim(char *s, const int len)
{
    int end = len - 1;
    int start = 0;
    int i = 0;

    while ((start &amp;lt; len) &amp;amp;&amp;amp; (s[start] &amp;lt;= ' '))
    {
        start++;
    }

    while ((start &amp;lt; end) &amp;amp;&amp;amp; (s[end] &amp;lt;= ' '))
    {
        end--;
    }

    if (start &amp;gt; end)
    {
        memset(s, '\0', len);
        return;
    }

    for (i = 0; (i + start) &amp;lt;= end; i++)
    {
        s[i] = s[start + i];
    }
    memset((s + i), '\0', len - i);
}

int main()
{
    char s[] = "   srikanth s     \n";
    char empty[] = "";
    char newline[] = "\n";
    char double_newline[] = "\n\n";
    char single_char[] = " s ";
    trim(s, strlen(s));
    printf("s = '%s'\n", s);
    trim(empty, strlen(empty));
    printf("empty = '%s'\n", empty);
    trim(newline, strlen(newline));
    printf("newline = '%s'\n", newline);
    trim(double_newline, strlen(double_newline));
    printf("double_newline = '%s'\n", double_newline);
    trim(single_char, strlen(single_char));
    printf("single_char = '%s'\n", single_char);
    return 0;
}

&lt;/pre&gt;&lt;br /&gt;
The main() is just for testing the function, let's see how it went.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="code"&gt;$ gcc -Wall -o go trim.c

$ ./go
s = 'srikanth s'
empty = ''
newline = ''
double_newline = ''
single_char = 's'
&lt;/pre&gt;&lt;br /&gt;
This function doesn't create a new char[] for the trimmed string, it modifies the original. Let me know if you've got an optimized version than this, I'll be interested to learn.&lt;br /&gt;
&lt;br /&gt;
(Edit: Thanks to my colleague Hiren for catching a nasty bug. The memset at the end, &lt;code&gt;memset((s + i), '\0', len)&lt;/code&gt; had a bug. It should've been &lt;code&gt;memset((s + i), '\0', len - i)&lt;/code&gt;. *So, that brings us to the disclaimer. Take the code at your own risk. I'm not responsible if it formats your hard drive or if it kills your cat.)&lt;br /&gt;
&lt;br /&gt;
That's it, see you later, I've gotta go trim.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3745660400968632543-7262771172795887124?l=blog.srikanths.net'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=bMXxIEo7u-A:HZgFHZJNTco:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=bMXxIEo7u-A:HZgFHZJNTco:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?i=bMXxIEo7u-A:HZgFHZJNTco:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=bMXxIEo7u-A:HZgFHZJNTco:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=bMXxIEo7u-A:HZgFHZJNTco:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/SrikanthS/~4/bMXxIEo7u-A" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.srikanths.net/feeds/7262771172795887124/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.srikanths.net/2008/10/trim-for-c.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/7262771172795887124?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/7262771172795887124?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SrikanthS/~3/bMXxIEo7u-A/trim-for-c.html" title="trim() for C" /><author><name>Srikanth</name><uri>http://www.blogger.com/profile/15033538359169947653</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15249198309624625418" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://blog.srikanths.net/2008/10/trim-for-c.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkEMR3c8fCp7ImA9WxRSGU4.&quot;"><id>tag:blogger.com,1999:blog-3745660400968632543.post-4715899414775756254</id><published>2008-09-08T08:33:00.000-07:00</published><updated>2008-09-20T11:18:06.974-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-09-20T11:18:06.974-07:00</app:edited><title>Calling C++ Functions in C</title><content type="html">&amp;lt;skippable&amp;gt;&lt;br /&gt;
&lt;blockquote&gt;&lt;span style="font-style: italic;"&gt;I'm currently working on some code written in C, I've never done C programming before; only Java and a little bit of Python. I'm currently in the process of learning C, so whatever I write may not be the best way to do "that" thing. But as I keep learning new things, I'll blog them when I find time. So if you're interested in learning C, follow my posts; especially if you're a Java programmer who doesn't know C but you're interested just for the heck of it. You may find these posts useful.&lt;/span&gt;&lt;/blockquote&gt;&amp;lt;/skippable&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I'd to call a few C++ class's methods from a C program recently, and I didn't know how to do it. I found a way that suits my situation and here it is.&lt;br /&gt;
&lt;br /&gt;
The fact as I found out is that you &lt;span style="font-weight: bold;"&gt;cannot create an instance of a C++ object in your C program&lt;/span&gt; and obviously that means you can't call its methods. So, we need a workaround. In general, we need to be able to do these things from our C code:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Create an instance of a C++ class&lt;/li&gt;
&lt;li&gt;Call its methods, pass arguments, etc.&lt;/li&gt;
&lt;li&gt;Destroy the created instance.&lt;/li&gt;
&lt;/ol&gt;&lt;div&gt;(Instance == Object). Just thought I should let you know!&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;I'll demonstrate the process with an example. So up first, let's create a C++ class which we'll call from a C program.&lt;/div&gt;&lt;br /&gt;
&lt;pre class="code"&gt;&lt;span style="font-weight: bold;"&gt;// cppclass.cpp&lt;/span&gt;
class CppClass
{
public:
    char *returnHello()
    {
        char *ret_val = "Hello";
        return ret_val;
    }
};
&lt;/pre&gt;&lt;br /&gt;
But I've already told you that we can't create an instance of this class directly, so we've to provide &lt;span style="font-weight: bold;"&gt;wrapper functions&lt;/span&gt;&amp;nbsp;that our C program can call. The disadvantage with this workaround is, for every public function we want to use we need a wrapper function. Anyway, let's write them.&lt;br /&gt;
&lt;br /&gt;
(Add the following lines to cppclass.cpp file)&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="code"&gt;extern "C" void *create_cppclass()
{
    return new CppClass();
}

extern "C" char *call_return_hello(void *obj)
{
    return reinterpret_cast&amp;lt;CppClass*&amp;gt;(obj)-&amp;gt;returnHello();
}

extern "C" void *free_cppclass(void *obj)
{
    delete reinterpret_cast&amp;lt;CppClass*&amp;gt;(obj);
}

&lt;/pre&gt;&lt;br /&gt;
A few things should be noticed here.&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;All these wrapper functions are&amp;nbsp;preceded&amp;nbsp;with extern "C" (uppercase C)&lt;/li&gt;
&lt;li&gt;In create_cppclass() wrapper function, the newly created object of CppClass is returned as a void pointer (void *). Void pointers can be used to point to any type. So when we return the instance as a pointer to void in this function, it can stored it in our C program. That's the whole point here.&lt;/li&gt;
&lt;li&gt;In call_return_hello() and free_cppclass() wrapper functions, we use&amp;nbsp;&lt;a href="http://msdn.microsoft.com/en-us/library/e0w9f63b%28VS.80%29.aspx"&gt;reinterpret_cast&lt;/a&gt;&amp;nbsp;to convert the void pointer back to CppClass pointer type. The -&amp;gt; operator is used for dereferencing the pointers instead of the . (dot) operator.&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;Now, let's call these functions from our C program. We should declare these functions first in our C program before we can use them.&lt;/div&gt;&lt;br /&gt;
&lt;pre class="code"&gt;&lt;span style="font-weight: bold;"&gt;// cfile.c&lt;/span&gt;
#include &amp;lt;stdio.h&amp;gt;

extern "C" void *create_cppclass();
extern "C" char *call_return_hello(void *obj);
extern "C" void *free_cppclass(void *obj);

main()
{
    void *obj = create_cppclass();
    char *hello = call_return_hello(obj);
    free_cppclass(obj);
    printf("%s\n", hello);
}
&lt;/pre&gt;&lt;br /&gt;
Now, I'll use g++ to compile:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="code"&gt;g++ -o go cfile.c cppclass.cpp
&lt;/pre&gt;&lt;pre class="code"&gt;./go&lt;/pre&gt;&lt;br /&gt;
-o indicates the executable output file name which is "go" here. Write the code and try out for yourself. It should print "Hello" (Duh!)&lt;br /&gt;
&lt;br /&gt;
That's it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3745660400968632543-4715899414775756254?l=blog.srikanths.net'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=F-l-Q_kH0kA:C1M4G-qUar0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=F-l-Q_kH0kA:C1M4G-qUar0:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?i=F-l-Q_kH0kA:C1M4G-qUar0:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=F-l-Q_kH0kA:C1M4G-qUar0:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=F-l-Q_kH0kA:C1M4G-qUar0:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/SrikanthS/~4/F-l-Q_kH0kA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.srikanths.net/feeds/4715899414775756254/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.srikanths.net/2008/09/calling-c-functions-in-c.html#comment-form" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/4715899414775756254?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/4715899414775756254?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SrikanthS/~3/F-l-Q_kH0kA/calling-c-functions-in-c.html" title="Calling C++ Functions in C" /><author><name>Srikanth</name><uri>http://www.blogger.com/profile/15033538359169947653</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15249198309624625418" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://blog.srikanths.net/2008/09/calling-c-functions-in-c.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkEGRX86fSp7ImA9WxRXFUw.&quot;"><id>tag:blogger.com,1999:blog-3745660400968632543.post-8173590261736308839</id><published>2008-06-24T05:04:00.000-07:00</published><updated>2008-10-20T06:50:24.115-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-10-20T06:50:24.115-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="Tips" /><title>Java One Liner - Reading a Text File at Once</title><content type="html">Java is not meant or known for any one-liners, but who said we can't try? There you go:&lt;br /&gt;
&lt;pre class="code"&gt;String contents = new Scanner(new File("filepath")).findWithinHorizon(Pattern.compile(".*", Pattern.DOTALL), 0);
&lt;/pre&gt;&lt;br /&gt;
Cool, eh?&lt;br /&gt;
&lt;br /&gt;
Hmm, may be not. Of course, you still have to deal with the checked exceptions + 3 import statements, etc. The so called one-liner by me has 113 characters (could be more or could be less if you consider the file path's length). I'm not sure if I would consider anything more than 80 chars as "one-liner" but hey, this is Java and this is as close as you can get.&lt;br /&gt;
&lt;br /&gt;
Just for fun. Do you have anything better than this in Java? How about in Java 1.4? Now, don't write a separate method, call it, and say it's a one-liner for Perl sakes!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3745660400968632543-8173590261736308839?l=blog.srikanths.net'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=7VARJnyKawM:f8gXZv3hUiI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=7VARJnyKawM:f8gXZv3hUiI:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?i=7VARJnyKawM:f8gXZv3hUiI:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=7VARJnyKawM:f8gXZv3hUiI:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=7VARJnyKawM:f8gXZv3hUiI:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/SrikanthS/~4/7VARJnyKawM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.srikanths.net/feeds/8173590261736308839/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.srikanths.net/2008/06/java-one-liner-reading-text-file-at.html#comment-form" title="7 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/8173590261736308839?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/8173590261736308839?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SrikanthS/~3/7VARJnyKawM/java-one-liner-reading-text-file-at.html" title="Java One Liner - Reading a Text File at Once" /><author><name>Srikanth</name><uri>http://www.blogger.com/profile/15033538359169947653</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15249198309624625418" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">7</thr:total><feedburner:origLink>http://blog.srikanths.net/2008/06/java-one-liner-reading-text-file-at.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0MESX8-cSp7ImA9WxdSEUk.&quot;"><id>tag:blogger.com,1999:blog-3745660400968632543.post-6491843165068586629</id><published>2008-05-18T12:24:00.000-07:00</published><updated>2008-05-18T13:10:08.159-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-05-18T13:10:08.159-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="pingpong" /><title>Clipboard PingPong</title><content type="html">&lt;span style="font-weight: bold;"&gt;What is it?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Clipboard PingPong can send your clipboard contents to other computers and receive the other computers' published clipboard contents. Currently, it has been restricted to transfer only string data. It runs on top of the JVM and that's the only prerequisite. It's also very tiny. (Version 0.1's size is roughly 58KB of which 35KB is GNU GPL v3 license text.)&lt;br /&gt;&lt;br /&gt;Wanna try? &lt;a href="http://code.google.com/p/clipboard-pingpong/"&gt;Download from here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The Development Lesson&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I learned one thing: &lt;span style="font-style: italic;"&gt;release early&lt;/span&gt;. I wrote the first working version almost a month ago for my personal use in about 1 hour. I just wanted to exchange the clipboard contents between 2 machines I was using. It had to be platform independent because I was using both Linux and Windows. Then I decided to share the code and had all these plans like having a configuration utility, adding a logging module, etc. But I kept procrastinating and didn't have the time to finish it. So now, I didn't add any graphical configuration utility. Instead, I added some instructions in README which should explain the configuration process which is frankly very trivial. I also have the startup and shutdown scripts. This software should really run as a service but I am releasing it early. May be the suggestions from you can steer me in the right direction.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What do I need?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Testing. And lots of it. I tested with 2 machines; it did fine. Bug reports will be really helpful to enhance and decide the future development activities. Report the bugs &lt;a href="http://code.google.com/p/clipboard-pingpong/issues/list"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Decisions&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Before writing the code, I had a few things in my mind on how the software must be written which I would like to share here. I called them "requirements." These are they:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Should be platform independent&lt;/li&gt;&lt;li&gt;Should have no library dependencies&lt;/li&gt;&lt;li&gt;Should use a simple text file for configuration (no XML)&lt;/li&gt;&lt;/ul&gt;I needed the software to be platform independent, and that's the reason why I chose Java. I could have chosen Python but in most of the the machines a JVM can be found easily than a Python interpreter. Minimum Java version required is 1.4. I didn't test it on a 1.4 JRE, I tested it on 1.5. But it should run without any problems. If someone is testing on 1.4 and if it doesn't run, please let me know.&lt;br /&gt;&lt;br /&gt;The other thing I made sure was not to use any libraries (no dependent jars). I had to parse command line arguments, but I wrote my own helper class to do it. That's the same reason why I didn't use XML for configuration files apart from plain text being easy to edit manually than XML.&lt;br /&gt;&lt;br /&gt;Note: It also requires a desktop environment.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3745660400968632543-6491843165068586629?l=blog.srikanths.net'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=igPSqt2tGSI:pl4-BW4c1ZY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=igPSqt2tGSI:pl4-BW4c1ZY:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?i=igPSqt2tGSI:pl4-BW4c1ZY:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=igPSqt2tGSI:pl4-BW4c1ZY:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=igPSqt2tGSI:pl4-BW4c1ZY:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/SrikanthS/~4/igPSqt2tGSI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.srikanths.net/feeds/6491843165068586629/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.srikanths.net/2008/05/clipboard-pingpong.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/6491843165068586629?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/6491843165068586629?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SrikanthS/~3/igPSqt2tGSI/clipboard-pingpong.html" title="Clipboard PingPong" /><author><name>Srikanth</name><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.srikanths.net/2008/05/clipboard-pingpong.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkEAQXg6eCp7ImA9WxVXFU4.&quot;"><id>tag:blogger.com,1999:blog-3745660400968632543.post-3364616991850057640</id><published>2008-04-24T06:46:00.000-07:00</published><updated>2009-02-13T06:17:20.610-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-02-13T06:17:20.610-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><title>How to Debug a Remote Java Application?</title><content type="html">&lt;span style="font-size: 130%;"&gt;&lt;span style="font-weight: bold;"&gt;A Little Story&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;skippable-story&amp;gt;&lt;br /&gt;
&lt;blockquote&gt;Recently I was working with a Java application that was bugging me when it was running in another country (USA) but it works fine when I run it on my desktop here in India. Of course, there is no connection with the geography except that the connection is slower. Every time I had a problem which is time consuming to reproduce on my desktop, I would login to that computer remotely through VNC client, reproduce the problem, get the logs, diagnose, and test it again there. You may ask, "Why don't you create a similar setup of that remote machine next to your desktop?" Trust me, there's a reason why I can't do it and I won't have a setup anytime sooner. Don't let &lt;span style="font-style: italic;"&gt;that&lt;/span&gt; distract you about what I am trying to say, just forget it and assume I have to test it on a remote machine that resides in the same Intranet.&lt;br /&gt;
&lt;br /&gt;
I was a having a conversation with one of my coworkers on phone about a particular problem and he said, "It will be slow but why don't you debug and see it?" My face turned red and I felt a little ashamed, I knew what he was talking about. He is a smart guy, I knew for sure he was not asking me to switch my whole development environment to some remote machine sitting on the other side of the globe. I hung up the phone, I walked to his desk and asked him. "Did you say &lt;span style="font-style: italic;"&gt;debug&lt;/span&gt;?" He generously showed me how to do it. In fact, he thought that I don't know what is debugging and he explained me everything -- all that Step-Into, Step-Over, Step-Out stuff with its shortcuts.&lt;br /&gt;
&lt;br /&gt;
It was easy for me to jump and say, "Dude! I know how to debug" but that would have been a wrong thing to do at that time. I know many people who come for help to me do this. So I quietly listened to him and gently said, "Yep, I'm familiar with that."&lt;br /&gt;
&lt;br /&gt;
In case you have never done this before --here is how you do it. I will show how to do this using the Eclipse IDE, and I am very sure you are smart enough to figure out for your development setup.&lt;/blockquote&gt;&amp;lt;/skippable-story&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let's say you have your application compiled into a jar called &lt;span style="font-weight: bold;"&gt;myapp.jar&lt;/span&gt; and this will be running remotely on a machine called &lt;span style="font-weight: bold;"&gt;myremote.mycompany.com&lt;/span&gt; (or some IP). Your development machine is &lt;span style="font-weight: bold;"&gt;mydevel.mycompany.com&lt;/span&gt;. Now to debug the myapp.jar that is running remotely from your desktop machine, there are two steps you have to follow:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Start the application and tell the JVM that it will be debugged remotely&lt;/li&gt;
&lt;li&gt;Configure your IDE on your desktop to be able to debug that remote application&lt;/li&gt;
&lt;/ol&gt;&lt;span style="font-size: 130%;"&gt;&lt;span style="font-weight: bold;"&gt;Starting the Application with Remote Debugging Enabled&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="code"&gt;java -Xdebug -Xrunjdwp:transport=dt_socket,address=8998,server=y -jar myapp.jar
&lt;/pre&gt;The above command says: start myapp.jar + start a server socket at port 8998 and publish the debugging messages using the &lt;span style="font-weight: bold;"&gt;Java Debug Wire Protocol&lt;/span&gt; (jdwp) there.&lt;br /&gt;
&lt;br /&gt;
Other than &lt;span style="font-weight: bold;"&gt;address&lt;/span&gt;, &lt;span style="font-weight: bold;"&gt;server&lt;/span&gt;, and &lt;span style="font-weight: bold;"&gt;transport&lt;/span&gt; there are other sub options available for &lt;span style="font-weight: bold;"&gt;-Xrunjdwp&lt;/span&gt; option -- for example: &lt;span style="font-weight: bold;"&gt;suspend&lt;/span&gt;. I will leave that for you. Let's move on to step 2, that is configuring Eclipse.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: 130%;"&gt;&lt;span style="font-weight: bold;"&gt;Configuring Eclipse to Debug a Remotely Running Application&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
I will just show the screenshots without writing much, it's just intuitive that way.&lt;br /&gt;
&lt;br /&gt;
1. Start Eclipse&lt;br /&gt;
2. Go to &lt;span style="font-weight: bold;"&gt;Run&lt;/span&gt; -&amp;gt; &lt;span style="font-weight: bold;"&gt;Debug Configurations&lt;br /&gt;
&lt;br /&gt;
&lt;/span&gt;&lt;a href="http://2.bp.blogspot.com/_3d4j-n-2yEU/SBMcx5lNGPI/AAAAAAAAAJ8/IDPE3Fcktw8/s1600-h/eclipse-run-debug-conf-menu-item.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5193526438884350194" src="http://2.bp.blogspot.com/_3d4j-n-2yEU/SBMcx5lNGPI/AAAAAAAAAJ8/IDPE3Fcktw8/s400/eclipse-run-debug-conf-menu-item.png" style="cursor: pointer;" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;3. Create a new &lt;span style="font-weight: bold;"&gt;Remote Java Application&lt;/span&gt; configuration&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://1.bp.blogspot.com/_3d4j-n-2yEU/SBMiqplNGQI/AAAAAAAAAKE/ZFYDVc96BeE/s1600-h/find-remote-java-app-new.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5193532911400065282" src="http://1.bp.blogspot.com/_3d4j-n-2yEU/SBMiqplNGQI/AAAAAAAAAKE/ZFYDVc96BeE/s400/find-remote-java-app-new.png" style="cursor: pointer;" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;  &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;4. Configure the remote application's details&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://4.bp.blogspot.com/_3d4j-n-2yEU/SBMlOZlNGRI/AAAAAAAAAKM/o2z_4C10Guo/s1600-h/new-remote-app-form-filling.PNG" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5193535724603644178" src="http://4.bp.blogspot.com/_3d4j-n-2yEU/SBMlOZlNGRI/AAAAAAAAAKM/o2z_4C10Guo/s400/new-remote-app-form-filling.PNG" style="cursor: pointer;" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
5. If you would like to have this launch configuration in your favorites menu&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://2.bp.blogspot.com/_3d4j-n-2yEU/SBMlm5lNGSI/AAAAAAAAAKU/nb3eDYc70qo/s1600-h/new-remote-app-form-filling-optional.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5193536145510439202" src="http://2.bp.blogspot.com/_3d4j-n-2yEU/SBMlm5lNGSI/AAAAAAAAAKU/nb3eDYc70qo/s400/new-remote-app-form-filling-optional.png" style="cursor: pointer;" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
6. Don't forget to click &lt;span style="font-weight: bold;"&gt;Apply&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
That it. Happy remote debugging!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3745660400968632543-3364616991850057640?l=blog.srikanths.net'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=-steREtceEc:ephmpsnU7Dk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=-steREtceEc:ephmpsnU7Dk:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?i=-steREtceEc:ephmpsnU7Dk:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=-steREtceEc:ephmpsnU7Dk:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=-steREtceEc:ephmpsnU7Dk:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/SrikanthS/~4/-steREtceEc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.srikanths.net/feeds/3364616991850057640/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.srikanths.net/2008/04/how-to-debug-remote-java-app.html#comment-form" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/3364616991850057640?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/3364616991850057640?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SrikanthS/~3/-steREtceEc/how-to-debug-remote-java-app.html" title="How to Debug a Remote Java Application?" /><author><name>Srikanth</name><email>noreply@blogger.com</email></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_3d4j-n-2yEU/SBMcx5lNGPI/AAAAAAAAAJ8/IDPE3Fcktw8/s72-c/eclipse-run-debug-conf-menu-item.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">5</thr:total><feedburner:origLink>http://blog.srikanths.net/2008/04/how-to-debug-remote-java-app.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkEMRHo6eip7ImA9WxRXFUw.&quot;"><id>tag:blogger.com,1999:blog-3745660400968632543.post-4745217520559316451</id><published>2008-04-12T06:18:00.000-07:00</published><updated>2008-10-20T06:51:25.412-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-10-20T06:51:25.412-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="General" /><title>What Is Your TO-LEARN List for This Year?</title><content type="html">&lt;span style="font-size: 130%; font-weight: bold;"&gt;Face ISN'T the Index of Mind&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
I love reading interesting blogs. One of my very favorite blogs is BetterExplained by Kalid Azad. I was reading one of his posts which was about "Building a site you (and your readers) will love" and in that blog post he recommends a famous blog which I knew from a very long time but never read because they were monstrous (too long). It's none other than Steve Yegge's blog. I admire Kalid's writing and a recommendation coming from him is highly regarded by me. So, I went ahead and read a few blogs of Steve Yegge. Before reading his blog, I had a prejudice about Stevey and I thought he was just a guy who rants about things endlessly and the articles are boring and controversial (like VI vs EMACS). I never completed the first paragraph of any of his posts cause I was too scared and too tired to read due to the scroll bar's length. But this time around, I scheduled some time and read some of his writings.&lt;br /&gt;
&lt;br /&gt;
I loved his blog. I missed them all these days, but that's OK. Yes, he writes BIG articles, but they are worth reading for a programmer. In one of Stevey's posts, he talks about Practicing Programming (isn't that my blog's name?) and he gives a few drills for us. That made me think about "&lt;span style="font-weight: bold;"&gt;What do I want to learn this year?&lt;/span&gt;" I will list them here now. This will make you aware or motivate you in learning the things you have planned but never did. That's what you can take from reading this post. You can also give me suggestions if you think I am wrong somewhere with my choice. The following is the list that I made to answer that question. All the suggestions are highly appreciated.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: 130%;"&gt;&lt;span style="font-weight: bold;"&gt;(X)HTML + CSS&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
I learned HTML &amp;amp; CSS just by looking at the source of a few sites, and to customize my blog just to a point where I will be done with what I wanted. I know "what" makes it work but I don't know "how" it works. And XHTML being the language spoken by the web server to the web browser, it is my necessity to learn it well. In my honest opinion, every developer must know XHTML in today's world. (Don't you want to have your own site?)&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Book&lt;/span&gt;: Head First HTML &amp;amp; CSS&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: 130%;"&gt;&lt;span style="font-weight: bold;"&gt;Shell Scripting&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Don't I know? Yes, I do. Again, it is exactly like how I know about HTML &amp;amp; CSS. I want to learn stuffs thoroughly. I love Unix, I like to work on the command line. It makes me feel like I'm a rocket scientist doing complicated stuffs :). But that's not the point. Unix is tougher to use than MS Windows and both their philosophies are completely different. Learning Unix and Shell Scripting should be one of the top priorities for a developer who doesn't work on MS technologies. And we all the know the benefits of scripting.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Books&lt;/span&gt;: Any recommendations?&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: 130%; font-weight: bold;"&gt;Regular Expressions&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
This should be fun. Regex is very powerful and great. But with great power comes greater responsibility. So, I should really be knowing what I am doing with it. I have written a few regexes, but I am just an ordinary user. I want to elevate to the power user category in regular expressions.&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;&lt;blockquote&gt;Some people, when confronted with a problem, think “I know, I’ll use regular expressions.” Now they have two problems. --Jamie Zawinski&lt;/blockquote&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;Book&lt;/span&gt;: Mastering Regular Expressions by Jeffrey E. F. Friedl (O'Reilly)&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: 130%; font-weight: bold;"&gt;Python&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
My favorite scripting language. I love the syntax though I seriously hope that it's source code documentation gets improved (the one that we get with the help() function). Again, I know, I can write scripts, I can figure out things. But I would like to learn more here. Probably, I need to spend more time or write an Open Source module that is missing. This will surely be a good exercise to learn more.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Book&lt;/span&gt;: Python in a Nutshell by Alex Martelli (O'Reilly)&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Online&lt;/span&gt;: Tech talks about Python on Google Videos by Google's employees (Alex has one too)&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: 130%;"&gt;&lt;span style="font-weight: bold;"&gt;C&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
I'm ashamed to say that I not proficient with the mother of modern programming languages. Yeah, I know what you are saying, I learned in school. I also learned rocket science in school, does it count at NASA?&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Books&lt;/span&gt;: Any recommendations here?&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: 130%; font-weight: bold;"&gt;J2EE&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
I will be working on real J2EE applications now, not the ones we try out for learning it. I learned a lot of Servlets, JSP, EJB and so on. But never implemented them or got a chance to do these things at work so far. But now, I have to. I will learn all the buzzwords like JMS, WAS, Web Services, EJB, etc. that you "cool J2EE" dudes talk about. (Am I sounding like Stevey now? Whatever!)&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Books&lt;/span&gt;: No idea, just Google.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: 130%;"&gt;&lt;span style="font-weight: bold;"&gt;VI/VIM&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Now this will be really hard. I use Eclipse for everything and working on something tougher than notepad should be real fun. I know how to use it, I am not a complete stranger to VIM. I even know how to enable syntax highlighting, and stuff. But I want more than that. I would like to do find/replace without searching vim.org for tips (regex again). I would like to find out the total number of lines/words/characters while I am in the editor (not using grep on shell). I would like to do copy pasting very freely. I want all this to be done and more without my conscious mind getting disturbed while it's doing some other task. VIM should become the extension of my hand.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Books&lt;/span&gt;: Any suggestions?&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: 130%;"&gt;&lt;span style="font-weight: bold;"&gt;Subversion (SVN)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
I love Subversion (do you know Linus Torvalds hates it?). I love Subversion because it is free, easy to use, has excellent support for IDEs and has a huge community. I have used Subversion before at my workplace, I use it currently for my Open Source project hosted at Google Code. But I want to learn more about it. I want to know how to setup an SVN server that supports http and https connections. I want to know how the authentication and authorization need to be configured. I want to know how to work with SVN just by using the command line interface (for fun). I want to collect the useful commands, tips, and best practices.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Book&lt;/span&gt;: Version Control with Subversion (O'Reilly)&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: 130%;"&gt;&lt;span style="font-weight: bold;"&gt;Release Version 1.0 of Clipboard PingPong&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
That's the first &lt;a href="http://code.google.com/p/clipboard-pingpong/" target="_blank"&gt;open source software that I created&lt;/a&gt; which can be used to transfer clipboard contents across computers. It's at version "0.0.2" at present. I want to bring it to the general audience. Learning some of the things mentioned above will help me bring it in a better shape. It's really exciting, though it's very very small (I would like to keep it that way). Hopefully I will learn a lot from this experience and I can start contributing to other bigger and useful Open Source projects in future.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: 130%;"&gt;&lt;span style="font-weight: bold;"&gt;Blogging&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Of course. This doesn't belong in "TO-LEARN" category but it's more of a TODO. Well, blogging about blogging is generally hated. So I won't go any further, it's boring too. But I would like to quote one thing from Stevey's blog post:&lt;br /&gt;
&lt;blockquote&gt;Even if nobody reads them, you should write them. It's become pretty clear to me that blogging is a source of both innovation and clarity. I have many of my best ideas and insights while blogging. &lt;span style="font-weight: bold;"&gt;Struggling to express things that you're thinking or feeling helps you understand them better&lt;/span&gt;.&lt;/blockquote&gt;The last line is so true.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: 130%;"&gt;&lt;span style="font-weight: bold;"&gt;What If I Don't Complete Everything I Mentioned?&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
I will be very disappointed. If I don't finish the mentioned things with *satisfaction*, I will push it to next year. But life is so short and knowing these things are necessary for anyone who wants to become a good software developer. Just knowing Java, using Eclipse and developing on Windows totally sucks! Life is much bigger and better than that. I will be working very hard and pushing a lot to complete these things. But quality matters more than quantity. I would rather learn half the things mentioned here thoroughly than just skimming through everything. In fact, I know most of the things mentioned here. I just want to know them better than an average developer in the streets. My quest is understanding better than just knowing them.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: 130%;"&gt;&lt;span style="font-weight: bold;"&gt;Next Year&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
It's too early but I left out a lot of things that were there in my head. These are the things I plan to do next year:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Algorithms &amp;amp; Data Structures&lt;/li&gt;
&lt;li&gt;Algorithms &amp;amp; Data Structures (yes, I would like to do it twice)&lt;/li&gt;
&lt;li&gt;SQL in detail&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Unix Operating System in detail&lt;/li&gt;
&lt;li&gt;EMACS&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Ruby (could be replaced by Scala)&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;JDK 7 new features (with a fresh mind after learning the other things)&lt;/li&gt;
&lt;/ul&gt;That's all. (If you have read this far, you are really great!)&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: 130%; font-weight: bold;"&gt;References&lt;/span&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://betterexplained.com/"&gt;BetterExplained&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://steve.yegge.googlepages.com/practicing-programming"&gt;Practicing Programming by Steve Yegge&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://video.google.com/videosearch?q=engEDU+Python&amp;amp;sitesearch="&gt;Python Tech Talks on Google Video&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://steve.yegge.googlepages.com/you-should-write-blogs"&gt;You Should Write Blogs by Steve Yegge&lt;/a&gt;&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3745660400968632543-4745217520559316451?l=blog.srikanths.net'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=p20oegnLi3I:P-wN6XCTvIQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=p20oegnLi3I:P-wN6XCTvIQ:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?i=p20oegnLi3I:P-wN6XCTvIQ:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=p20oegnLi3I:P-wN6XCTvIQ:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=p20oegnLi3I:P-wN6XCTvIQ:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/SrikanthS/~4/p20oegnLi3I" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.srikanths.net/feeds/4745217520559316451/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.srikanths.net/2008/04/what-is-your-to-learn-list-for-this.html#comment-form" title="26 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/4745217520559316451?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/4745217520559316451?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SrikanthS/~3/p20oegnLi3I/what-is-your-to-learn-list-for-this.html" title="What Is Your TO-LEARN List for This Year?" /><author><name>Srikanth</name><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">26</thr:total><feedburner:origLink>http://blog.srikanths.net/2008/04/what-is-your-to-learn-list-for-this.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUYERXczfSp7ImA9WxRbGEU.&quot;"><id>tag:blogger.com,1999:blog-3745660400968632543.post-7757977713114050806</id><published>2008-04-04T05:31:00.000-07:00</published><updated>2008-12-09T21:31:44.985-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-12-09T21:31:44.985-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Tips" /><title>The Anatomy of a Command Line</title><content type="html">&lt;span style="font-weight: bold;font-size:130%;" &gt;Command Line&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Command line needs no introduction among the computer folks. We all know what it is. Yet, many of the developers are really scared to work on the terminal; they rather prefer GUIs. Command line somehow makes them uncomfortable. They think it is tough. In fact, when they design their own application's command line interface, they forget some of the simple and basic things they should have taken care. It will be one of my agendas in this post.&lt;br /&gt;&lt;br /&gt;You may read this post even if you are not a developer, this isn't a developer specific post.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Misconceptions/Preconceptions&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;There are two kinds of people who don't prefer command line:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The ones who've used and quit because it looked tough at the beginning&lt;/li&gt;&lt;li&gt;The ones who've never tried (I call it the &lt;span style="font-weight: bold;"&gt;startup-syndrome&lt;/span&gt;)&lt;/li&gt;&lt;/ol&gt;I went through both the phases until the bulb glowed over my head. It shouldn't be tough, computers are easy to use. After all, command line is not programming. It is aimed at the end user. The Operating System designers must have came up with some pattern before implementing these commands. Yes, the keyword is &lt;span style="font-weight: bold;"&gt;pattern&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;The Basic Syntax&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A command consists of three main parts:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;What to do?&lt;/li&gt;&lt;li&gt;How to do?&lt;/li&gt;&lt;li&gt;Other Inputs&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Can You Show Me an Example?&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Yes My Lord! Sure. Let's take an example. We will see the command line interface of the &lt;a href="http://www.freebsd.org/cgi/man.cgi?query=tail&amp;amp;apropos=0&amp;amp;sektion=0&amp;amp;manpath=FreeBSD+6.3-RELEASE&amp;amp;format=html" target="_blank"&gt;&lt;span style="font-family:courier new;"&gt;tail&lt;/span&gt;&lt;/a&gt; Unix utility. Here are the first few lines from the man page and I quote (please read it thoroughly once):&lt;br /&gt;&lt;pre class="code"&gt;NAME&lt;br /&gt;tail -- display the last part of a file&lt;br /&gt;&lt;br /&gt;SYNOPSIS&lt;br /&gt;tail [-F | -f | -r] [-q] [-b number | -c number | -n number] [file ...]&lt;br /&gt;&lt;br /&gt;DESCRIPTION&lt;br /&gt;The tail utility displays the contents of file or, by default, its stan-&lt;br /&gt;dard input, to the standard output.&lt;br /&gt;&lt;/pre&gt;The part that is found difficult and that I would like to explain here is the &lt;span style="font-weight: bold;"&gt;SYNOPSIS&lt;/span&gt;. Remember the three main parts? The what? The how? And the other inputs? Let us see these three parts for this tail command.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_3d4j-n-2yEU/R_c1eLvcpnI/AAAAAAAAAJ0/GEqr5xcY0IM/s1600-h/command-line.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://2.bp.blogspot.com/_3d4j-n-2yEU/R_c1eLvcpnI/AAAAAAAAAJ0/GEqr5xcY0IM/s400/command-line.png" alt="" id="BLOGGER_PHOTO_ID_5185672288604563058" border="0" /&gt;&lt;/a&gt;The &lt;span style="font-weight: bold;"&gt;How&lt;/span&gt; part can be a little tricky for the newbies. You may even wander what is -f? -n? number? the "|" sign? Actually, that is what makes the command line interface friendly. This little table should help you understand about the syntax.&lt;br /&gt;&lt;pre class="code"&gt;Anything inside []          = Optional&lt;br /&gt;...                         = Can occur more than once&lt;br /&gt;-something (or --something) = The How&lt;br /&gt;option1 | option2           = Either option1 or option2 can appear&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The "how" part can consist of two kinds of options. 1) Self descriptive options 2) Options that need more input.&lt;br /&gt;&lt;pre class="code"&gt;tail -v -n 25 logs.txt&lt;br /&gt;&lt;/pre&gt;The "How" in the above command tells the tail command to print the last 25 lines of the file logs.txt and print the output in verbose mode. The below figure explains better.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_3d4j-n-2yEU/R_cnKbvcpmI/AAAAAAAAAJs/48pVvw6CTa4/s1600-h/command-line-the-how.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://3.bp.blogspot.com/_3d4j-n-2yEU/R_cnKbvcpmI/AAAAAAAAAJs/48pVvw6CTa4/s400/command-line-the-how.png" alt="" id="BLOGGER_PHOTO_ID_5185656556139357794" border="0" /&gt;&lt;/a&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;The Design Difference&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In a well designed graphical user interface, everything is presented to you. You need not remember or search for anything (like the -n option). GUIs follow the "push" model. Everything is pushed to you and you get to choose. You learn and discover things quickly. Whereas, in a command line interface, you need to tell what you want to do. You need to search and "pull" the options from the manual and tell the command "how" you want to execute it.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;How *NOT* to Design a Command Line Interface&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Have you ever used a command line that was like:&lt;br /&gt;&lt;pre class="code"&gt;doSomething 49595 39504 "/usr/local/file" "/home/srikanths/dir/file"&lt;br /&gt;&lt;/pre&gt;You got the point. The "how" and the "other inputs" parts are totally messed up. You don't know the meaning of the numbers you are passing and even if you have a manual about this command, you need to refer it every time you use and you have to double check to make sure you pass the arguments correctly. A command line nightmare! Now, see the same command's better version:&lt;br /&gt;&lt;pre class="code"&gt;doSomething\&lt;br /&gt;-port 49595\&lt;br /&gt;-fallbackPort 39504\&lt;br /&gt;-configFile "/usr/local/file"\&lt;br /&gt;-fallbackConfigFile "/home/srikanths/dir/file"&lt;br /&gt;&lt;/pre&gt;So, when you design a command line interface, make it more user friendly and follow the common pattern that is already there for decades now. There are many modules available either out of the box or as frameworks that can parse the command line arguments for you. Just search which ones are the most popular CLI frameworks for your language and choose one from that. Hope this post helped you!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Bottom Line&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;"The next time you tell someone &lt;a href="http://en.wikipedia.org/wiki/RTFM" target="_blank"&gt;RTFM&lt;/a&gt;, tell them how to RTFM."&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;References&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://jopt-simple.sourceforge.net/"&gt;http://jopt-simple.sourceforge.net&lt;/a&gt;. A simple command line parser for Java.&lt;/li&gt;&lt;li&gt;&lt;a href="http://jargs.sourceforge.net/"&gt;http://jargs.sourceforge.net&lt;/a&gt;. Another CLI tool for Java. The problem is choice :)&lt;/li&gt;&lt;li&gt;&lt;a href="http://docs.python.org/lib/module-getopt.html"&gt;http://docs.python.org/lib/module-getopt.html&lt;/a&gt;. The out of the box module for Python&lt;/li&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Command_line_interface"&gt;http://en.wikipedia.org/wiki/Command_line_interface&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Other posts&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://programmingpractices.blogspot.com/2008/02/cool-firefox-tips.html"&gt;Cool Firefox Tips&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://programmingpractices.blogspot.com/2007/08/python-calculate-size-of-mysql-schema.html"&gt;Calculate size of a MySQL Schema&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3745660400968632543-7757977713114050806?l=blog.srikanths.net'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=12oalP7sr_g:d5aWj4nEy8o:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=12oalP7sr_g:d5aWj4nEy8o:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?i=12oalP7sr_g:d5aWj4nEy8o:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=12oalP7sr_g:d5aWj4nEy8o:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=12oalP7sr_g:d5aWj4nEy8o:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/SrikanthS/~4/12oalP7sr_g" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.srikanths.net/feeds/7757977713114050806/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.srikanths.net/2008/04/anatomy-of-command-line.html#comment-form" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/7757977713114050806?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/7757977713114050806?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SrikanthS/~3/12oalP7sr_g/anatomy-of-command-line.html" title="The Anatomy of a Command Line" /><author><name>Srikanth</name><email>noreply@blogger.com</email></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_3d4j-n-2yEU/R_c1eLvcpnI/AAAAAAAAAJ0/GEqr5xcY0IM/s72-c/command-line.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">5</thr:total><feedburner:origLink>http://blog.srikanths.net/2008/04/anatomy-of-command-line.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkAESXgzfCp7ImA9WxRXFUw.&quot;"><id>tag:blogger.com,1999:blog-3745660400968632543.post-8274346557772988618</id><published>2008-02-29T01:50:00.001-08:00</published><updated>2008-10-20T06:51:48.684-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-10-20T06:51:48.684-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><title>The Deadly Question!</title><content type="html">One of my favorite questions that I ask during an interview is "What is a deadlock and how do you avoid them?"&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Typical answers:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Definition: Deadlock happens when &lt;span style="font-style: italic;"&gt;Object 1&lt;/span&gt; is waiting for &lt;span style="font-style: italic;"&gt;Object 2&lt;/span&gt; which is waiting for &lt;span style="font-style: italic;"&gt;Object 1&lt;/span&gt; again.&lt;br /&gt;
&lt;br /&gt;
Avoiding deadlocks: (Answer 1): Using wait &amp;amp; notify. (Answer 2): Using synchronization.&lt;br /&gt;
&lt;br /&gt;
Not only is the terminology wrong, it also clearly shows that the candidate is not sure with the fundamentals of multi-threading. To be frank, I was asked the same question when I was interviewed and I wasn't able to give a proper answer even though I did good amount of multi-threading before to answer this innocent looking question.&lt;br /&gt;
&lt;br /&gt;
Lets suppose there are two threads T1, and T2 running in your application. T1 is executing a method called &lt;span style="font-style: italic;"&gt;method1()&lt;/span&gt; and T2 is executing &lt;span style="font-style: italic;"&gt;method2()&lt;/span&gt;. &lt;span style="font-style: italic;"&gt;method1() &lt;/span&gt;has acquired &lt;span style="font-style: italic;"&gt;lock1 &lt;/span&gt;and now it is trying to acquire &lt;span style="font-style: italic;"&gt;lock2&lt;/span&gt;. But at the same time, &lt;span style="font-style: italic;"&gt;method2() &lt;/span&gt;has acquired &lt;span style="font-style: italic;"&gt;lock2 &lt;/span&gt;and it is now trying to acquire &lt;span style="font-style: italic;"&gt;lock1&lt;/span&gt;. &lt;span style="font-style: italic;"&gt;method1() &lt;/span&gt;cannot relinquish &lt;span style="font-style: italic;"&gt;lock1 &lt;/span&gt;until it gets &lt;span style="font-style: italic;"&gt;lock2 &lt;/span&gt;and finishes the job; &lt;span style="font-style: italic;"&gt;method2() &lt;/span&gt;cannot relinquish &lt;span style="font-style: italic;"&gt;lock2 &lt;/span&gt;until it gets &lt;span style="font-style: italic;"&gt;lock1 &lt;/span&gt;and finishes the job. Both the threads, T1 and T2, are now waiting for one another to proceed their execution which will never happen. This situation is called a deadlock or a deadly embrace.&lt;br /&gt;
&lt;br /&gt;
See the following code that is almost sure to encounter a deadlock during it's execution.&lt;br /&gt;
&lt;pre class="code"&gt;public class DeadLockDemo {
private Object lock1 = new Object();
private Object lock2 = new Object();

public void method1() {
while (true) {
// Acquire lock1 first
synchronized (lock1) {
// Acquire lock2 next
synchronized (lock2) {
System.out.println("Method 1");
}
}
}
}

public void method2() {
while (true) {
// Acquire lock2 first
synchronized (lock2) {
// Acquire lock1 next
synchronized (lock1) {
System.out.println("Method 2");
}
}
}
}

public static void main(String[] args) {
final DeadLockDemo deadLockDemo = new DeadLockDemo();
Thread thread1 = new Thread() {
public void run() {
deadLockDemo.method1();
}
};

Thread thread2 = new Thread() {
public void run() {
deadLockDemo.method2();
}
};

thread1.start();
thread2.start();
}
}
&lt;/pre&gt;&lt;br /&gt;
How do we avoid this deadlock here? The typical answers like "synchronizing" the code doesn't solve the problem. Actually, deadlock happens because of improper synchronization. The answer is very simple though. Always acquire the locks in the same order. That is, acquire lock1 and then lock2 or lock2 and then lock1. Yes, it's as simple as that. You can try running the code and check it for yourself.&lt;br /&gt;
&lt;br /&gt;
Till then, happy multi-threading!&lt;br /&gt;
Srikanth&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3745660400968632543-8274346557772988618?l=blog.srikanths.net'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=5K_G-GbO4Ac:2TVqX4HGHik:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=5K_G-GbO4Ac:2TVqX4HGHik:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?i=5K_G-GbO4Ac:2TVqX4HGHik:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=5K_G-GbO4Ac:2TVqX4HGHik:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=5K_G-GbO4Ac:2TVqX4HGHik:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/SrikanthS/~4/5K_G-GbO4Ac" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.srikanths.net/feeds/8274346557772988618/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.srikanths.net/2008/02/deadly-question.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/8274346557772988618?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/8274346557772988618?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SrikanthS/~3/5K_G-GbO4Ac/deadly-question.html" title="The Deadly Question!" /><author><name>Srikanth</name><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://blog.srikanths.net/2008/02/deadly-question.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUYERH85eip7ImA9WxRbGEU.&quot;"><id>tag:blogger.com,1999:blog-3745660400968632543.post-2329511243032091032</id><published>2008-02-26T04:04:00.001-08:00</published><updated>2008-12-09T21:31:45.122-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-12-09T21:31:45.122-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Tips" /><title>Cool Firefox Tips</title><content type="html">Firefox is my favorite browser despite it's appetite for memory. I use a few command line options and extension that is worth sharing here.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Firefox Profiles:&lt;/span&gt; Do you use more than one &lt;a href="http://support.mozilla.com/kb/Profiles" target="_blank"&gt;profile in Firefox&lt;/a&gt;? It's a very useful feature. I use it when I would like to log into multiple Gmail accounts at the same time (or you can also use it if you don't use your Gmail account for other Google services such as &lt;a href="http://reader.google.com/" target="_blank"&gt;Reader&lt;/a&gt; and Orkut). My main use of the "profiles" feature is during development and testing. You can have one Firefox loaded with all the extensions in the world like Firebug, XPath viewer, various themes, etc. and you can have another light-weight Firefox with a very few extensions which you always need.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So how do you create and use another profile?&lt;br /&gt;&lt;br /&gt;&lt;pre class="code"&gt;$ firefox -profilemanager -no-remote&lt;br /&gt;&lt;/pre&gt;This opens up the following self explanatory profile launcher window:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_3d4j-n-2yEU/R8QELdPx2BI/AAAAAAAAAIE/Eauo_v8Toxo/s1600-h/firefox-profile-launcher-window.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5171262867004053522" src="http://1.bp.blogspot.com/_3d4j-n-2yEU/R8QELdPx2BI/AAAAAAAAAIE/Eauo_v8Toxo/s400/firefox-profile-launcher-window.png" style="cursor: pointer; display: block; margin: 0px auto 10px; text-align: center;" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;As you can see, I have one 'default' and one 'dev' profile. To open a particular profile:&lt;br /&gt;&lt;br /&gt;&lt;pre class="code"&gt;$ firefox -p &lt;span style="font-style: italic;"&gt;profile_name&lt;/span&gt; -no-remote&lt;br /&gt;&lt;/pre&gt;The "-no-remote" option is used from Firefox2+ when there's already a profile running.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Firefox Extensions:&lt;/span&gt; This is what makes Firefox truly a personal browser. You can create your own extensions or you can &lt;a href="https://addons.mozilla.org/en-US/firefox/" target="_blank"&gt;download and install the existing ones&lt;/a&gt; that are available on the internet. Typically, you browse for an extension and you install it using the "Install" button that is found on the website. But when you do it in this way, the installation only happens for that current profile you are using. To install an extension for all the profiles follow the steps below:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;1. Instead of directly clicking on the "Install" button, use right-click button and select "Save Link As..." and save it to your local hard drive. Typically this file is a &lt;a href="http://filext.com/file-extension/XPI" target="_blank"&gt;.xpi&lt;/a&gt; or a &lt;a href="http://filext.com/file-extension/JAR" target="_blank"&gt;.jar&lt;/a&gt; file.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;2. Type the following command on your terminal (or Start -&amp;gt; Run on Windows):&lt;br /&gt;&lt;br /&gt;&lt;pre class="code"&gt;$ firefox -install-global-extension "path_to_saved_extension_file"&lt;br /&gt;# for example:&lt;br /&gt;$ firefox -install-global-extension "c:\downloads\firefox\firebug.xpi"&lt;br /&gt;&lt;/pre&gt;My favorite Firefox extensions are:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.getfirebug.com/" target="_blank"&gt;Firebug&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/1095" target="_blank"&gt;XPath Viewer&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/3479" target="_blank"&gt;Winestripe&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/1419" target="_blank"&gt;IE Tab&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;Other recommendations:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.google.com/search?hl=en&amp;amp;q=Useful+Firefox+extensions&amp;amp;btnG=Google+Search" target="_blank"&gt;http://www.google.com/search?hl=en&amp;amp;q=Useful+Firefox+extensions&amp;amp;btnG=Google+Search&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;Happy browsing!&lt;br /&gt;&lt;br /&gt;Srikanth&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;PS:&lt;/span&gt; One more feature you may want to turn on. Firefox on Ubuntu selects the complete URL when you double click on any part of the URL. Try double clicking on any single word on this this URL: http://codeblog.srikanths.net, if you could select the complete URL then you are doing good. Otherwise, follow the steps:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Go to &lt;span style="color: #990000;"&gt;Location bar&lt;/span&gt; on Firefox (Alt + D)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Type &lt;span style="color: #990000; font-style: italic;"&gt;about:config&lt;/span&gt; and press &lt;span style="color: #990000;"&gt;ENTER&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;In the &lt;span style="color: #990000;"&gt;Filter&lt;/span&gt; text box, type this: &lt;strong&gt;layout.word_select.stop_at_punctuation&lt;/strong&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Double click to change the value to &lt;span style="color: #990000;"&gt;FALSE&lt;/span&gt; to enable URL selection while double clicking.&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;I learned this trick from &lt;a href="http://ramikayyali.com/archives/2006/02/19/fffixes" target="_blank"&gt;this blog post&lt;/a&gt;, so all the credit goes to him/her for this tip.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3745660400968632543-2329511243032091032?l=blog.srikanths.net'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=zVQYWh9EmhQ:5_ns7WfsASA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=zVQYWh9EmhQ:5_ns7WfsASA:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?i=zVQYWh9EmhQ:5_ns7WfsASA:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=zVQYWh9EmhQ:5_ns7WfsASA:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=zVQYWh9EmhQ:5_ns7WfsASA:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/SrikanthS/~4/zVQYWh9EmhQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.srikanths.net/feeds/2329511243032091032/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.srikanths.net/2008/02/cool-firefox-tips.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/2329511243032091032?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/2329511243032091032?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SrikanthS/~3/zVQYWh9EmhQ/cool-firefox-tips.html" title="Cool Firefox Tips" /><author><name>Srikanth</name><email>noreply@blogger.com</email></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_3d4j-n-2yEU/R8QELdPx2BI/AAAAAAAAAIE/Eauo_v8Toxo/s72-c/firefox-profile-launcher-window.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.srikanths.net/2008/02/cool-firefox-tips.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUYERHw-fip7ImA9WxRbGEU.&quot;"><id>tag:blogger.com,1999:blog-3745660400968632543.post-3634768444361115622</id><published>2008-02-19T00:47:00.000-08:00</published><updated>2008-12-09T21:31:45.256-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-12-09T21:31:45.256-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="General" /><title>Microformat</title><content type="html">As I was browsing through the &lt;a href="http://blog.mozilla.com/faaborg/2007/06/01/the-user-interface-of-firefox-3-features/" target="_blank"&gt;speculated features of Firefox3&lt;/a&gt;, I happened to hit something called &lt;span style="font-style: italic;"&gt;Microformats&lt;/span&gt;. If you haven't heard about it before, then I must tell you it looks very interesting to me.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Microformats in plain English:&lt;/span&gt; The content we read on the Internet using our browser is HTML. Some of those contents belong to a particular category (logically). Examples: Contact details, Events, etc. Take this scenario, lets say that you received an e-mail from your friend and your friend has sent his new address in the content of the e-mail. How nice would it be if you can add that contact details of your friend to your favorite contacts manager applications with just a click of a button without you leaving the browser?&lt;br /&gt;&lt;br /&gt;Take another scenario. You are going through &lt;a href="http://developers.sun.com/events/techdays/" target="_blank"&gt;Sun's Tech Days&lt;/a&gt; website and you see that there is a program next Sunday at your city at 12:00 PM. How nice would it be to add this event to your favorite Calendar application with just a click of a button so that it is added to your schedule and you will be reminded automatically? It would be very nice to do so.&lt;br /&gt;&lt;br /&gt;For now, the contact detail or the event detail is lying in the HTML page just like any other text or image and there is no way a software can differentiate them from the normal content. This is where Microformats are going to play a big role. The web site developer while constructing the HTML page will add some meta-data to these content which will tell the browser that the microformatted content belongs to a particular category (say, a contact detail or an event). Then the browser will visually indicate you about the content in someway and provide you an interface to do the action you would like to do (say, add that event to your Calendar). Isn't it cool?&lt;br /&gt;&lt;br /&gt;Well, this is what I understood from what I read. It could be completely different.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;References:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Microformats" target="_blank"&gt;http://en.wikipedia.org/wiki/Microformats&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blog.mozilla.com/faaborg/2006/12/11/microformats-part-0-introduction" target="_blank"&gt;http://blog.mozilla.com/faaborg/2006/12/11/microformats-part-0-introduction&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;I like the Microformat's logo, looks green and cute:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_3d4j-n-2yEU/R7qi-tPx2AI/AAAAAAAAAH8/s9yyLn4ESBc/s1600-h/microformat-logo.jpg" target="_blank"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://4.bp.blogspot.com/_3d4j-n-2yEU/R7qi-tPx2AI/AAAAAAAAAH8/s9yyLn4ESBc/s400/microformat-logo.jpg" alt="" id="BLOGGER_PHOTO_ID_5168622720542431234" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;PS:&lt;/span&gt; I noticed several times Gmail detecting the events in my e-mails' content and presenting an option to add it to Google Calendar. Bravo Gmail! You are ahead of time!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3745660400968632543-3634768444361115622?l=blog.srikanths.net'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=hffE3AxqV30:T0MwNWqkehs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=hffE3AxqV30:T0MwNWqkehs:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?i=hffE3AxqV30:T0MwNWqkehs:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=hffE3AxqV30:T0MwNWqkehs:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=hffE3AxqV30:T0MwNWqkehs:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/SrikanthS/~4/hffE3AxqV30" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.srikanths.net/feeds/3634768444361115622/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.srikanths.net/2008/02/microformats.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/3634768444361115622?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/3634768444361115622?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SrikanthS/~3/hffE3AxqV30/microformats.html" title="Microformat" /><author><name>Srikanth</name><email>noreply@blogger.com</email></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_3d4j-n-2yEU/R7qi-tPx2AI/AAAAAAAAAH8/s9yyLn4ESBc/s72-c/microformat-logo.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.srikanths.net/2008/02/microformats.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUYERHc-eyp7ImA9WxRbGEU.&quot;"><id>tag:blogger.com,1999:blog-3745660400968632543.post-1473766675876207236</id><published>2008-02-11T05:34:00.000-08:00</published><updated>2008-12-09T21:31:45.953-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-12-09T21:31:45.953-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Tips" /><title>Filter Your 'Tasks View' in Eclipse Using Patterns in TODO</title><content type="html">&lt;span style="font-weight: bold;"&gt;The Feature:&lt;/span&gt; Eclipse's &lt;span style="font-style: italic;"&gt;Tasks &lt;/span&gt;is one of my favorite features in the IDE. You can set reminders right there in your source code and you can see all of them in the &lt;span style="font-style: italic;"&gt;Tasks View&lt;/span&gt; of the IDE which you can dock it anywhere you want. A sample screenshot of the &lt;span style="font-style: italic;"&gt;Tasks View&lt;/span&gt; can be seen below.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_3d4j-n-2yEU/R7AcvtPx19I/AAAAAAAAAHg/NpOfe76CgKs/s1600-h/cluttered-tasks-view.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5165660378519164882" src="http://2.bp.blogspot.com/_3d4j-n-2yEU/R7AcvtPx19I/AAAAAAAAAHg/NpOfe76CgKs/s400/cluttered-tasks-view.png" style="cursor: pointer; display: block; margin: 0px auto 10px; text-align: center;" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The Problem:&lt;/span&gt; As you can see from the sample screenshot that many people added their own TODOs and FIXMEs. Imagine this for a big project, this will be in hundreds. The point of adding TODOs and FIXMEs right in the source code is that it can be seen more often such that we will be constantly reminded about the unfinished. But when everybody adds, it becomes a problem to keep track of your own &lt;span style="font-style: italic;"&gt;Tasks&lt;/span&gt; and we may start ignoring them like spam mail. Having control is the key to using this feature, just like e-mail.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The Solution:&lt;/span&gt; Fortunately there's a very simple solution to this problem with a little effort. You can create and configure filters, just like you can create filters for your e-mails in Gmail. On the&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;&lt;span style="font-style: italic;"&gt;Tasks View&lt;/span&gt; you will see the button using which you can create filters. See below:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_3d4j-n-2yEU/R7Aj9NPx1-I/AAAAAAAAAHo/l0XMwPmpnA8/s1600-h/filter-config-button.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5165668307028793314" src="http://4.bp.blogspot.com/_3d4j-n-2yEU/R7Aj9NPx1-I/AAAAAAAAAHo/l0XMwPmpnA8/s400/filter-config-button.png" style="cursor: pointer; display: block; margin: 0px auto 10px; text-align: center;" /&gt;&lt;/a&gt;The rest of the filter configuration work is simple. The &lt;span style="font-style: italic;"&gt;Filters&lt;/span&gt; dialog pops up and it's very intuitive as what all you can do with it. I typically create filter that contains the string "(srikanths): " in its description. And when I write my TODOs and FIXMEs, I make sure I prefix them with that description. You can come up with your own standard within your team and follow that.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The tasks that I write in the code typically look like this:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="code"&gt;// TODO(srikanths): Srikanth should come back to complete this.&lt;br /&gt;// FIXME(srikanths): Srikanth should fix this ASAP or he is dead.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_3d4j-n-2yEU/R7Au0dPx1_I/AAAAAAAAAHw/tYA_6i7AJx8/s1600-h/filters-dialog.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5165680251332843506" src="http://1.bp.blogspot.com/_3d4j-n-2yEU/R7Au0dPx1_I/AAAAAAAAAHw/tYA_6i7AJx8/s400/filters-dialog.png" style="cursor: pointer; display: block; margin: 0px auto 10px; text-align: center;" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Happy coding!&lt;br /&gt;&lt;br /&gt;Srikanth&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3745660400968632543-1473766675876207236?l=blog.srikanths.net'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=V2PwY-mVbLA:-BxQELKrIn0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=V2PwY-mVbLA:-BxQELKrIn0:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?i=V2PwY-mVbLA:-BxQELKrIn0:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=V2PwY-mVbLA:-BxQELKrIn0:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=V2PwY-mVbLA:-BxQELKrIn0:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/SrikanthS/~4/V2PwY-mVbLA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.srikanths.net/feeds/1473766675876207236/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.srikanths.net/2007/12/filter-your-tasks-view-in-eclipse-using.html#comment-form" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/1473766675876207236?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/1473766675876207236?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SrikanthS/~3/V2PwY-mVbLA/filter-your-tasks-view-in-eclipse-using.html" title="Filter Your 'Tasks View' in Eclipse Using Patterns in TODO" /><author><name>Srikanth</name><email>noreply@blogger.com</email></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_3d4j-n-2yEU/R7AcvtPx19I/AAAAAAAAAHg/NpOfe76CgKs/s72-c/cluttered-tasks-view.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">5</thr:total><feedburner:origLink>http://blog.srikanths.net/2007/12/filter-your-tasks-view-in-eclipse-using.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ck4ERn4zfyp7ImA9WxRXFUw.&quot;"><id>tag:blogger.com,1999:blog-3745660400968632543.post-4765244973330482880</id><published>2008-02-07T08:57:00.000-08:00</published><updated>2008-10-20T06:55:07.087-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-10-20T06:55:07.087-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="General" /><title>Favor 'Read' Time over 'Write' Time</title><content type="html">There are thousands of books and millions of web pages that will define modularity and explain you how to achieve them in your program. I am not going to talk about that here. I will answer you why modularity is important.&lt;br /&gt;
&lt;br /&gt;
Any program can be written in just one single method (or function). At least theoretically? The people who are new to programming do this till they are told about "Abstraction", "Encapsulation", etc. Still I see many programmers not following this. They don't modularize their program well. Sure, they understand what is going on but it's not about them. Code should be written keeping in mind that it will be read many times by many people.&lt;br /&gt;
&lt;br /&gt;
557774423456789.&lt;br /&gt;
&lt;br /&gt;
Can you repeat the number? Don't peak! :-)&lt;br /&gt;
&lt;br /&gt;
(Most of us would have not even read it completely just looking at those many digits)&lt;br /&gt;
&lt;br /&gt;
Now, read this: 55-777-44-23456789.&lt;br /&gt;
&lt;br /&gt;
So, which one was easier to read? And which one was easier to write? The first form (without the hyphen separator) was easier to write if you have this number memorized but it is hard to read and recollect for someone who is not familiar with this number. At the same time, the second form took some more time to carefully break at the right places and make it easy for the reader. We invested some more time in writing to save a lot of time for others to memorize this.&lt;br /&gt;
&lt;br /&gt;
This is the whole point. When you write code, you surely understand and it may seem trivial and waste of time to do "separation of concerns." But it's not about you or me, its about that someone who is going to maintain your code in future long after you have moved to another project. Make sure that she won't curse you :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3745660400968632543-4765244973330482880?l=blog.srikanths.net'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=zdbaXIGP05M:5agrelwmy5E:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=zdbaXIGP05M:5agrelwmy5E:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?i=zdbaXIGP05M:5agrelwmy5E:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=zdbaXIGP05M:5agrelwmy5E:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=zdbaXIGP05M:5agrelwmy5E:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/SrikanthS/~4/zdbaXIGP05M" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.srikanths.net/feeds/4765244973330482880/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.srikanths.net/2008/02/favor-read-time-over-write-time.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/4765244973330482880?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/4765244973330482880?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SrikanthS/~3/zdbaXIGP05M/favor-read-time-over-write-time.html" title="Favor 'Read' Time over 'Write' Time" /><author><name>Srikanth</name><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.srikanths.net/2008/02/favor-read-time-over-write-time.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ck4GSHwzcCp7ImA9WxRXFUw.&quot;"><id>tag:blogger.com,1999:blog-3745660400968632543.post-6425975074484091899</id><published>2008-02-03T05:29:00.000-08:00</published><updated>2008-10-20T06:55:29.288-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-10-20T06:55:29.288-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="General" /><title>Programming Language of 2007</title><content type="html">And the award goes to... &lt;span style="font-weight: bold;"&gt;Python!?!&lt;br /&gt;
&lt;br /&gt;
Source: &lt;a href="http://www.tiobe.com/tpci.htm" target="_blank"&gt;http://www.tiobe.com/tpci.htm&lt;/a&gt;&lt;/span&gt;&lt;a href="http://www.tiobe.com/tpci.htm"&gt;&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;&lt;/span&gt; &lt;/a&gt;&lt;br /&gt;
I must tell this very frankly, I am pleasantly surprised for one reason: The programming language I learned in 2007 is Python. And now it is declared as the programming language of the year. I am feeling lucky :)&lt;br /&gt;
&lt;br /&gt;
When I started learning it, I hated it for one reason ---Dynamic Typing. Coming from a heavy Java background this was a hard unlearning curve for me. I debated a lot on this topic with my friends and coworkers. I debated on Python forums about this. A very strong debate that I had can be found here (you will have fun reading this, I had fun reading my own post after a very long time!): &lt;a href="http://python-forum.org/pythonforum/viewtopic.php?f=1&amp;amp;t=3064&amp;amp;start=0&amp;amp;st=0&amp;amp;sk=t&amp;amp;sd=a" target="_blank"&gt;How to program safely in Python?&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Not only this, &lt;a href="http://www.python.org/~guido/" target="_blank"&gt;Guido van Rossum&lt;/a&gt; once replied in my post in one of the mailing lists when I asked about &lt;span style="font-weight: bold;"&gt;Why isn't there a try-catch-finally block in Python?&lt;/span&gt; It's available only from Python 2.5+. After pondering, I came to the conclusion that every programming language has its own pros and cons and Python is one such beautiful and stylish language. Yes, you don't have a compiler, yes you will have a python-bite at runtime, but guess what? A compiler only tells that your program is syntactically right. The best way to ensure that your program works is by testing, testing and more testing. Like Bruce Eckel once said, "If it isn't tested, it's broken."&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3745660400968632543-6425975074484091899?l=blog.srikanths.net'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=OSKu9Dvq6Eg:dUPDIx2jlv8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=OSKu9Dvq6Eg:dUPDIx2jlv8:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?i=OSKu9Dvq6Eg:dUPDIx2jlv8:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=OSKu9Dvq6Eg:dUPDIx2jlv8:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=OSKu9Dvq6Eg:dUPDIx2jlv8:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/SrikanthS/~4/OSKu9Dvq6Eg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.srikanths.net/feeds/6425975074484091899/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.srikanths.net/2008/02/programming-language-of-2007.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/6425975074484091899?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/6425975074484091899?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SrikanthS/~3/OSKu9Dvq6Eg/programming-language-of-2007.html" title="Programming Language of 2007" /><author><name>Srikanth</name><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.srikanths.net/2008/02/programming-language-of-2007.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0IFQXczfyp7ImA9WxNTEUU.&quot;"><id>tag:blogger.com,1999:blog-3745660400968632543.post-955752451240341692</id><published>2007-11-13T04:15:00.000-08:00</published><updated>2009-08-13T10:45:10.987-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-13T10:45:10.987-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="General" /><title>Introduction to Algorithms (An OpenCourseWare from MIT)</title><content type="html">One of my friends (&lt;a href="http://manugarg.com/"&gt;Manu Garg&lt;/a&gt;) told me about this course by MIT on Algorithms. Here are the links if you are interested:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://ocw.mit.edu/OcwWeb/Electrical-Engineering-and-Computer-Science/6-046JFall-2005/CourseHome/index.htm"&gt;Course Home&lt;/a&gt; | &lt;a href="http://ocw.mit.edu/OcwWeb/Electrical-Engineering-and-Computer-Science/6-046JFall-2005/DownloadthisCourse/index.htm"&gt;Course Download page&lt;/a&gt; | &lt;a href="http://ocw.mit.edu/OcwWeb/Electrical-Engineering-and-Computer-Science/6-046JFall-2005/LectureNotes/index.htm"&gt;Video &amp;amp; Audio lectures of the course&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
I found a way to download these courses and also some other lectures of the prerequisites for this course by Googling. Yes, it's legal and it's from MIT's website.&lt;br /&gt;
One of the prerequisites for this course is "6.001 Structure and Interpretation of Computer Programs." The first version of this course's video lectures are &lt;a href="http://www.swiss.ai.mit.edu/classes/6.001/abelson-sussman-lectures/"&gt;available here for download&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Downloading 6.046J / 18.410J Introduction to Algorithms&lt;/span&gt;:&lt;br /&gt;
&lt;br /&gt;
The URLs of the video lectures for Introduction to Algorithms have the following format:&lt;br /&gt;
&lt;pre class="code"&gt;&lt;span style="color: red; font-weight: bold;"&gt;http://mfile.akamai.com/7870/rm/mitstorage.download.akamai.com/7870&lt;/span&gt;/6/6.046j/f05/lecturenotes/ocw-6.046-07sep2005-220k.rm
&lt;/pre&gt;If you'd like to download the entire file and play it, use the following URL:&lt;br /&gt;
&lt;pre class="code"&gt;&lt;span style="color: red; font-weight: bold;"&gt;http://ocw.mit.edu/ans7870&lt;/span&gt;/6/6.046j/f05/lecturenotes/ocw-6.046-07sep2005-220k.rm
&lt;/pre&gt;The only change is the part in bold and red (i.e., till mitstorage.download.akamai.com/ in the first URL, the rest is the same.)&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Extra, extra:&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.jroller.com/ginanjar/entry/alternative_link_for_video_lectures"&gt;Alternative Link for Video Lectures&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.hanselman.com/blog/BackToBasicsAlgorithmsAndGoingBackToVirtualSchool.aspx"&gt;Scott Hanselman on Learning Algorithms&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://freescienceonline.blogspot.com/"&gt;Free Science Online&lt;/a&gt; has plenty of excellent links&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;b&gt;More Extra:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Steve Skiena's, the author of the infamous Algorithm Design Manual, lectures are available for viewing from &lt;a href="http://www.cs.sunysb.edu/%7Ealgorith/video-lectures/"&gt;here&lt;/a&gt;. He also has videos of his discrete mathematics lectures &lt;a href="http://www.cs.sunysb.edu/%7Ealgorith/math-video/"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3745660400968632543-955752451240341692?l=blog.srikanths.net'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=K4SmmO3QjRE:orQWQZfuUNM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=K4SmmO3QjRE:orQWQZfuUNM:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?i=K4SmmO3QjRE:orQWQZfuUNM:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=K4SmmO3QjRE:orQWQZfuUNM:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=K4SmmO3QjRE:orQWQZfuUNM:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/SrikanthS/~4/K4SmmO3QjRE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.srikanths.net/feeds/955752451240341692/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.srikanths.net/2007/11/introduction-to-algorithms.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/955752451240341692?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/955752451240341692?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SrikanthS/~3/K4SmmO3QjRE/introduction-to-algorithms.html" title="Introduction to Algorithms (An OpenCourseWare from MIT)" /><author><name>Srikanth</name><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://blog.srikanths.net/2007/11/introduction-to-algorithms.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0IGQ3syfSp7ImA9WxdUFkU.&quot;"><id>tag:blogger.com,1999:blog-3745660400968632543.post-4528679883975600107</id><published>2007-08-27T05:16:00.000-07:00</published><updated>2008-08-02T06:58:42.595-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-08-02T06:58:42.595-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Practices" /><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><title>Java :: FindBugs :: Dead Store</title><content type="html">I ran &lt;a href="http://findbugs.sourceforge.net/"&gt;FindBugs&lt;/a&gt; on one of our projects and I had a warning on some code similar to this, let's see how the code was written. This is just a sample code to show an example, don't expect any logic here :-)&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;// DeadStoreExample.java&lt;br /&gt;import java.util.ArrayList;&lt;br /&gt;import java.util.List;&lt;br /&gt;&lt;br /&gt;public class DeadStoreExample {&lt;br /&gt;  public static void main(String[] args) {&lt;br /&gt;    List&lt;string&gt; list = new ArrayList&lt;string&gt;(); // Dead Store here.&lt;br /&gt;    list = getList();&lt;br /&gt;    System.out.println(list);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  private static List&lt;string&gt; getList() {&lt;br /&gt;    // Some intense operation and finally we return a java.util.List&lt;br /&gt;    return new ArrayList&lt;string&gt;();&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;FindBugs reported me this problem: &lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;Dead store to list in DeadStoreExample.main(String[])&lt;/span&gt;. When I first saw it, I was like "What do you mean by Dead Store?" And when I looked into the code I saw a List&lt;string&gt; object being created but not used. Instead, in the next line the reference variable is pointing to some other object in the heap. The object created on &lt;span style="font-weight: bold;"&gt;line number 6&lt;/span&gt; is never used and hence it's a dead store.&lt;br /&gt;&lt;br /&gt;So, what is a Dead Store? If we assign a value to a local variable, but the value is not read by any subsequent instruction, then it's called a Dead Store.&lt;br /&gt;&lt;br /&gt;I love FindBugs, the thing that I like the most about FindBugs is that it tries to find all the lame bugs which many veteran programmers accidentally make. I always like to set my compiler warnings very high (even for my Javadoc comments). And now I have developed a habit of running FindBugs before I make a build or commit my code. It's one of those things like Unit Testing, you must try and get infected.&lt;br /&gt;&lt;br /&gt;If a compiler or a tool can catch a bug, then I will always go for it. No one can write bug free code, at least I have not seen anyone till now. And I believe in automating anything that is possible so that we never have to do that manually again. That's why we have computers :-)&lt;br /&gt;&lt;br /&gt;If you're not using FindBugs, I highly recommend that you to use it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3745660400968632543-4528679883975600107?l=blog.srikanths.net'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=AxISbPYXsxo:zz8Y9l5HGxs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=AxISbPYXsxo:zz8Y9l5HGxs:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?i=AxISbPYXsxo:zz8Y9l5HGxs:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=AxISbPYXsxo:zz8Y9l5HGxs:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=AxISbPYXsxo:zz8Y9l5HGxs:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/SrikanthS/~4/AxISbPYXsxo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.srikanths.net/feeds/4528679883975600107/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.srikanths.net/2007/08/findbugs-dead-store.html#comment-form" title="7 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/4528679883975600107?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/4528679883975600107?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SrikanthS/~3/AxISbPYXsxo/findbugs-dead-store.html" title="Java :: FindBugs :: Dead Store" /><author><name>Srikanth</name><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">7</thr:total><feedburner:origLink>http://blog.srikanths.net/2007/08/findbugs-dead-store.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0UFSHw7eSp7ImA9WxRXFUw.&quot;"><id>tag:blogger.com,1999:blog-3745660400968632543.post-4519892287115688459</id><published>2007-08-26T22:54:00.000-07:00</published><updated>2008-10-20T07:00:19.201-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-10-20T07:00:19.201-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><title>Python :: Calculate the Size of a MySQL Schema Approximately</title><content type="html">Hi,&lt;br /&gt;
&lt;br /&gt;
Recently I wanted to find out the total size of a schema in a MySQL database. I searched for it but can't really find it. So, I wrote something on my own, really simple which doesn't really bother about a lot of error conditions. But I think that's ok, I mean really this is not a project. I am posting my code here now, feel free to optimize it and tweak it to your own requirement and let me know if you have a better solution :-)&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="code"&gt;#!/usr/bin/python

"""Calculates the total size of a MySQL database schema approximately."""

import MySQLdb
import getpass

def main():
    db_host = raw_input('Host name: ')
    schema_name = raw_input('Schema name: ')
    user_name = raw_input('User name: ')
    password = getpass.getpass('DB Password: ')
    db_conn = MySQLdb.connect(host=db_host, user=user_name,
            passwd=password, db=schema_name)
    db_cursor = db_conn.cursor(MySQLdb.cursors.DictCursor)
    db_cursor.execute('show table status')
    rows = db_cursor.fetchall()
    total_size = 0
    for row in rows:
        data_length = row['Data_length']
        if data_length is None:
            data_length = 0
        index_length = row['Index_length']
        if index_length is None:
            index_length = 0
        total_size = total_size + data_length + index_length
    print '------------------------'
    print 'Total size: %s KB.' % str(total_size / 1024)
    db_conn.close()


if __name__ == '__main__':
    main()
&lt;/pre&gt;&lt;br /&gt;
I didn't add any exception handling code, I thought it would clutter the actual code I wanted to show.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3745660400968632543-4519892287115688459?l=blog.srikanths.net'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=HfJ5mYieeNI:ETMYUUx794k:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=HfJ5mYieeNI:ETMYUUx794k:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?i=HfJ5mYieeNI:ETMYUUx794k:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=HfJ5mYieeNI:ETMYUUx794k:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=HfJ5mYieeNI:ETMYUUx794k:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/SrikanthS/~4/HfJ5mYieeNI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.srikanths.net/feeds/4519892287115688459/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.srikanths.net/2007/08/python-calculate-size-of-mysql-schema.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/4519892287115688459?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/4519892287115688459?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SrikanthS/~3/HfJ5mYieeNI/python-calculate-size-of-mysql-schema.html" title="Python :: Calculate the Size of a MySQL Schema Approximately" /><author><name>Srikanth</name><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.srikanths.net/2007/08/python-calculate-size-of-mysql-schema.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D04NQ387cSp7ImA9WxZbEEo.&quot;"><id>tag:blogger.com,1999:blog-3745660400968632543.post-3316888679028021189</id><published>2007-04-27T04:45:00.000-07:00</published><updated>2008-04-13T01:39:52.109-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-04-13T01:39:52.109-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Tips" /><title>Eclipse :: Configuring Eclipse Startup</title><content type="html">If your eclipse is starting up a little slower or if it's running a little slower or if it gets an OutOfMemoryError, then just go through this checklist:-&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;Is it using the latest and the fastest JRE?&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;Is it having a good minimum and maximum memory?&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;And then follow this lovely blog:-&lt;br /&gt;&lt;a href="http://swem.wm.edu/blogs/waynegraham/index.cfm/2006/9/7/Tweaking-Eclipse"&gt;http://swem.wm.edu/blogs/waynegraham/index.cfm/2006/9/7/Tweaking-Eclipse&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Let me know if the link doesn't work :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3745660400968632543-3316888679028021189?l=blog.srikanths.net'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=pcIRS29gyZ0:qrq-LKqEdl4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=pcIRS29gyZ0:qrq-LKqEdl4:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?i=pcIRS29gyZ0:qrq-LKqEdl4:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=pcIRS29gyZ0:qrq-LKqEdl4:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=pcIRS29gyZ0:qrq-LKqEdl4:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/SrikanthS/~4/pcIRS29gyZ0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.srikanths.net/feeds/3316888679028021189/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.srikanths.net/2007/04/configuring-eclipse-startup.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/3316888679028021189?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/3316888679028021189?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SrikanthS/~3/pcIRS29gyZ0/configuring-eclipse-startup.html" title="Eclipse :: Configuring Eclipse Startup" /><author><name>Srikanth</name><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.srikanths.net/2007/04/configuring-eclipse-startup.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEMEQ3k-eyp7ImA9WxdUFkU.&quot;"><id>tag:blogger.com,1999:blog-3745660400968632543.post-1693323592681154072</id><published>2007-04-02T20:56:00.000-07:00</published><updated>2008-08-02T07:13:22.753-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-08-02T07:13:22.753-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Practices" /><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><title>Java :: Constants Interface or Constants Class?</title><content type="html">We all know about patterns and anti-patterns. One anti-pattern that has been hated by many people is the Constant Interface anti-pattern. Java doesn't support globals directly, but sometimes you will need to have a few things as global. Meaning, accessible to every class in your entire program.&lt;br /&gt;&lt;br /&gt;In Java to get the platform independent new line character, we write the following code:&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;final String NEW_LINE = System.getProperty("line.separator");&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;But the new line character is something any class in our program may need and writing System.getProperty("line.separator") is not good for two reasons.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;We may misspell the key 'line.separator' in which case we'll get a 'null' back, and&lt;/li&gt;&lt;li&gt;It's inefficient.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;A better way is to get this new line character one time, store it in the memory and make it accessible to all the classes in our program. This kind of a situation led to the invention of the "Constant Interface" anti-pattern. People implemented this pattern like this:&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;public interface Constants {&lt;br /&gt;  String NEW_LINE = System.getProperty("line.separator");&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And the client of this 'Constants' interface started implementing this interface for convenience reasons. This is a bad idea because let's say this 'Constants' interface has 100 constants and a client class implements this interface for convenience reasons, all the 100 constants from the interface end up being a part of the public API of the client class. This breaks inheritance and you can by now imagine how the Javadoc will look like for this client class.&lt;br /&gt;&lt;br /&gt;OK, we may ask all of our clients of this 'Constants' interface that they must not implement this interface and they should only see it as a place where global constants are stored, but what's the guarantee that they will NOT implement this interface?&lt;br /&gt;&lt;br /&gt;Thankfully we have a better way of doing this, see the following code:&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;public class Constants {&lt;br /&gt;  public static final String NEW_LINE = System.getProperty("line.separator");&lt;br /&gt;&lt;br /&gt;  private Constants() {&lt;br /&gt;    // Private constructor to enforce un-instantiability.&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The above 'Constants' class has the following benefits over the 'Constants' interface:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;No client can instantiate, because the constructor is private&lt;/li&gt;&lt;li&gt;No client can extend, again for the same reason, the constructor is private&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;Having a class for constants and making it's constructor private is a much better approach than using an interface.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3745660400968632543-1693323592681154072?l=blog.srikanths.net'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=1LFbhrXuCz0:wqmz6Rpq4UY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=1LFbhrXuCz0:wqmz6Rpq4UY:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?i=1LFbhrXuCz0:wqmz6Rpq4UY:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=1LFbhrXuCz0:wqmz6Rpq4UY:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/SrikanthS?a=1LFbhrXuCz0:wqmz6Rpq4UY:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/SrikanthS?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/SrikanthS/~4/1LFbhrXuCz0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.srikanths.net/feeds/1693323592681154072/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.srikanths.net/2007/04/java-constants.html#comment-form" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/1693323592681154072?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3745660400968632543/posts/default/1693323592681154072?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SrikanthS/~3/1LFbhrXuCz0/java-constants.html" title="Java :: Constants Interface or Constants Class?" /><author><name>Srikanth</name><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://blog.srikanths.net/2007/04/java-constants.html</feedburner:origLink></entry></feed>
