Spring's need for optional dependencies
Ali Ebrahimi
ali.ebrahimi1781 at gmail.com
Fri Dec 18 16:28:40 UTC 2015
Hi,
Can we all agree that native Optional dependency support would be clean,
best and reasonable solution.
On Fri, Dec 18, 2015 at 7:47 PM, Peter Levart <peter.levart at gmail.com>
wrote:
> Hi Ali,
>
> On 12/18/2015 05:05 PM, Ali Ebrahimi wrote:
>
> Hi,
> In general, your workaround has some disadvantages:
> 1) Existing code does not work as is: (your need read edges)
>
>
> See my message written concurrently with your's ;-) Optional dependency
> could add a read edge for you if the target module was pulled in by some
> other means, but would not cause it to be pulled in.
>
> 2) command line options only apply to boot layer not to dynamic
> configurations created by future containers
>
>
> Who knows what future containers will do. They are free to add all modules
> deployed in a deployment unit as root modules to the layer configuration.
> Root modules could be listed in a deployment descriptor of the deployment
> unit. Jigsaw is providing the API for them to do what they want.
>
> Regards, Peter
>
>
>
> On Fri, Dec 18, 2015 at 7:19 PM, Peter Levart <peter.levart at gmail.com>
> wrote:
>
>> Hi Paul,
>>
>> I think we are not in disagreement. We are just talking of slightly
>> different things. So let me answer your concerns...
>>
>> On 12/17/2015 06:14 PM, Paul Benedict wrote:
>>
>>> Peter, thanks for your comments. I differ in that I don't see any
>>> problems with optional dependencies. Right now, like in Spring, optional
>>> features are enabled with a Class.forName() runtime check; if
>>> ClassNotFoundException is captured, the feature is unavailable. I expect
>>> that coding pattern to continue with optional dependencies. Libraries know
>>> how to check if a class is available and fallback to another plan when it's
>>> not.
>>>
>>
>> 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.
>>
>> What's different with jigsaw is how you include an optional module in the
>> runtime configuration.
>>
>> Now you do this:
>>
>> java -classpath ....:/path/to/my-optional-module.jar:...
>>
>> With jigsaw you do this:
>>
>> java -mp /repository/of/modules -addmods ...:my-optional-module:...
>>
>> What's nice is that you don't have to remember to put the module into the
>> 'repository-of-modules'. You just have to remember to '-addmods
>> my-optional-module' and jigsaw will tell you if it can't find it. So you
>> have explicit control from command line.
>>
>>
>>> Regarding your concern on the command line, I am not sure if people will
>>> be using the command line often. I expect tools to eventually read the
>>> Module Descriptors and assemble the correct list of modules. I believe
>>> Maven is currently investigating something similar right now. Currently,
>>> Jigsaw only reads a module directory, but eventually individual jars will
>>> be able to be listed. Just let tools solve this problem.
>>>
>>
>> I think this feature is only meant to simplify establishing a set of
>> searchable modules when each of them is found in a directory with some
>> other files that would otherwise be in the way if the directory as a whole
>> was included in the modulepath (think of automatic modules). And that's
>> only needed when compiling or running directly from the layout of Maven
>> local repository. Application assembly usually puts all modules into a
>> single archive. I believe this could be a .jimage file in the future.
>>
>> When you put something in -modulepath, it does not automatically become
>> part of your runtime configuration and I think it should not. The concept
>> of listing the root module(s) explicitly and letting the system figure out
>> the transitive closure which then becomes a set of modules included in the
>> runtime configuration is a powerful concept. And I think optional modules
>> should not automatically be included in the runtime configuration.
>>
>> All that Juergen has to tell jigsaw Spring users is to "require" the
>> modules that are Spring optional dependencies in their own root application
>> module and jigsaw will make sure they are included at runtime. Or users can
>> choose to delay that decision to launch runtime by not "require"-ing the
>> modules and using -addmods option instead.
>>
>> Regards, Peter
>>
>>
>>> Cheers,
>>> Paul
>>>
>>> On Thu, Dec 17, 2015 at 10:58 AM, Peter Levart <
>>> <peter.levart at gmail.com>peter.levart at gmail.com <mailto:
>>> peter.levart at gmail.com>> wrote:
>>>
>>> Hi,
>>>
>>>
>>> On 12/17/2015 12:03 PM, Stephen Colebourne wrote:
>>>
>>> And here are the threads for Joda projects, which also need
>>> optional
>>> dependencies:
>>>
>>> http://mail.openjdk.java.net/pipermail/jigsaw-dev/2015-December/005462.html
>>>
>>> http://mail.openjdk.java.net/pipermail/jigsaw-dev/2015-December/005638.html
>>>
>>> Note, I do not consider command line flags to be acceptable as
>>> a solution.
>>>
>>> Stephen
>>>
>>>
>>> On 17 December 2015 at 09:41, Stephane Epardaud
>>> <stef at epardaud.fr <mailto:stef at epardaud.fr>> wrote:
>>>
>>> As I already mentioned, we also have the need for this in
>>> Ceylon, for
>>> the same reasons. Dependencies are required at
>>> compile-time but optional
>>> at run-time, based on detection: if it's there fine, if
>>> not then no problem.
>>>
>>>
>>>
>>> The only problem I see with optional dependencies at runtime is as
>>> follows...
>>>
>>> If "requires optional X" semantic was to include the module X in
>>> configuration if it could be found with module finder (on
>>> -modulepath), otherwise not, then the established configuration
>>> would not only be dependent on command-line arguments, but also on
>>> the content of module directories. If there was a common directory
>>> used as a repository for various modules, you would not be able to
>>> opt-out of using a particular module if it was declared as
>>> optional dependency and included in the modulepath.
>>>
>>> So instead of assembling command-line arguments (-addmods ...),
>>> you would be forced to assemble private module directories for
>>> each particular configuration.
>>>
>>> Contrasting this with what we have now, the classpath: you have to
>>> declare that you use a particular optional dependency on command
>>> line, by mentioning it on the -classpath. And when you do that
>>> (assemble a -classpath command line argument), the configuration
>>> does not even check that it really is there. If the .jar file
>>> isn't there, it is simply ignored.
>>>
>>> So I think the safe "requires optional X" semantic would have to
>>> be such that it acts as two descriptors:
>>>
>>> requires X - at compile time
>>>
>>> nothing - at runtime (no attempt to find the module and add it to
>>> configuration)
>>>
>>> You would still have to put -addmods X to command line, but then
>>> you would have a total control over configuration from
>>> command-line only.
>>>
>>> Optional dependencies basically then just reduce to a means to
>>> have two different descriptors: one for compile-time and one for
>>> run-time, where run-time has a sub-set of requires from
>>> compile-time descriptor. It can be done now (with separate
>>> compilation), but it would be convenient to have a single
>>> descriptor with two scopes of requires.
>>>
>>> Regards, Peter
>>>
>>>
>>>
>>
>
>
> --
>
> Best Regards,
> Ali Ebrahimi
>
>
>
--
Best Regards,
Ali Ebrahimi
More information about the jigsaw-dev
mailing list