Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is an automatic module?

Automatic modules are mentioned many times on stackoverflow but I couldn't find a complete, succinct and self-sufficient definition of an automatic module.

So, what is an automatic module? Does it export all packages? Does it open all packages? Does it read all other modules?

like image 399
ZhekaKozlov Avatar asked Oct 14 '17 07:10

ZhekaKozlov


People also ask

What is automatic module name?

The module is a collection of packages designed for reuse, and Module JAR is a regular JAR with a module descriptor in its root folder. An Automatic Module is a JAR from the classpath that has been put in the module path. Their name is derived from the jar file name by default.

Do you have to use modules in Java?

No. There is no need to switch to modules. There has never been a need to switch to modules. Java 9 and later releases support traditional JAR files on the traditional class path, via the concept of the unnamed module, and will likely do so until the heat death of the universe.

What is unnamed module?

An unnamed module is a JAR that is built without module-info. java declaration. An unnamed module will require all other modules and will export all its packages as well. Type 2: Named Module. A named module is a module that is created with a module declaration file module-info.

What is module-info in Java?

module-info. java file. It declares the dependencies within the module system and allows the compiler and the runtime to police the boundaries/access violations between the modules in your application.


1 Answers

I first answer your actual question ("What is an automatic module?"), but I also explain what they are there for. It is hard to understand why automatic modules behave the way they do without that information.

What is an automatic module?

The module system creates a module from every JAR it finds on the module path. For modular JARs (i.e. those with module descriptors) that is straightforward as they define the module's properties (name, requires, exports). For plain JARs (no module descriptor) this approach doesn't work, so what should the module system do instead? It automatically creates a module - an automatic module, so to speak - and takes the most safe guesses for the three properties.

Name

Deriving the name is a two-step process:

  • if the JAR defines the Automatic-Module-Name header in its manifest, it defines the module's name
  • otherwise, the JAR file name is used to determine the name

The second approach is intrinsically unstable, so no modules with a dependency on such an automatic module should be published. Maven warns about that.

Requires

Since a plain JAR expresses no requires clauses, the module system lets automatic modules read all other modules that make it into the readability graph (aka module graph). Unlike explicit modules, automatic ones also read the unnamed module, which contains everything that was loaded from the class path. This seemingly minor detail turns out to be very important (see below).

Automatic modules have some further readability quirks, though:

  • As soon as the first automatic module is resolved, so are all others. That means once a single plain JAR on the module path is referenced by another module, all plain JARs are loaded as automatic modules.
  • Automatic modules imply readability on all other automatic modules, which means a module reading one of them, reads all of them.

Taken together this can have the unfortunate effect that an explicit module (i.e. a non-automatic one) that depends on several plain JARs can get away with only requiring one of them (as long as the others end up on the module path as well).

Exports/Opens

Since the JAR contains no information which packages are considered public APIs and which aren't, the module system exports all packages and also opens them for deep reflection.

More

The module system also scans META-INF/services and makes the automatic module provide the services named therein. An automatic module is assumed allowed to use all services.

Finally, the Main-Class manifest entry is processed as well, so a plain JAR that defines one can be launched just like an automatic module where the main class was set with the jar tool (i.e. java --module-path my-app.jar --module my.app).

Proper module

Once the automatic module was created, it is treated as any other module. This explicitly includes that the module system checks it a any other module, for example for split packages.

What is an automatic module for?

One of the reasons for introducing modules was to make compiling and launching applications more reliable and find errors sooner that was possible with the class path. A critical aspect of that are requires clauses.

To keep them reliable, there is no way for a module declaration to require anything other than a named module, which excludes everything loaded from the class path. If the story ended here, a modular JAR could only depend on other modular JARs, which would force the ecosystem to modularize from the bottom up.

That is unacceptable, though, so automatic modules were introduced as a means for modular JARs to depend on non-modular ones and all you need to do for that is place the plain JAR on the module path and require it by the name the module system gives it.

The interesting bit is that because automatic modules read the unnamed module, it is feasible (and I generally recommend doing that) to leave its dependencies on the class path. This way automatic modules act as a bridge from the module to the class path.

Your modules can sit on one side, require their direct dependencies as automatic modules, and indirect dependencies can remain on the other side. Every time one of your dependencies turns into an explicit module, it leaves the bridge on the modular side and draws its direct dependencies as automatic modules onto the bridge.

like image 116
Nicolai Parlog Avatar answered Sep 21 '22 19:09

Nicolai Parlog