A few questions on layers ... and a compile problem with split-package caused by automatic module
Martin Lehmann
martin.lehmann at gmx.de
Mon Sep 5 17:26:53 UTC 2016
Hi all,
I have a few questions regarding layers, especially to "split package
compile problem caused by automatic module". I tried out my examples with
build b132. Any help is much appreciated! Thanks in advance, Martin!
In some examples, I am creating a hierarchy of layers as follows:
boot (with 1 module mod.main)
--isparentof -- "top" layer (with 1 module mod.x_top)
--isparentof -- "middle" layer (with 1 module mod.x_middle)
--isparentof -- "bottom" layer (with 1 module mod.x_bottom)
Question 1) Is there any way to give a layer a name or an ID? My current
workaround is to put my layers to a map which do the name <-> layer-instance
mapping which is not nice. Please consider to allow layer names, thanks.
Question 2) The creation of the layer in my code looks more or less as
follows. A starter class in module mod.main (in the boot layer) creates all
the other layers. Via naming convention of module names (suffix of module
must match the layer name), all relevant modules are found (from a single
module path) and added/resolved with Configuration.resolveRequires()
void createJigsawLayersAndAddModules() {
Layer parentLayer = Layer.boot();
Path modPath = Paths.get("./mlib").toAbsolutePath().normalize();
ModuleFinder finder = ModuleFinder.of(modPath);
Set<ModuleReference> allModules = finder.findAll();
for (String layerName: new String[] {"top", "middle", "bottom"}) {
Set<String> allFilteredModuleNames = new HashSet<>();
allModules.stream()
.map(modRef -> modRef.descriptor().name())
.filter(modName -> modName.contains("_"+layerName)) // naming
convention
.forEach(modName -> allFilteredModuleNames.add(modName));
// ***
Configuration cf = parentLayer.configuration()
.resolveRequires(ModuleFinder.of(), finder,
allFilteredModuleNames);
Layer layer = parentLayer
.defineModulesWithOneLoader(cf,
ClassLoader.getSystemClassLoader());
parentLayer = layer;
}
}
What's the visibility of modules (i.e. their classes) along the layer
hierarchy / relationships? I had expected that a module (i.e. its classes)
can only see modules (i.e. classes) in the same layer or in its parent or in
any of its parent layers.
I have tried this with a class hierarchy where a class in "bottom" is
derived from a super class in "middle" which is again derived from a super
class in "top". For that readability is needed from bottom -> middle -> top.
Works as expected.
On the other hand, my starter module mod.main is in the topmost boot layer.
Via reflection, it can see and call anything from there in any module (i.e.
also classes in "lower layers", i.e. in top, middle and bottom).
If readability and accessibility are given either statically in module-infos
or dynamically at runtime, then are there any constraints of what can be
seen / called?
Question 3)
Is there any way to add / delete modules from a given configuration? For
now I used the 2 code lines above (***) to use the parent layer's
configuration when creating a new configuration for a new layer.
I have not found any API to add / delete modules "on the fly". Did I miss
something?
Question 4)
With using (***) I cannot "instantiate" a module twice along the layer
hierarchy (which makes sense). So a module in a parent layer is already
resolved and not added to the new layer again. Correct?
Would it be possible to add the same module to two sibling layers (i.e. the
children of the same parent layer)? Or to cousins or ... ;-)
Is it needed to use the parentLayer's configuration? Or is there any way to
create new configuration just for the new layer without "looking up the
chain"?
Question 5)
I tried out if the split package problem does not occur, when the mod.x*
modules have/export the same package, but are put to different layers. Works
fine indeed, no split package problem occurs. Also, from my mod.main module,
I can call all of them via reflection.
Normally I am compiling mod.main, mod.x_top, mod.x_middle, mod.x_bottom at
the same time with this bash script one-liner:
$JAVA_HOME/bin/javac -d mods --module-path mlib -modulesourcepath src
$(find src -name "*.java")
The split package problem in mod.x* does not cause compile problems, because
no other module has a read relationship to them at compile time. Instead,
the mod.x* modules with the split package problem are only read/required and
called via reflection from mod.main. So far so good.
Now I wanted to extend my mod.main module to parse a layer "topology" from a
JSON file instead of hard-coding the top/middle/bottom hierarchy. I hence
added javax.json-1.0.4.jar to amlib, added "requires javax.json;" to
mod.main's module-info. Only by doing that I am running into these
unexpected compile errors (checked with b127 and b132):
error: module reads package pkgx from both mod.x_top and mod.x_middle
error: module reads package pkgx from both mod.x_top and mod.x_bottom
error: module javax.json reads package pkgx from both mod.x_top and
mod.x_middle
error: module javax.json reads package pkgx from both mod.x_top and
mod.x_bottom
4 errors
I assume that having added the automatic module javax.json , I now
implicitely added a read-relationship to *all* other modules at compile
time, i.e. also to mod.x* modules. With that, the split package problem now
prevents compile success. Let me emphasize that I have no reads static
relationship to the mod.x* modules *anywhere* (not in code, not via compiler
command-line options).
It seems pretty (too?) restrictive to me, that simply adding a third-part
lib (i.e. an already compiled automatic module) now prevents the compilation
of (totally unrelated) code. Is that a known and wanted behaviour?
Even then you should consider of correcting the compiler error messages: The
first two of them do not include the cause's module name. For whatever
reason only the latter two do show the correct problem cause "module
javax.json".
And yes, by compiling the mod.x* modules separately from the rest, I can get
around the compile problem. Still, this looks bit awkward to me...
More information about the jigsaw-dev
mailing list