Re: #CompileTimeDependencies and module resolution

2017-01-13 Thread Remi Forax
Ok, thanks.

Rémi

- Mail original -
> De: "Sander Mak" <sander@luminis.eu>
> À: "jigsaw-dev" <jigsaw-dev@openjdk.java.net>
> Envoyé: Vendredi 13 Janvier 2017 14:47:59
> Objet: Re: #CompileTimeDependencies and module resolution

> On 13 Jan 2017, at 14:37, fo...@univ-mlv.fr<mailto:fo...@univ-mlv.fr> wrote:
> 
> As i've read the mail of Sander,
> the module which is required statically is present in the module path but not
> resolved by default, you have to use --add-modules. But maybe i'm wrong ?
> 
> You're not wrong, see the email exchange with Stephen as well. Just a 
> `requires
> static` does not cause a module to be resolved from the module path, there
> needs to be a non-static requires or --add-modules for the optional module.
> This is intentional behaviour according to the proposal:
> http://mail.openjdk.java.net/pipermail/jpms-spec-experts/2016-June/000306.html
> 
> 
> Sander


Re: #CompileTimeDependencies and module resolution

2017-01-13 Thread Remi Forax
- Mail original -
> De: "David M. Lloyd" <david.ll...@redhat.com>
> À: "Sander Mak" <sander@luminis.eu>, "jigsaw-dev" 
> <jigsaw-dev@openjdk.java.net>
> Envoyé: Vendredi 13 Janvier 2017 15:23:56
> Objet: Re: #CompileTimeDependencies and module resolution

> On 01/13/2017 06:48 AM, Sander Mak wrote:
>>
>>> The standard use case for the feature is for libraries with optional
>>> dependencies:
>>
>> That is indeed the use case I was thinking of.
>>
>>> The --add-modules flag is only relevant when using the command line to
>>> turn setup #1 into setup #2, something which should be rare.
>>
>> Interesting, so what you're saying is if an application wants the optional
>> behaviour of Lib through A, the application module itself (or any of its
>> modules) has to declare a non-optional dependency in its descriptor on module
>> A. Even though, technically, this application module doesn't have any direct
>> relation at all with A. If you do that, the application can freely use types
>> exported from A. Which is not always what you want (in most cases even, I'd
>> say). For example, Lib would be a machine learning library that the 
>> application
>> uses and A would be a super-fast matrix multiplication library (possibly with
>> native code not available on all platforms, so it has to be optional). I 
>> won't
>> ever use the matrix multiplication lib A directly in my application, but I 
>> want
>> it to be used by Lib for increased performance.
>>
>> What I was expecting, is that the mere presence of A on the module path would
>> cause it to be resolved when Lib is resolved, without needing a non-static
>> requires or --add-modules. Conversely, if A isn't there, Lib would get 
>> resolved
>> without A just as well. Obviously Lib needs to guard for this situation, as 
>> you
>> said.
> 
> This is the intuitive behavior I also expect of an optional dependency.
> The problem however is that a static dependency isn't an optional
> dependency; it's a compile-time-only dependency, which is not exactly
> the same thing.
> 
> We (Jigsaw) don't have a concept of an optional dependency (i.e. one
> that is eagerly used if present but does not cause an error if absent)
> at all.  Maybe we should though, as experience has shown that this is a
> useful operating mode.

You can implement it at runtime if you control the Layer, either by removing 
the requires directive or by synthetising a fake module descriptor 
corresponding to the dependency.

> 
>> Alternatively, you can view optional dependency usage more like 'if the
>> application already uses A, then Lib should also use A as well' in which case
>> your suggested setup and the current implementation make total sense. This 
>> does
>> make the example I described above a bit awkward, but I don't have any data 
>> on
>> which use case is more prevalent.
>>
>> Thanks for the insights!
>>
>>
>> Sander
>>
> 
> --
> - DML

Rémi


Re: #CompileTimeDependencies and module resolution

2017-01-13 Thread David M. Lloyd

On 01/13/2017 06:48 AM, Sander Mak wrote:



The standard use case for the feature is for libraries with optional
dependencies:


That is indeed the use case I was thinking of.


The --add-modules flag is only relevant when using the command line to
turn setup #1 into setup #2, something which should be rare.


Interesting, so what you're saying is if an application wants the optional 
behaviour of Lib through A, the application module itself (or any of its 
modules) has to declare a non-optional dependency in its descriptor on module 
A. Even though, technically, this application module doesn't have any direct 
relation at all with A. If you do that, the application can freely use types 
exported from A. Which is not always what you want (in most cases even, I'd 
say). For example, Lib would be a machine learning library that the application 
uses and A would be a super-fast matrix multiplication library (possibly with 
native code not available on all platforms, so it has to be optional). I won't 
ever use the matrix multiplication lib A directly in my application, but I want 
it to be used by Lib for increased performance.

What I was expecting, is that the mere presence of A on the module path would 
cause it to be resolved when Lib is resolved, without needing a non-static 
requires or --add-modules. Conversely, if A isn't there, Lib would get resolved 
without A just as well. Obviously Lib needs to guard for this situation, as you 
said.


This is the intuitive behavior I also expect of an optional dependency. 
The problem however is that a static dependency isn't an optional 
dependency; it's a compile-time-only dependency, which is not exactly 
the same thing.


We (Jigsaw) don't have a concept of an optional dependency (i.e. one 
that is eagerly used if present but does not cause an error if absent) 
at all.  Maybe we should though, as experience has shown that this is a 
useful operating mode.



Alternatively, you can view optional dependency usage more like 'if the 
application already uses A, then Lib should also use A as well' in which case 
your suggested setup and the current implementation make total sense. This does 
make the example I described above a bit awkward, but I don't have any data on 
which use case is more prevalent.

Thanks for the insights!


Sander



--
- DML


Re: #CompileTimeDependencies and module resolution

2017-01-13 Thread Sander Mak

On 13 Jan 2017, at 14:37, fo...@univ-mlv.fr wrote:

As i've read the mail of Sander,
the module which is required statically is present in the module path but not 
resolved by default, you have to use --add-modules. But maybe i'm wrong ?

You're not wrong, see the email exchange with Stephen as well. Just a `requires 
static` does not cause a module to be resolved from the module path, there 
needs to be a non-static requires or --add-modules for the optional module. 
This is intentional behaviour according to the proposal: 
http://mail.openjdk.java.net/pipermail/jpms-spec-experts/2016-June/000306.html


Sander


Re: #CompileTimeDependencies and module resolution

2017-01-13 Thread Alan Bateman

On 13/01/2017 12:48, Sander Mak wrote:


:
Alternatively, you can view optional dependency usage more like 'if the 
application already uses A, then Lib should also use A as well' in which case 
your suggested setup and the current implementation make total sense. This does 
make the example I described above a bit awkward, but I don't have any data on 
which use case is more prevalent.

For Stephen's example then it would be better to steer people to using 
services and avoid the reflection guard that Lib would need to cope with 
A not being resolved.


`requires static A` does have its usages of courses, the main one is 
where `module A` only exports packages containing annotations and where 
those annotations may not be present at run time.


-Alan.


Re: #CompileTimeDependencies and module resolution

2017-01-13 Thread forax
As i've read the mail of Sander,
the module which is required statically is present in the module path but not 
resolved by default, you have to use --add-modules. But maybe i'm wrong ?

Rémi

- Mail original -
> De: "Alan Bateman" <alan.bate...@oracle.com>
> À: "Remi Forax" <fo...@univ-mlv.fr>, "Sander Mak" <sander@luminis.eu>
> Cc: "jigsaw-dev" <jigsaw-dev@openjdk.java.net>
> Envoyé: Vendredi 13 Janvier 2017 12:33:53
> Objet: Re: #CompileTimeDependencies and module resolution

> On 13/01/2017 11:08, Remi Forax wrote:
> 
>> Hi Sander,
>> you're right, it's a bug, --add-modules should not be necessary.
>>
>> Rémi
> I don't think there is a bug here. Instead the example that Sander has
> chosen doesn't resolve a module that `requires B`. The "Notes" section
> in #CompileTimeDependences proposal has the rational for this. If the
> example is extended to:
> 
> module A { requires static B; requires C; }
> module B { ... }
> module C { requires B; }
> 
> then the resulting module graph will have contain at least A, B and C,
> and A will read at least B and C.
> 
> -Alan


Re: #CompileTimeDependencies and module resolution

2017-01-13 Thread Sander Mak

> The standard use case for the feature is for libraries with optional
> dependencies:

That is indeed the use case I was thinking of.

> The --add-modules flag is only relevant when using the command line to
> turn setup #1 into setup #2, something which should be rare.

Interesting, so what you're saying is if an application wants the optional 
behaviour of Lib through A, the application module itself (or any of its 
modules) has to declare a non-optional dependency in its descriptor on module 
A. Even though, technically, this application module doesn't have any direct 
relation at all with A. If you do that, the application can freely use types 
exported from A. Which is not always what you want (in most cases even, I'd 
say). For example, Lib would be a machine learning library that the application 
uses and A would be a super-fast matrix multiplication library (possibly with 
native code not available on all platforms, so it has to be optional). I won't 
ever use the matrix multiplication lib A directly in my application, but I want 
it to be used by Lib for increased performance. 

What I was expecting, is that the mere presence of A on the module path would 
cause it to be resolved when Lib is resolved, without needing a non-static 
requires or --add-modules. Conversely, if A isn't there, Lib would get resolved 
without A just as well. Obviously Lib needs to guard for this situation, as you 
said.

Alternatively, you can view optional dependency usage more like 'if the 
application already uses A, then Lib should also use A as well' in which case 
your suggested setup and the current implementation make total sense. This does 
make the example I described above a bit awkward, but I don't have any data on 
which use case is more prevalent.

Thanks for the insights!


Sander

Re: #CompileTimeDependencies and module resolution

2017-01-13 Thread Stephen Colebourne
The standard use case for the feature is for libraries with optional
dependencies:

module Lib { requires static A; requires B; }
module A { ... }
module B { ... }

Given this setup:
 module App1 { requires Lib; }
the module graph should include App1, Lib and B.
Any use of A from Lib must be guarded, as A is not present.

Given this setup:
 module App2 { requires Lib; requires A }
the module graph should include App1, Lib, A and B.
Module A will be visible and read by Lib.

ie. the optional depenedency expresses the concept of "use module A if
it is available, otherwise ignore it"


The --add-modules flag is only relevant when using the command line to
turn setup #1 into setup #2, something which should be rare.

Stephen


On 13 January 2017 at 11:33, Alan Bateman  wrote:
> On 13/01/2017 11:08, Remi Forax wrote:
>
>> Hi Sander,
>> you're right, it's a bug, --add-modules should not be necessary.
>>
>> Rémi
>
> I don't think there is a bug here. Instead the example that Sander has
> chosen doesn't resolve a module that `requires B`. The "Notes" section in
> #CompileTimeDependences proposal has the rational for this. If the example
> is extended to:
>
> module A { requires static B; requires C; }
> module B { ... }
> module C { requires B; }
>
> then the resulting module graph will have contain at least A, B and C, and A
> will read at least B and C.
>
> -Alan


Re: #CompileTimeDependencies and module resolution

2017-01-13 Thread Alan Bateman

On 13/01/2017 11:08, Remi Forax wrote:


Hi Sander,
you're right, it's a bug, --add-modules should not be necessary.

Rémi
I don't think there is a bug here. Instead the example that Sander has 
chosen doesn't resolve a module that `requires B`. The "Notes" section 
in #CompileTimeDependences proposal has the rational for this. If the 
example is extended to:


module A { requires static B; requires C; }
module B { ... }
module C { requires B; }

then the resulting module graph will have contain at least A, B and C, 
and A will read at least B and C.


-Alan


Re: #CompileTimeDependencies and module resolution

2017-01-13 Thread Remi Forax
Hi Sander,
you're right, it's a bug, --add-modules should not be necessary.

Rémi

- Mail original -
> De: "Sander Mak" <sander@luminis.eu>
> À: "jigsaw-dev" <jigsaw-dev@openjdk.java.net>
> Envoyé: Vendredi 13 Janvier 2017 11:39:10
> Objet: #CompileTimeDependencies and module resolution

> When you have a module A with an optional dependency on B (`requires static 
> B`),
> module B is not resolved from the module path unless `--add-modules B` is
> provided at startup (tested with jigsaw-b151). In [1] this is mentioned as a
> detail, and in fact  it is phrased as a question there. Is this still an open
> question? Because in my mind, expressing an optional dependency *and* having 
> to
> add the module as root module to get it resolved seems a bit over the top (and
> typically you'd also have to add it as dependency in your build tool of choice
> to get it on the module path).
> 
> "If it's on the module path, use it, otherwise, ignore it" is intuitively more
> appealing to me for optional dependencies. It also more closely resembles the
> way things currently work on the classpath with many frameworks.
> 
> For linking, I can see why adding optional modules explicitly is better. 
> Still,
> I think not having to do this at run-time (just like service provider modules
> are resolved at run-time but not at link-time) makes more sense.
> 
> 
> Regards,
> Sander
> 
> 
> [1] 
> http://openjdk.java.net/projects/jigsaw/spec/issues/#CompileTimeDependences


#CompileTimeDependencies and module resolution

2017-01-13 Thread Sander Mak
When you have a module A with an optional dependency on B (`requires static 
B`), module B is not resolved from the module path unless `--add-modules B` is 
provided at startup (tested with jigsaw-b151). In [1] this is mentioned as a 
detail, and in fact  it is phrased as a question there. Is this still an open 
question? Because in my mind, expressing an optional dependency *and* having to 
add the module as root module to get it resolved seems a bit over the top (and 
typically you'd also have to add it as dependency in your build tool of choice 
to get it on the module path). 

"If it's on the module path, use it, otherwise, ignore it" is intuitively more 
appealing to me for optional dependencies. It also more closely resembles the 
way things currently work on the classpath with many frameworks. 

For linking, I can see why adding optional modules explicitly is better. Still, 
I think not having to do this at run-time (just like service provider modules 
are resolved at run-time but not at link-time) makes more sense.


Regards,
Sander


[1] http://openjdk.java.net/projects/jigsaw/spec/issues/#CompileTimeDependences