What does "Required filename-based automodules detected." warning mean?
Solution 1:
Automatic module recap
An explicit module (i.e. one with a module-info.java
) can only access code of modules that it requires (ignoring implied readability for a moment). That's great if all dependencies are modularized, but what if they are not? How to refer to a JAR that isn't modular?
Automatic modules are the answer: Any JAR that ends up on the module path gets turned into a module. If a JAR contains no module declaration, the module system creates an automatic module with the following properties:
- inferred name (this is the important bit here)
- reads all other modules
- exports all packages
Maven relies on that mechanism and once you create a module-info.jar
it places all dependencies on the module path.
Automatic names
There are two ways to infer an automatic module's name:
- entry in the manifest
- guess from the JAR file name
In the first case, the name was deliberately picked by the maintainer, so it can be assumed to be stable (for example it doesn't change when the project gets modularized). The second one is obviously unstable across the ecosystem - not all project setups lead to the exact same file names of their dependencies.
What does it mean?
The reason for the warnings is that some of your dependencies are automatic modules and do not define their future module name in the manifest. Instead, their name is derived from the file name, which makes them unstable.
Stable names
So why are unstable names such a problem? Assume your library gets published with requires guava
and my framework gets published with requires com.google.guava
. Now somebody uses your library with my framework and suddenly they need the modules guava and com.google.guava on their module path. There is no painless solution to that problem, so it needs to be prevented!
How? For example by discouraging developers from publishing artifacts that depend on filename-based automatic modules. 😉
Solution 2:
[WARNING] * Required filename-based automodules detected. Please don't publish this project to a public artifact repository! *
Is that because I have only a few modules with module-info.java and not the whole project?
No, its not because of a few module listed on the module-info.java
but generated by the maven-compiler-plugin
for all the automatic modules found in the module graph.
What does it mean?
Not to publish the current project is insisted probably since the automatic modules are expected to be converted to named or explicit modules by their owners and then published to repositories which might result in change to their module name as well. Additionally a precautionary point to note here is that according to the progress document of Maven ~> Java+9+-+Jigsaw, they are still not completely ready with the JDK9 compatible plugin versions.
Just to portray an example for such a use case. Think over these lines -
- I've published an artifact
com-foo-bar:1.0.0-SNAPSHOT:jar
. - Another project of mine
com-xyz:1.0.0
depends on it. - Eventually a project of yours relies on
com-foo-bar
transitively viacom-xyz
-
You plan to modularize your code and make use of something like
module your.module { requires com.foo.bar; requires com.xyz; }
(you need to specify the transitive dependencies in the module declarations separately)
- All worked fine, but until the time I decided to modularize my libraries.
- Now, the first thing I did was name my modules!
-
And I did something fantastic to explicitly call out my efforts like this:-
module modular.com.foo.bar {}
I end up breaking the code of any dependent library and eventually any that depends on yours in a modularized way.
Note: I agree over not practicing to use SNAPSHOTs in production, but there could be cases when eventually you rely on an artifact which is still in development phase.
Edit: From the comments by @khmarbaise
Its understood that people would wish to publish to artifactories but if they are not aware of the consequences you will be beaten in the future by this.
Maven would like to make it clear that the WARNING in this case is very serious which could have instead been a FAILURE but that would had been a bad user experience to deal with.
The ideal way to deal with this is that the library owners plan to migrate their artifacts to JDK9 and the tree is traversed bottom-up in which case the named/explicit module would be the only aspect prevailing without the need of the automatic module names and such warnings.