Proposal: #NonHierarchicalLayers

David M. Lloyd david.lloyd at
Mon Jan 30 15:13:31 UTC 2017

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.

>>> The `add{Opens,Exports}ToAll` variants shouldn't be needed since you can
>>> just include unqualified `open` and `exports` directives in the module
>>> descriptor that you're going to build anyway.  That has the additional
>>> benefit of making the exports apparent to the JPMS resolver so that JPMS
>>> modules can resolve against your modules, whereas invoking these methods
>>> wouldn't do that.
>> The problem is that when I first build the module, I don't have all the
>> dependency information available, and also some of the dependencies will
>> include modules which are not visible to the layer (in fact right now
>> I'm putting each module into a separate layer), and some of the
>> dependencies are on non-Jigsaw entities which I also can't know initially.
>>> The `addPackage` method is problematic, in part since it's quite slow
>>> (at least in HotSpot, where we've optimized for the common case of the
>>> set of packages in a module never changing).  Can't you compute the set
>>> of packages in a module at the time you create the descriptor?
>> Two things prevent this: firstly, we don't have the module contents
>> until after we've constructed the module class loader, which requires
>> the layer controller in order to process dependencies, so as of now,
>> adding contents depends on having the module established.  Secondly, it
>> is allowed to add content to a JBoss module after it has been
>> established.  The first might be fixable, but I can't think of a way
>> around the second.
> Me neither.
> 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 

> 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

> - Mark


More information about the jpms-spec-observers mailing list