Implied readability + layers
Alex Buckley
alex.buckley at oracle.com
Thu Nov 5 18:44:36 UTC 2015
On 11/5/2015 1:30 AM, Ali Ebrahimi wrote:
> Hi alan,
> So far quite disappointing!
>
> But I think Alex's last response on this topic says opposite of this:
>
> "We'll have to think about the implication of com.baz in layer1 sometimes
> offering a 'requires public' on com.bar in layer1, and sometimes offering a
> 'requires public' on com.bar in layer2, depending on who is reading com.baz
> in layer1."
Alan and I have discussed this. It's not possible for com.baz in layer1
to "switch" which com.bar it depends on. There are two reasons.
First, in some loader of layer1, code in com.baz refers to a type
exported by com.bar at 1, and thus triggers class loading of that type from
whichever class loader in layer1 is responsible for loading com.bar at 1.
The loader for com.baz will be marked by the JVM as an "initiating
loader" for the type -- see JVMS8 5.3.2 -- so any further execution of
code in com.baz that refers to the type will get the same class as
initially loaded (from com.bar at 1). There is no way around this.
Second, when code in com.foo calls code in com.baz, the callee has no
idea who the caller is. The bytecodes for method invocation don't pass
that information. Since code in com.baz doesn't know the caller is
com.foo in layer2, there is no possibility of com.baz "switching" to
invoke code in com.bar at 2 in layer2 rather than com.bar at 1 in layer1.
It would be possible to write code in com.baz that reflectively detects
its caller, then reflectively invokes code in either com.bar at 2 or
com.bar at 1, never referring to exported types of any com.bar module via
the constant pool. If you do this, good luck with all the mental
accounting -- it's not a sane technique to build into the module system.
Since layers can come and go, it makes sense for the module system to
isolate code in a parent layer (com.baz in layer1) from the comings and
goings of code in a child layer (com.bar in layer2).
> In this case adding 'requires public' on com.bar in layer2 does not mean
> we should pick com.bar at 2 for com,foo?
> This scenario would have many usages in future when world would filled with
> modules and developers would have to use newer versions of modules to fix
> bugs.
> What if com.foo compiled against com.bar at 2? adding redundant requires com.bar
> in com.foo does not help and my app will fail.
> So what is advantage of multiple layers?
Inconsistent separate compilation has caused problems at run time since
1995. I was very clear in "Project Jigsaw: Under The Hood" that mixing
multiple versions of a module must not be done casually.
What layers give to a managed runtime (e.g. an app server) is i) freedom
to map modules to loaders (not only 1:1 but also n:1 and n:m), and ii)
freedom to isolate different versions of modules from each other (see
slide 55 in
http://openjdk.java.net/projects/jigsaw/j1/jigsaw-under-the-hood-j1-2015.pdf).
Alex
More information about the jigsaw-dev
mailing list