Surprises with Java packages
Packages in Java is a quite simple and straightforward concept of the language. It’s there from the beginning and it’s commonly used by every Java programmer. In a few words, these are the rules you have to follow to create a class inside a package (spoiler: which are not completely true, as we’ll see later):
- Package statement must be the first one specified in a java class file
- A package namespace must match the physical path of the file, i.e a class defined with a package
a.b.c
must be placed in a patha/b/c/
Easy right? Let’s check…
Turns out that the second rule is not mandatory but a recommendation (a good one, BTW), but Eclipse IDE enforces it to the point that if you don’t follow it, it throws a compilation error. Let’s open the following class in Eclipse:
package a.b.c;
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}
And you’ll get the following error:
But as I said, it’s not a restriction of the language but from the IDE itself:
- https://bugs.eclipse.org/bugs/show_bug.cgi?id=16209
- http://stackoverflow.com/questions/8395916/package-name-is-different-than-the-folder-structure-but-still-java-code-compiles
In fact, turns out that manually compiling this class works perfectly fine (also tried maven and worked flawesly):
$ javac src/HelloWorld.java -d bin
$ java -cp bin a.b.c.HelloWorld
Hello world!
$ tree bin/
bin/
└── a
└── b
└── c
└── HelloWorld.class
Corollary: if you’re a programmer, don’t trust even the most basic and accepted statement you could think of. Even if you’re absolutely right at this very moment, it will eventually be modified and surprise you.