Proposal: #VersionedDependences

mark.reinhold at mark.reinhold at
Fri Dec 9 21:46:46 UTC 2016

Issue summary

  #VersionedDependences --- Consider allowing specific version strings,
  or perhaps version constraints, as an optional element of `requires`
  clauses in module declarations.  Failing that, consider allowing
  specific version strings, or perhaps version constraints, to be added
  to the dependences recorded in a compiled module descriptor; this
  would, e.g., allow a compiler or build system to record the versions
  of the modules against which a particular module was compiled, for
  use by other tools.  In either case, if such version information is
  merely informative then it will still honor the version selection
  non-requirement; if such version information is interpreted by the
  module system then that requirement may come into question. [1]


When compiling a module that depends on some other modules, record the
version strings of those modules, if available, in the resulting module
descriptor.  These version strings will not be interpreted, in any phase;
they are provided solely for diagnostic purposes and for use by tools,
frameworks, and containers that assist in the selection and validation
of module versions.  This proposal, therefore, continues to honor the
version-selection non-requirement [2].

The specific changes to implement this feature include:

  - Extend module descriptors to allow the inclusion of version strings
    in the `requires` table of the `Module` attribute by introducing a
    `u2 requires_version_index` field after the `requires_flags` field
    of each entry of that table.  The value of this new field is either
    zero, to indicate that no version string was recorded, or else the
    constant-pool index of a `CONSTANT_Utf8_info` structure whose value
    is the version string.

  - Extend the `java.lang.module.ModuleDescriptor.Requires` API with a
    single new method:

        Optional<ModuleDescriptor.Version> compiledVersion();

    This method will return an empty `Optional` object if no version
    string was recorded for the corresponding dependence, or else an
    `Optional` that contains the recorded version string.

  - Recommend that Java language compilers provide a means by which a
    version string can be indicated for any modules being compiled, and
    that they record such strings in the resulting module descriptors.
    (The RI's `javac` compiler will support this via a new command-line
    option, `--module-version`.)

  - If a compiler can record the version string of the modules being
    compiled in the resulting compiled module descriptors then it would
    be simpler for those version strings to be placed in the `Module`
    attribute rather than the ancillary `ModuleVersion` attribute.  We'll
    therefore drop the latter and add a `u2 module_version_index` field
    to the `Module` attribute, immediately following the `module_flags`

Now that compile-time versions can be recorded in module descriptors
there is even less need to tolerate version information in module names,
a bad practice that we'd like to discourage at the outset.  We therefore
further propose to:

  - Revise the accepted proposal for #VersionsInModuleNames [3] to state
    that a module name appearing anywhere in a source-form module
    declaration must both start and end with "Java letters" [4].  This
    includes the name of the module being declared and also the names of
    other modules mentioned in `requires` directives or in qualified
    `exports` or `opens` directives.  This restriction will be enforced
    by the `ModuleDescriptor.Builder` API, which is intended to be
    consistent with the source language.  The `ModuleDescriptor` API
    itself will continue to be able to read class files that contain
    module names that violate this constraint.


More information about the jpms-spec-experts mailing list