Proposal: #AutomaticModuleNames (revised)
mark.reinhold at oracle.com
mark.reinhold at oracle.com
Thu May 4 17:38:32 UTC 2017
Issue summary
-------------
#AutomaticModuleNames -- Revise the algorithm that computes the names
of automatic modules to include the Maven group identifier, when
available in a JAR file's `pom.properties` file, so that module names
are less likely to collide, or else drop the automatic-modules feature
entirely, since it may be more trouble than it's worth. [1]
Proposal
--------
- Do not drop the automatic-modules feature. It's a critical part of
the overall migration story: It allows application developers to
get started modularizing their own code without having to wait for
all of the libraries and frameworks that they use to be modularized.
Popular libraries and frameworks that are actively maintained will
hopefully be modularized fairly soon, but less-active projects will
take longer -- perhaps years or even decades -- and many inactive or
abandoned projects will never be modularized. This feature has been
well-received by a wide variety of developers despite the fact that
some expert users are not comfortable with it.
- Define a JAR-file manifest attribute, `Automatic-Module-Name`, whose
value is used as the name of the automatic module defined by that JAR
file when it is placed on the module path, as previously suggested
[2][3]. If a JAR file on the module path does not have such a
manifest attribute then its automatic-module name is computed using
the existing filename-based algorithm.
The name of this attribute is now `Automatic-Module-Name` rather than
`Module-Name`. The former makes it clear that if a JAR file on the
module path contains both an `Automatic-Module-Name` manifest
attribute and an explicit `module-info.class` file then the manifest
attribute is irrelevant, because the module defined by the JAR file
is explicit rather than automatic. `Module-Name` would also suggest
that there are `Module-Exports` and `Module-Requires` attributes,
which there are not.
With this mechanism a library maintainer can claim a stable module
name with very little effort; in Maven, e.g., a manifest attribute
can be added in just a few lines of a project's `pom.xml` file. A
library maintainer can claim a stable name early, before all of the
library's dependencies are modularized, which will allow libraries
and applications that depend upon it to be modularized immediately.
A user of a library can suggest a stable name to the library's
maintainer, and easily submit a patch that implements it. This will
enable the uncoordinated modularization of libraries across the
entire ecosystem.
- Strongly recommend that all modules be named according to the reverse
Internet domain-name convention. A module's name should correspond
to the name of its principal exported API package, which should also
follow that convention. If a module does not have such a package, or
if for legacy reasons it must have a name that does not correspond to
one of its exported packages, then its name should at least start
with the reversed form of an Internet domain with which the author is
associated.
- Make sure that developers are aware of the risks of publishing, for
broad use, explicit modules that require automatic modules. An
automatic module is unreliable, since it can depend on types on the
class path, and its name and exported packages could change if and
when it's converted into an explicit module. It's fine to declare
and use explicit modules that require automatic modules in limited
settings. If you publish such a module to, e.g., Maven Central, then
you must be prepared to revise both the declaration and content of
your module as its dependencies are modularized over time. This may
have an adverse impact on the users of your module, especially if
your module `requires transitive` an automatic module.
The following three points are essentially unchanged from the first
proposal [4]:
- Do not revise the algorithm that computes the names of automatic
modules. The suggestion to use Maven coordinates when available [5]
would help less than half of the most popular projects in use today,
as determined by three different surveys. It would result in module
names that are often annoyingly verbose and known to be objectionable
to some module authors, and it would raise non-trivial issues with
regard to standardization and convention. The names generated by the
current algorithm do not follow the reverse-DNS convention, but they
are at least easily derivable from the name of the original JAR
files. [6]
- To increase awareness of when automatic modules are used, and of the
consequences of their use, suggest that Java language compilers issue
two new types of warnings, and implement these warnings in the RI:
- An opt-in (i.e., off-by-default) warning on a reference to
an automatic module in a `requires` directive in a module
declaration, and
- An opt-out (i.e., on-by-default) warning on a reference to
an automatic module in a `requires transitive` directive in
a module declaration.
The first warning allows developers to be maximally hygienic if they
so choose. The second helps make the author of an explicit module
aware that they're putting the users of that module at risk by
establishing implied readability to an automatic module.
- Encourage Java run-time systems to make it easy to identify via,
e.g., command-line options, which observable modules are automatic,
which observable modules would establish implied readability to
automatic modules if resolved, and which automatic observable modules
are actually resolved. Implement these capabilities in the RI.
Notes
-----
This revised proposal is informed by a vigorous discussion on the OpenJDK
jigsaw-dev mailing list [7] of the first proposal [4]. Two things became
clear in that discussion, and in related discussions triggered by it.
First, after twenty years the reverse-DNS naming convention is deeply
ingrained in the minds of most Java developers. Stephen Colebourne made
a clear and passionate case for it [8] and many developers voiced support
for his argument, both on Twitter and elsewhere. Some people may prefer
shorter, project-oriented names, and those can be fine to use in limited
projects that will never, ever see the light of day outside of a single
organization. If you create a module that has even a small chance of
being open-sourced in the future, however, then the safest course is to
choose a reverse-DNS name for it at the start.
Second, the fact that the name and effective API of an automatic module
are inherently unstable is less of a problem than I previously thought
[9][a]. Developers who use Maven and related tools, such as Gradle --
which is most developers -- are used to coping with breakage when they
upgrade the dependencies of a project to a newer version [b][c]. If the
name or effective API of an automatic module change, either when its
maintainer adds an `Automatic-Module-Name` attribute or writes an
explicit `module-info.java` file, then the maintainers of projects that
use that module will just fix any problems that they encounter when they
upgrade.
After thinking about the first observation I'm now convinced that if
tools insert `Automatic-Module-Name` manifest attributes then they will
only do so when the module names that they define follow the reverse-DNS
convention, since to do otherwise would go against what most developers
strongly prefer and expect. After thinking about that and the second
observation I hereby retract [d] my previous advice [9] that automatic
modules should not be given stable names.
* * *
In related threads on jigsaw-dev both Stephen Colebourne [e] and Robert
Scholte [f] suggest a new kind of explicit module, variously called
"partial" or "incomplete" or "soft", which can read all unnamed modules
so that dependencies that have not yet been modularized can be left on
the class path. This is an attractive notion on the surface, and in fact
one that we partly implemented in the prototype code base over two years
ago, using the term "loose". We didn't pursue it then, however, and I
don't think it's worth pursuing now, for two reasons:
- If "partial" (or whatever) modules were to replace automatic modules
then application developers would have to wait until all of their
dependencies have been at least "partially" modularized before they
can even begin to experiment with modularizing their own code.
- We could solve that by keeping automatic modules and adding partial
modules, but then we'd have a more complex module system and a more
complex story to tell. To consider just one possible question,
should developers go ahead and use their dependencies as automatic
modules, or wait for them to become named automatic modules, or wait
for them to become partial modules?
The `Automatic-Module-Name` manifest attribute is, from a technical
standpoint, aesthetically unpleasant since it defines a second way
to name modules. Taken alone, however, it does enable uncoordinated
modularization using stable module names with little effort, and so
it appears to be the least-bad option on the table.
[1] http://openjdk.java.net/projects/jigsaw/spec/issues/#AutomaticModuleNames
[2] http://mail.openjdk.java.net/pipermail/jpms-spec-experts/2017-February/000582.html
[3] http://openjdk.java.net/projects/jigsaw/spec/issues/#ModuleNameInManifest
[4] http://mail.openjdk.java.net/pipermail/jpms-spec-experts/2017-April/000667.html
[5] http://mail.openjdk.java.net/pipermail/jpms-spec-experts/2017-January/000537.html
[6] http://mail.openjdk.java.net/pipermail/jpms-spec-experts/2017-April/000666.html
[7] http://mail.openjdk.java.net/pipermail/jigsaw-dev/2017-April/thread.html#11955
[8] http://blog.joda.org/2017/04/java-se-9-jpms-module-naming.html
[9] http://mail.openjdk.java.net/pipermail/jpms-spec-experts/2017-April/000682.html
[a] http://mail.openjdk.java.net/pipermail/jigsaw-dev/2017-April/012304.html
[b] http://mail.openjdk.java.net/pipermail/jigsaw-dev/2017-April/012327.html
[c] http://mail.openjdk.java.net/pipermail/jigsaw-dev/2017-April/012335.html
[d] http://mail.openjdk.java.net/pipermail/jigsaw-dev/2017-April/012367.html
[e] http://mail.openjdk.java.net/pipermail/jigsaw-dev/2017-April/012370.html
[f] http://mail.openjdk.java.net/pipermail/jigsaw-dev/2017-April/012399.html
More information about the jpms-spec-experts
mailing list