Saturday, November 29, 2008

Srikanth's Favorite Firefox Add-ons

After Google Chrome came out, I haven't been using Firefox a lot. And it's for a very simple reason: speed. 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: add-ons.

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.

Adblock

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.

Flashblock

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.

Firebug

I'm not a web-developer, still I find this add-on extremely useful. A couple of my usages are:
  • Tweaking any page and removing unwanted elements before printing
  • Learning CSS and HTML (a better way to view the source)
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.

Menu Editor

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.

Direct Link

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.

Paste to Tab and Go

Unfortunately, Paste and Go 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.

IE Tab

Useful when that stupid government site refuses to load in any browser other than IE.

Greasemonkey

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. Do you think I'm missing some amazing script? Please leave your suggestion in the comments if I'm doing so.

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:
  • Disable plugins like Acrobat Reader, Google Update
  • No themes, just the default
  • Monospace font as Consolas (I love Consolas)
So, what's your favorite add-on and why? What are the tweakings you do after installing Firefox?

Thursday, October 16, 2008

trim() for C

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 :)


#include <stdio.h>
#include <string.h>

void trim(char *s, const int len)
{
    int end = len - 1;
    int start = 0;
    int i = 0;

    while ((start < len) && (s[start] <= ' '))
    {
        start++;
    }

    while ((start < end) && (s[end] <= ' '))
    {
        end--;
    }

    if (start > end)
    {
        memset(s, '\0', len);
        return;
    }

    for (i = 0; (i + start) <= 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;
}


The main() is just for testing the function, let's see how it went.

$ gcc -Wall -o go trim.c

$ ./go
s = 'srikanth s'
empty = ''
newline = ''
double_newline = ''
single_char = 's'

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.

(Edit: Thanks to my colleague Hiren for catching a nasty bug. The memset at the end, memset((s + i), '\0', len) had a bug. It should've been memset((s + i), '\0', len - i). *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.)

That's it, see you later, I've gotta go trim.

Monday, September 8, 2008

Calling C++ Functions in C

<skippable>
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.
</skippable>

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.

The fact as I found out is that you cannot create an instance of a C++ object in your C program 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:
  1. Create an instance of a C++ class
  2. Call its methods, pass arguments, etc.
  3. Destroy the created instance.
(Instance == Object). Just thought I should let you know!
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.

// cppclass.cpp
class CppClass
{
public:
    char *returnHello()
    {
        char *ret_val = "Hello";
        return ret_val;
    }
};

But I've already told you that we can't create an instance of this class directly, so we've to provide wrapper functions 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.

(Add the following lines to cppclass.cpp file)

extern "C" void *create_cppclass()
{
    return new CppClass();
}

extern "C" char *call_return_hello(void *obj)
{
    return reinterpret_cast<CppClass*>(obj)->returnHello();
}

extern "C" void *free_cppclass(void *obj)
{
    delete reinterpret_cast<CppClass*>(obj);
}


A few things should be noticed here.

  • All these wrapper functions are preceded with extern "C" (uppercase C)
  • 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.
  • In call_return_hello() and free_cppclass() wrapper functions, we use reinterpret_cast to convert the void pointer back to CppClass pointer type. The -> operator is used for dereferencing the pointers instead of the . (dot) operator.
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.

// cfile.c
#include <stdio.h>

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);
}

Now, I'll use g++ to compile:

g++ -o go cfile.c cppclass.cpp
./go

-o indicates the executable output file name which is "go" here. Write the code and try out for yourself. It should print "Hello" (Duh!)

That's it.

Tuesday, June 24, 2008

Java One Liner - Reading a Text File at Once

Java is not meant or known for any one-liners, but who said we can't try? There you go:
String contents = new Scanner(new File("filepath")).findWithinHorizon(Pattern.compile(".*", Pattern.DOTALL), 0);

Cool, eh?

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.

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!

Sunday, May 18, 2008

Clipboard PingPong

What is it?

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.)

Wanna try? Download from here.

The Development Lesson

I learned one thing: release early. 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.

What do I need?

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 here.

Decisions

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:
  • Should be platform independent
  • Should have no library dependencies
  • Should use a simple text file for configuration (no XML)
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.

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.

Note: It also requires a desktop environment.

Thursday, April 24, 2008

How to Debug a Remote Java Application?

A Little Story

<skippable-story>
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 that 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.

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 debug?" 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.

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."

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.
</skippable-story>

Let's say you have your application compiled into a jar called myapp.jar and this will be running remotely on a machine called myremote.mycompany.com (or some IP). Your development machine is mydevel.mycompany.com. Now to debug the myapp.jar that is running remotely from your desktop machine, there are two steps you have to follow:
  1. Start the application and tell the JVM that it will be debugged remotely
  2. Configure your IDE on your desktop to be able to debug that remote application
Starting the Application with Remote Debugging Enabled

java -Xdebug -Xrunjdwp:transport=dt_socket,address=8998,server=y -jar myapp.jar
The above command says: start myapp.jar + start a server socket at port 8998 and publish the debugging messages using the Java Debug Wire Protocol (jdwp) there.

Other than address, server, and transport there are other sub options available for -Xrunjdwp option -- for example: suspend. I will leave that for you. Let's move on to step 2, that is configuring Eclipse.

Configuring Eclipse to Debug a Remotely Running Application

I will just show the screenshots without writing much, it's just intuitive that way.

1. Start Eclipse
2. Go to Run -> Debug Configurations



3. Create a new Remote Java Application configuration



4. Configure the remote application's details




5. If you would like to have this launch configuration in your favorites menu



6. Don't forget to click Apply

That it. Happy remote debugging!

Saturday, April 12, 2008

What Is Your TO-LEARN List for This Year?

Face ISN'T the Index of Mind

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.

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 "What do I want to learn this year?" 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.

(X)HTML + CSS

I learned HTML & 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?)

Book: Head First HTML & CSS

Shell Scripting

Don't I know? Yes, I do. Again, it is exactly like how I know about HTML & 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.

Books: Any recommendations?

Regular Expressions

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.

Some people, when confronted with a problem, think “I know, I’ll use regular expressions.” Now they have two problems. --Jamie Zawinski
Book: Mastering Regular Expressions by Jeffrey E. F. Friedl (O'Reilly)

Python

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.

Book: Python in a Nutshell by Alex Martelli (O'Reilly)
Online: Tech talks about Python on Google Videos by Google's employees (Alex has one too)

C

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?

Books: Any recommendations here?

J2EE

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!)

Books: No idea, just Google.

VI/VIM

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.

Books: Any suggestions?

Subversion (SVN)

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.

Book: Version Control with Subversion (O'Reilly)

Release Version 1.0 of Clipboard PingPong

That's the first open source software that I created 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.

Blogging

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:
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. Struggling to express things that you're thinking or feeling helps you understand them better.
The last line is so true.

What If I Don't Complete Everything I Mentioned?

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.

Next Year

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:
  • Algorithms & Data Structures
  • Algorithms & Data Structures (yes, I would like to do it twice)
  • SQL in detail
  • Unix Operating System in detail
  • EMACS
  • Ruby (could be replaced by Scala)
  • JDK 7 new features (with a fresh mind after learning the other things)
That's all. (If you have read this far, you are really great!)

References

Friday, April 4, 2008

The Anatomy of a Command Line

Command Line

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.

You may read this post even if you are not a developer, this isn't a developer specific post.

Misconceptions/Preconceptions

There are two kinds of people who don't prefer command line:
  1. The ones who've used and quit because it looked tough at the beginning
  2. The ones who've never tried (I call it the startup-syndrome)
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 pattern.

The Basic Syntax

A command consists of three main parts:
  1. What to do?
  2. How to do?
  3. Other Inputs
Can You Show Me an Example?

Yes My Lord! Sure. Let's take an example. We will see the command line interface of the tail Unix utility. Here are the first few lines from the man page and I quote (please read it thoroughly once):
NAME
tail -- display the last part of a file

SYNOPSIS
tail [-F | -f | -r] [-q] [-b number | -c number | -n number] [file ...]

DESCRIPTION
The tail utility displays the contents of file or, by default, its stan-
dard input, to the standard output.
The part that is found difficult and that I would like to explain here is the SYNOPSIS. Remember the three main parts? The what? The how? And the other inputs? Let us see these three parts for this tail command.

The How 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.
Anything inside []          = Optional
... = Can occur more than once
-something (or --something) = The How
option1 | option2 = Either option1 or option2 can appear

The "how" part can consist of two kinds of options. 1) Self descriptive options 2) Options that need more input.
tail -v -n 25 logs.txt
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.

The Design Difference

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.

How *NOT* to Design a Command Line Interface

Have you ever used a command line that was like:
doSomething 49595 39504 "/usr/local/file" "/home/srikanths/dir/file"
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:
doSomething\
-port 49595\
-fallbackPort 39504\
-configFile "/usr/local/file"\
-fallbackConfigFile "/home/srikanths/dir/file"
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!

Bottom Line

"The next time you tell someone RTFM, tell them how to RTFM."

References
Other posts

Friday, February 29, 2008

The Deadly Question!

One of my favorite questions that I ask during an interview is "What is a deadlock and how do you avoid them?"

Typical answers:

Definition: Deadlock happens when Object 1 is waiting for Object 2 which is waiting for Object 1 again.

Avoiding deadlocks: (Answer 1): Using wait & notify. (Answer 2): Using synchronization.

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.

Lets suppose there are two threads T1, and T2 running in your application. T1 is executing a method called method1() and T2 is executing method2(). method1() has acquired lock1 and now it is trying to acquire lock2. But at the same time, method2() has acquired lock2 and it is now trying to acquire lock1. method1() cannot relinquish lock1 until it gets lock2 and finishes the job; method2() cannot relinquish lock2 until it gets lock1 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.

See the following code that is almost sure to encounter a deadlock during it's execution.
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();
}
}

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.

Till then, happy multi-threading!
Srikanth

Tuesday, February 26, 2008

Cool Firefox Tips

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.



Firefox Profiles: Do you use more than one profile in Firefox? 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 Reader 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.



So how do you create and use another profile?

$ firefox -profilemanager -no-remote
This opens up the following self explanatory profile launcher window:





As you can see, I have one 'default' and one 'dev' profile. To open a particular profile:

$ firefox -p profile_name -no-remote
The "-no-remote" option is used from Firefox2+ when there's already a profile running.



Firefox Extensions: This is what makes Firefox truly a personal browser. You can create your own extensions or you can download and install the existing ones 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:



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 .xpi or a .jar file.



2. Type the following command on your terminal (or Start -> Run on Windows):

$ firefox -install-global-extension "path_to_saved_extension_file"
# for example:
$ firefox -install-global-extension "c:\downloads\firefox\firebug.xpi"
My favorite Firefox extensions are:

Other recommendations:

Happy browsing!

Srikanth



PS: 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:

  1. Go to Location bar on Firefox (Alt + D)

  2. Type about:config and press ENTER

  3. In the Filter text box, type this: layout.word_select.stop_at_punctuation

  4. Double click to change the value to FALSE to enable URL selection while double clicking.

I learned this trick from this blog post, so all the credit goes to him/her for this tip.

Tuesday, February 19, 2008

Microformat

As I was browsing through the speculated features of Firefox3, I happened to hit something called Microformats. If you haven't heard about it before, then I must tell you it looks very interesting to me.

Microformats in plain English: 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?

Take another scenario. You are going through Sun's Tech Days 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.

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?

Well, this is what I understood from what I read. It could be completely different.

References:
I like the Microformat's logo, looks green and cute:


PS: 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!

Monday, February 11, 2008

Filter Your 'Tasks View' in Eclipse Using Patterns in TODO

The Feature: Eclipse's Tasks 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 Tasks View of the IDE which you can dock it anywhere you want. A sample screenshot of the Tasks View can be seen below.





The Problem: 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 Tasks and we may start ignoring them like spam mail. Having control is the key to using this feature, just like e-mail.



The Solution: 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 Tasks View you will see the button using which you can create filters. See below:



The rest of the filter configuration work is simple. The Filters 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.



The tasks that I write in the code typically look like this:



// TODO(srikanths): Srikanth should come back to complete this.
// FIXME(srikanths): Srikanth should fix this ASAP or he is dead.






Happy coding!

Srikanth

Thursday, February 7, 2008

Favor 'Read' Time over 'Write' Time

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.

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.

557774423456789.

Can you repeat the number? Don't peak! :-)

(Most of us would have not even read it completely just looking at those many digits)

Now, read this: 55-777-44-23456789.

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.

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 :-)

Sunday, February 3, 2008

Programming Language of 2007

And the award goes to... Python!?!

Source: http://www.tiobe.com/tpci.htm


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 :)

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!): How to program safely in Python?

Not only this, Guido van Rossum once replied in my post in one of the mailing lists when I asked about Why isn't there a try-catch-finally block in Python? 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."