Java – Why are packages and modules separate concepts in Java 9

javalanguage-designmodulespackages

Java 9 will have modules in addition to packages.
Usually languages have one or the other.
And most programmers perceive two terms as synonyms.

Modules are built on top of packages, treating them as primitives.

Composite pattern suggests to treat primitives and composites uniformly.
Otherwise bad things will happen.
For example, look at project Valhalla, where they try to retrofit common supertype for primitive (value) and reference types.

Do modules and packages represent semantically separate notions?

Meaning it is sensible to have both for any language
(separation of concerns).
Or Java has to have both as a tribute to backward compatibility?

Why introduce a new concept instead of augmenting the existing one?


JSR 376: "Java platform module system" implemented within project Jigsaw.

According to SOTMS

A module is a named, self-describing collection of code and data. Its code is organized as a set of packages containing types, i.e., Java classes and interfaces; its data includes resources and other kinds of static information.

JLS carefully avoids defining what is a package. From Wikipedia:

A Java package is a technique for organizing Java classes into namespaces similar to the modules of Modula, providing modular programming in Java.

I know that quoting Wikipedia is a bad practice, but it reflects common understanding. From the entry on modular programming:

The term package is sometimes used instead of module (as in Dart, Go, or Java). In other implementations, this is a distinct concept; in Python a package is a collection of modules, while in the upcoming Java 9 the introduction of the new module concept (a collection of packages with enhanced access control) is planned.

Best Answer

The concept of a module is different from the instantiation of that concept.

Java has always had modules. A method is a module, so is a class and so is a package. A module is a unit of organisation in which internal details are hidden, and that communicates with other modules via agreed contracts. For example, a method is a module because it has hidden internals (the code and local variables) and a contract (the parameters and return type). Modules can be composed out of lower-level modules, e.g. classes contain methods.

What's missing in core Java (pre-9) is a deployable module. All the above kinds of module are not deployable units that can be copied around. Java does have a deployable artifact called a JAR file, but these are not modules because they have no encapsulation or contract: at runtime JAR files disappear, all merging together into a single "classpath".

OSGi addressed the lack of deployable modules in 1998 with the concept of a "bundle". These are physically JAR files and they contain packages, but OSGi defines additional metadata along with a runtime system to support encapsulation and contracts at that level.

Java 9 addresses the lack of deployable modules in a similar way to OSGi. Arguably this was completely unnecessary because OSGi exists and works, but that's a whole different discussion...

Unfortunately Java 9 muddies the waters by naming the new module concept just a "module". This does not mean that methods, classes and packages stop being modules! A J9 "module" is just another instantiation of the module concept. Like OSGi bundles, J9 modules are made out of packages and they are physical artifacts (usually JAR files again) that can be copied around. The runtime system understands and reifies them.

Summary: yes J9 modules and packages are semantically separate notions. Obviously Java has to retain its existing package concept for backwards compatibility. Note that the word "package" is used quite differently in Java than in other languages or in package management systems like RPM. The new J9 modules (and OSGi bundles) are much more like packages in RPM than Java packages ever were.