Dynamic modules and bidirectional interoperation

Thomas Watson tjwatson at us.ibm.com
Fri Oct 28 19:20:51 UTC 2016


> From: forax at univ-mlv.fr
> To: Thomas Watson/Austin/IBM at IBMUS
> Cc: mark reinhold <mark.reinhold at oracle.com>, jpms-spec-observers 
> <jpms-spec-observers at openjdk.java.net>
> Date: 10/28/2016 11:01 AM
> Subject: Re: Dynamic modules and bidirectional interoperation
> 
> Hi Thomas,
> first, sorry,
> I'm not able to parse my own mail correctly.
> 
> Let's try again,
> currently a way to solve your issue is to allow a Layer to have 
> several parents,
> i really dislike this idea because it introduces an arbitrary order 
> that is hidden deep in the code thus makes really hard to reason 
> about which Layer resolve what,
> for me it's not different to add a kind of classpath resolution in 
> the middle of the module resolution.

I don't have near the history with JPMS as this group. I'm going out on a 
limb talking about the definitive behavior of the JMPS runtime, but here 
goes. Today layers are searched for required modules in a specific single 
parent order.  First the local layer is searched, if not found look in the 
parent layer, do this until the empty layer is reached.  For example, look 
at the following layers:

 A -> B -> C 

These are simply searched in order A, B, C.
Now we introduce multiple parents:

 A -> B -> C
  \-> D -> E

These are searched in order A, B, C, D, E.  From the perspective of layer 
A I would expect a consistent resolution result as if you had a single 
parent hierarchy.

 A -> B -> C -> D -> E

The problem I do see though is what happens if you have the following:

 layer B has modules X and Z
 layer D has modules Y and Z 
 both modules X and Y requires public Z
 layer A has module W which requires both X and Y

This better result in some kind of error regardless if single or 
multi-parent layers are used because in both cases module W is getting 
exposed to two copies of the Z module (through dependencies X.B->Z.B and 
Y.D->Z.D).  I'm basing this on the javadoc of Configuration for 
findModule(String name) and resolveRequires(ModuleFinder before, 
ModuleFinder after, Collection<String> roots).  In my opinion Z.B is the 
only Z module which module W should ever be able to wire to because if it 
requires Z directly it could only ever wire to Z.B.  But this may be 
over-restrictive. For example, what if W only requires Y? In that case it 
seems perfectly reasonable to allow W to wire to Y.D and Z.D. Is this 
problem made worse with multiple parent layers?

This approach of using #NonHierarchicalLayers is suggested as a tool to 
solve the problem of pinning modules that are dynamically updated or 
uninstalled in a dynamic module system like OSGi.  Another possible 
solution to that is to use a solution to #DiscardableModules, but that 
does require an ever growing chain of parent Layers to be created as 
modules are updated in the dynamic module system.

> 
> Currently, you control the classloaders, so you can load a hand 
> crafted class in the module (you just have to patch the class name 
> to have the right package, you can use the patching capabilities of 
> defineAnonymousClass for that, but you can also call defineClass on 
> the right classloader as again, you control the classloaders).
> Once you are able to execute arbitrary code in a module you can call
> addReads, addExports (and soon addOpens) on the j.l.r.Module.

I agree with you this could be used instead of a solution to 
#ReadabilityAddedByLayerCreator, but I think it is a bit messy when it 
doesn't have to be.  A solution to #ReadabilityAddedByLayerCreator should 
not be too controversial. I also think this is an orthogonal issue to the 
pinning stale modules issue. I don't think you are suggesting this 
approach to somehow reach into the Layer implementation to pluck out the 
stale modules ourselves. That is where the monkey-patching feels more like 
gorilla-patching to me.

> 
> regards,
> Rémi
> 

Tom




More information about the jpms-spec-experts mailing list