Currently if you wish to override a layer entry with path "folder/data" defined in module m1 with an entry folder/data
defined in m2, then m2 needs to have a dependency on m1 to ensure that it is loaded "after" m1. (In project.xml, this
would be a <run-dependency> with no <build-prerequisite> or <compile-dependency>.) We do this in a number of places in
nb.org modules, and even have
to verify that we get it right. But it is pretty painful, and most developers have no idea they need to do this:
Furthermore, it introduces an artificial dependency between modules, when in fact m2 might run perfectly well without m1
We should have some other system of ensuring that one layer entry overrides another. The simplest thing I can think of
is to define a special numeric-valued file attribute 'weight' (default 0), where "heavier" entries override "lighter"
entries. (For compatibility, in the case of conflicting entries with the same weight, the "later" layer wins, as now.)
This could be interpreted in MultiFileSystem with no reference to the module system. So for example
<file name="data" url="m1-contents"/>
<file name="data" url="m2-contents">
<attr name="weight" intvalue="100"/>
would suffice to ensure that Repo.gD().gDFS().fR("folder/data").getInputStream() would produce m2-contents rather than
m1-contents, regardless of module load order.
'priority' could also be used instead of 'weight' but I fear this might be mistaken for 'position', which is quite
ValidateLayerConsistencyTest could then be changed to just check that if multiple modules define the same file, each
specifies a different weight. This would be easy to test and failures would be easy to fix (either by removing duplicate
registrations or assigning weights according to priority).
You could override findResource in ModuleLayeredFileSystem to make it affect just XML layers. This might be inefficient,
however (the default impl uses private infrastructure in MFS/MFO), and also would not work from unit tests that do not
load core.jar. Would probably be better to implement directly in MultiFileSystem.
One catch is that customizations, in $userdir/config/, should always override layer entries even if they specify a
weight. I suggest the code always pick the resource from layers (the writable layer) if it exists, regardless of
weight in other layers. This ensures that after setting the content on a MFO, the observed content is what you just set.
Could also use createWritableOn to find the priority FS more accurately, taking care to ignore IOException's which are
meaningless in this context.
Created attachment 65843 [details]
I attached a patch which might work. (Only unit tested, not tried on a real example.) A full patch would also need API
changes & documentation, change of VLCT, fixup of nb.org modules to use the new attribute, and perhaps a change to
o.n.m.apisupport.project.layers to generate the weight attribute on new layer overrides (to e.g. 100 more than any
Relates to apisupport.
Ok, I'll add weight generation once this feature is done.
Jirko, any possibility to get this into 6.8?
It is probably better if I take over the base (non-apisupport) patch. I can work on VLCT and use that as a way to find layers in nb.org that need to be changed.
Created attachment 94399 [details]
Includes filesystems changes to recognize the new 'weight' attr; API change documentation; rewritten VLCT test; and fixes to a few modules to make them pass the test (cluster.config=bloated) - to use weight in the few cases where overriding was actually intended, otherwise to not override.
Integrated into 'main-golden', will be available in build *201003020200* on http://bits.netbeans.org/dev/nightly/ (upload may still be in progress)
User: Jesse Glick <firstname.lastname@example.org>
Log: Issue #141925: provide a simpler way to declare which layer entries override others.
the dtd specified attr and not attributed as reported in the documentation page above:
<file name="common.xml" url="special-snippet.xml">
<attribute name="weight" intvalue="100"/>
Integrated into 'main-golden', will be available in build *201011030000* on http://bits.netbeans.org/dev/nightly/ (upload may still be in progress)
User: Jesse Glick <email@example.com>
Log: #141925 apichanges tweak: <attr> not <attribute>.