Earth Hour

Sunday, October 25, 2009

Donate water

Saturday, October 24, 2009

Dealing with a Strange Java Problem

Here is a strange problem encountered by me while experimenting with Java. Have a look at the following code sample:

interface test {

void fun();
}

public class Test implements test {

public void fun() {
System.out.println("Test.fun() called");
}

public static void main(String[] args) {
new Test().fun();
}
}



Can you find any problem with the above code sample? Well there really isn't any problem with the above code. Still when you try to run this on Windows systems the execution fails for Test class ( i.e. >java Test) throwing exceptions like:-

java.lang.NoClassDefFoundError: test (wrong name: Test)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.security.AccessController.doPrivileged(Native Method)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:276)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.security.AccessController.doPrivileged(Native Method)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:276)
Exception in thread "main"
Exception in thread "main" Java Result: 1


And adding to the surprise, this program runs absolutely fine on Linux and other Unix based systems!

Ok so lets try to dissect the program and figure out what the problem is with this. Here is the possible explaination which I came up with.
Observing it a little carefully you can observe that the name of the interface is 'test' and class is 'Test' this makes them differ only in case. But what difference does it make to us? java is of course case sensitive, so we are free to chose names like that!
Well the answer is that, although java is case sensitive the underlying OS ( Windows) is not. Therefore the compiler (even though it wanted) couldn't create two separate .class files (one for interface, and other for the implementing class), because the other class file over-writes the previous one. In short, this problem arises because after compiling the above code, two class files: test.class and Test.class map only to a single file on windows, not two unlike the unix systems.
So be careful while getting trapped in such of hard-to-find bugs!