When we create java classes, we group them in packages so that we can manage them properly. We are using file systems to store our classes and we learned to map a package name to a corresponding folder:

• Oracle java tutorial summary package:
> The path names for a package’s source and class files mirror the name of the package.
• Java language specification host support for packages:
> Under this simple organization of packages, an implementation of the Java SE platform would transform a package name into a pathname by concatenating the components of the package name, placing a file name separator (directory indicator) between adjacent components.

I followed this rule and never thought to break it. A few years ago I was involved in a big refactoring for one project and we managed somehow to move few java files in a package that did not matched the folder structure. IntelliJ Idea did not complained, code was compiled and run. Nobody from our side noticed it because we all used Idea and the issue was discovered by the client because somebody used Eclipse. We fixed the issue by moving the classes into the right folders, we wondered a little bit and then we forgot.

I remembered these days about that issue and I discussed with my colleagues about it. We did not have a common understanding; some said that the code should not compile, others thought that even it it compiles, it will fail at runtime. I decided to check and share the findings.

I created the following files:

SamePackageAsPath – A class that behaves as expected, with package name in mirrored folder structure:

DifferentPackageThanPath – A class that is in the same folder as SamePackageAsPath but with a different package:

PackageNameTest – A class used to instantiate the other two classes. I used another package so that I need import statements:

I use Intellij Idea 15 community edition and it fails to compile above code but it compiles perfectly from command line. It also runs and the result is:

I also wanted to find out what happens if I add the following classes directly in src/main/java where classes with default package should exist but use package names:

Again Idea failed to compile but everthing compiled and run perfectly from command line:

The complete file structure for both java and class files is:

My conclusion is that the rule to mirror package name to folder structure is for generated class files and not for the sources. What is your opinion on this?

A similar discussion can be read on stack overflow.

Image credit: PublicDomainPictures, CC0 Public Domain

This site uses Akismet to reduce spam. Learn how your comment data is processed.