Proposal: #NonHierarchicalLayers

mark.reinhold at mark.reinhold at
Wed Feb 15 19:51:08 UTC 2017

2017/1/30 7:13:31 -0800, david.lloyd at
> On 01/26/2017 04:34 PM, mark.reinhold at wrote:
>> 2016/12/13 6:47:53 -0800, david.lloyd at
>>> On 12/12/2016 05:23 PM, mark.reinhold at wrote:
>>>> 2016/12/8 5:46:24 -0800, david.lloyd at
>>>>>  ...  I've added the following methods to Layer.Controller:
>>>>> public Controller addPackage(Module source, String pn) { ... }
>>>>> public Controller addOpens(Module source, String pn, Module target) { ... }
>>>>> public Controller addOpensToAll(Module source, String pn) { ... }
>>>>> public Controller addOpensToAllUnnamed(Module source, String pn) { ... }
>>>>> public Controller addExports(Module source, String pn, Module target) {
>>>>> ... }
>>>>> public Controller addExportsToAll(Module source, String pn) { ... }
>>>>> public Controller addExportsToAllUnnamed(Module source, String pn) { ... }
>>>>> public Controller addUses(Module source, Class<?> service) { ... }
>>>> Can you explain exactly why you need all these methods?
>>>> I can see why you might need the qualified `addExports` method, akin
>>>> to the existing `addOpens` method, if you're doing some form of module
>>>> resolution on your own that's somehow taking named layers, or whatever,
>>>> into account.
>>> Yeah we're assembling the module structure in a multi-stage lazy
>>> resolution process, thus we don't know exactly what we're opening or
>>> exporting until after all contents and dependencies are defined (and
>>> this can change over time).
>> Hmm.  This seems to be a fundamental difference between JBoss modules and
>> OSGi.  Once an OSGi bundle is loaded then its exports don't change, at
>> least not until it's updated, and this is part of what enables Watson's
>> JPMS embedding to work.
> OSGi does support dynamic attachments of fragments.  The current 
> prototype cannot do this but on Jan. 4 Thomas expressed that being able 
> to add packages would enable this part of the specification.  Re-linking 
> everything is (according to this email) an alternative that comes at the 
> cost of not supporting this feature.

True, but Thomas later recommended against complicating JPMS in order to
support this feature of OSGi [1].  He can live with having to re-resolve
bundles when fragments add API packages, which is not common and arguably
an anti-pattern.

>> ...
>> For any kind of Watson-style embedding of JBoss modules in JPMS to work
>> then there has to be a point in time at which you can say "okay, this
>> JBoss module is in a stable state, let's spin up a JPMS module descriptor
>> for it so that the JPMS resolver can resolve some JPMS modules against
>> it."  If the JBoss module is updated later on then you create a new JPMS
>> module descriptor for it and re-resolve any JPMS modules that used to
>> depend upon it.
> In order to do this we have to shut down all existing deployments in the 
> container that have any kind of dependency relationship, and restart 
> them.  This is not really acceptable as it defeats the purpose of the 
> mechanism.
>> Can you, in general, identify such points in time for JBoss modules?
> Any time the user deploys additional or replacement content is a point 
> where a module may need to be updated.
>> If so, then I don't think you need the above methods.  The JPMS module
>> descriptor that you construct needn't capture all the details of the
>> corresponding JBoss module.  In fact it can't, since JBoss modules can
>> relate to each other in ways that aren't expressible in JPMS.  That's
>> fine, though -- the module descriptor need only expose the information
>> that the JPMS resolver needs for actual JPMS modules, mainly `opens`,
>> `exports`, and `requires transitive`.
>> If not, then adding the above methods won't help you anyway.  They only
>> affect the run-time state of modules, i.e., the state known to the JVM
>> and surfaced in `java.lang.reflect.Module`.  The JPMS resolver doesn't
>> read the run-time state but, rather, the configurations computed by
>> earlier invocations of the resolver, and ultimately those are all based
>> on module descriptors, over in the `java.lang.module` package.
> Currently the prototype code does not use the JPMS resolver.  From my 
> understanding, the JVM tables mediate access control, but the actual 
> linkage between classes at run time happens via 
> java.lang.ClassLoader#findClass(java.lang.String, java.lang.String).  As 
> long as this method resolves

This sentence is incomplete, so I'm not sure what you meant to say here.

At any rate, if you're not eventually going to use the JPMS resolver to
resolve some JPMS modules against some JBoss modules, in order to obtain
bidirectional interoperation as is now possible with OSGi [2], then why
bother with any of this?

- Mark


More information about the jpms-spec-experts mailing list