Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8348404

Make automatic modules and the classpath read all observable modules

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Unresolved
    • Icon: P4 P4
    • None
    • None
    • core-libs
    • None

      Automatic modules do not declare their required dependencies. This can lead us down one of two paths, and automatic modules do not enjoy reliable configuration regardless of which of them is taken: 1. We could interpret that to mean that the module requires nothing and we expect the application to provide the necessary dependencies with `--add-modules` (possibly `--add-modules ALL-MODULE-PATH`) or 2. we could interpret that to mean that the automatic module implicitly (possibly) requires all observable modules.

      Currently, we do something in between. If any automatic module is a root module or (transitively) required by a root module then all automatic modules are loaded, but not other observable modules. In other words, this behaviour implicitly makes all automatic modules potential dependencies of each other, but it doesn't make explicit modules dependencies of automatic modules, even though there is no reason they shouldn't be.

      This behavior makes replacing the classpath with the module path more challenging:

      * An artifact on the classpath can freely make use of system modules required by `java.se`, but moving such a (non-modular) artifact to the module path requires `--add-modules` for system modules it uses other than `java.base`.

      * Consider a module path consisting of artifacts `A`, `B`, and `C`, whose (possibly implied) dependencies are `A -> B -> C` and `A` is root (e.g. `-m A`). If `A` is modular (and so `requires B`) but `B` and `C` are not -- they're automatic modules -- then the module path would work with no additional flags. But if `C` is then upgraded to a modular version, the program will not work without `--add-modules C` (or `--add-modules ALL-MODULE-PATH`).

      Additionally, if the entry point to the program is on the classpath and an automatic module is not transitively required by the root modules that are used in that case, we need to `--add-modules` the automatic module.

      This behavior does not improve reliable configuration, but it hinders the migration process from the classpath to the module path and from non-modular to modular artifacts when modular and non-modular artifacts are mixed on the module path. Neglecting to add appropriate `--add-modules` flags will result in runtime errors that won't be present if the artifacts are placed on the classpath, and the required `--add-modules` may change whenever any non-modular artifact is upgraded.

      The current behavior was chosen under the assumption that the module path may contain a great many modules -- including those that cannot peacefully coexist in the same resolved module graph -- and from which multiple projects each make use of a small portion. In practice, however, module paths, rather than being shared among projects, are typically constructed for a particular project by some build tool, and are quite minimal and "clean".

      Consequently, to improve usability and to aid migration to the module path and to modular artifacts, the behavior of the launcher should change such that if an automatic module is loaded, then *all* observable modules -- automatic and explicit alike -- are resolved, including all those on the module path as well as all modules in the runtime image (as if by `--add-modules ALL-MODULE-PATH --add-modules ALL-SYSTEM`).

      Furthermore, if the entry point to the program is on the classpath, then all automatic modules on the module path should be loaded.

      This, too, does not achieve reliable configuration when automatic modules are used, but it does allow artifacts to be gradually (and transparently) modularized, and that gradually achieves reliable configuration.

      The behavior of `javac` and `jlink` need not be affected by this change (?).

      This is a command-line incompatible change, as an existing command line may now load more modules than before, including those that may not coexist in the same module graph, which will cause a failure to launch. Alternatively, this change could be made backward compatible (at the cost of complicating the spec) by reverting to the "old" behavior if any `--add-modules` flag that isn't either `ALL-MODULE-PATH` or `ALL-SYSTEM` is present on the command line.

            Unassigned Unassigned
            rpressler Ron Pressler
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated: