Hi Paul,

On 12/18/2015 05:49 PM, Paul Benedict wrote:
Peter, when you say Jigsaw "doesn't search for module B" when it's optional, what do you mean by "search"?

To construct a layer (java.lang.reflect.Layer), a configuration (java.lang.module.Configuration) must 1st be created (from example in the javadoc):

 *     ModuleFinder finder = ModuleFinder.of(dir1, dir2, dir3);
 *
 *     Configuration cf
 *         = Configuration.resolve(finder,
 *                                 Layer.boot().configuration(),
 *                                 ModuleFinder.empty(),
 *                                 "myapp")
 *                        .bind();

...which takes a ModuleFinder, a parent Layer's configuration, and a set of root module names ("myapp" in above example). The resolve() method uses module finder and root module names to "search" for root modules and all their transitive dependencies (mentioned in their "requires" clauses). If any of those modules is not found, exception is thrown. The transitive closure of modules is then augmented with providers ("provides" clause) of services that those modules "use" (the bind() method). This is how the final set of modules that are part of the layer that is build from the configuration is constructed. Other modules that are left behind in the -modulepath directories and are not part of the configuration are not available to the runtime.

I'm suggesting that "requires optional" semantic should not count as a "soft" dependency when the transitive closure of modules is computed, but should add a read edge if the target module is included in the configuration by some other means (a normal "requires" from the module already part of configuration, -addmods option, etc.).

Regards, Peter


Cheers,
Paul

On Fri, Dec 18, 2015 at 10:42 AM, Peter Levart <peter.lev...@gmail.com <mailto:peter.lev...@gmail.com>> wrote:

    Hi Paul,

    On 12/18/2015 05:14 PM, Paul Benedict wrote:
    Adding read edges at runtime is not a backward compatible
    solution. Jigsaw should automatically allow you to read anything
    your Module Descriptor gives you access to -- required or optional.

    I was maybe not clear enough. So here's in the example. Suppose
    module A is a root module (the one mentioned in java -m option):

    module A {
        requires B;
    }

    ...searches for module B on -module-path and adds it to runtime
    configuration, failing to start the program if B is not found. If
    B is found it adds a read edge from A -> B.

    module A {
        requires optional B;
    }

    ... doesn't search for module B but still adds a read edge from A
    -> B if B happens to be included in the configuration by some
    other means. The 'other means' could be anything from:

    - some other module that is already a part of configuration
    "requires B" (say a root application module directly or a
    transitive dependency)
    - adding -addmods B command line option
    - deployment descriptor of a .mwar application says so


    I can certainly say that this is backward compatible in code. The
    code stays the same.

    I'm all *for* intorducing optional dependencies concept into the
    deployment descriptor. It's just that I don't see -modulepath as
    an equivalent to -classpath in the sense that optional dependency
    should make module part of the configuration when it happens to be
    searchable.

    Regards, Peter


    Cheers,
    Paul

    On Fri, Dec 18, 2015 at 10:02 AM, Peter Levart
    <peter.lev...@gmail.com <mailto:peter.lev...@gmail.com>> wrote:



        On 12/18/2015 04:49 PM, Peter Levart wrote:

            You can check whether the optional module is included in
            a runtime configuration or not with a simple
            Class.forName() check even if you don't depend on the
            module (i.e. don't list it in "requires" descriptor at
            runtime). The visibility of classes is not restricted. It
            only depends on ClassLoader hierarchy. When you
            successfully resolve some optional class at runtime (with
            Class.forName), you then have to add a read edge to it's
            module:

                Class<?> optionalClass = Class.forName("...");
            MySelfClass.getModule().addRead(optionalClass.getModule());

            ...before invoking any code that uses this module.


        Just had an idea!

        Optional dependency at runtime could add a read edge to the
        module if that module was included in the configuration, but
        would otherwise not cause that module to be included in the
        configuration by itself. How does that sound? Spring would
        work as before - no .addRead() calls needed. Just
        Class.forName("OptionalClass").

        Regards, Peter





Reply via email to