Proposal: #NonHierarchicalLayers

David M. Lloyd david.lloyd at
Wed Dec 7 04:43:00 UTC 2016

On 12/06/2016 05:08 PM, David M. Lloyd wrote:
> On 12/05/2016 06:21 PM, David M. Lloyd wrote:
>> On 12/05/2016 05:08 PM, mark.reinhold at wrote:
>>> 2016/11/29 18:51:22 -0800, david.lloyd at
>>>> On 11/29/2016 06:10 PM, mark.reinhold at wrote:
>>>>> 2016/11/22 13:23:34 -0800, david.lloyd at
>>>>>> ...
>>>>>> To degenerate the problem to the simplest case: I may have to
>>>>>> layers, A
>>>>>> and B, which are unrelated and both contain a module X.  I may need
>>>>>> the
>>>>>> module X in one layer to have a dependency on the module X in another
>>>>>> layer.  Unless there's new code I haven't seen, each dependency is
>>>>>> expressed by name only, therefore this is impossible.  Whereas in our
>>>>>> system, a dependency is a tuple of (module loader, module name),
>>>>>> allowing arbitrary weaving of modules from different name spaces
>>>>>> with no
>>>>>> problem.
>>>>>> I don't think we need it to work the exact same way, but we need some
>>>>>> equivalent.
>>>>> If this is how you need resolution to work for your modules then can't
>>>>> you write your own resolver to make it so, using whatever additional
>>>>> (weak) data structures you need to associate names with layers, class
>>>>> loaders, etc., in whatever manner you require?
>>>> No, because the input to the resolver is just a name; there's no other
>>>> context to say which layer the module comes from, without some kind of
>>>> name mangling scheme which raises more problems (we ran into exactly
>>>> this issue more than six years ago).  In other words I can require a
>>>> module named "X", but I can't say that I require the module "X" from
>>>> this other layer/namespace; rather I have to flatten out all my
>>>> namespaces in a way that can be mutually resolvable, which means that I
>>>> must ultimately constrain user module names in some weird way.  This is
>>>> not so good when modules refer to one another by name programmatically,
>>>> nor in diagnostic output.
>>> So, what do you suggest we do?
>> Is it possible to add overloads in ModuleDescriptor.Builder like this:
>>   // Export to the named module in the given layer
>>   ModuleDescriptor.Builder exports(String pn, String target, Layer
>> targetLayer);
>>   // Add dependence on module with the given name in the given layer
>>   ModuleDescriptor.Builder requires(String mn, Layer layer);
>>   ModuleDescriptor.Builder requires(Set<Modifier> mods, String mn, Layer
>> layer);
>> I think that's all that's necessary.
> I'm currently looking into defining modules with no dependency
> information, and adding all the exports after the fact: that might be a
> solution to this.

OK so my initial experiments indicate that I'd need at least a few more 
methods added to Layer.Controller to make this work.  I did need a 
small-ish patch to let me get some tests working, which can be viewed at and 
taken from there if these changes make sense (or I can bring this up on 
jigsaw-dev if that's where this discussion should take place).

I could probably get away without add*ToAllUnnamed (which are just there 
to allow for a few more interop options) if there's a security or other 
risk involved in that construct (I couldn't think of anything in 
particular though).

I'm still trying to devise tests that would show if this is actually 
working in nontrivial cases, but the fact that I've gotten it to run 
through at least the existing basic JBoss Modules unit tests is a good sign.

I think I'm also running across the same issue that Tom Watson raised 
last Tuesday about not knowing in advance what services are being used 
by a module.  I seem to recall that we discussed allowing the Layer to 
mediate service load requests made by modules within that layer; is that 
something I've recalled correctly, and if so, is that option still on 
the table?


More information about the jpms-spec-experts mailing list