#LayerPrimitives should be re-opened
David M. Lloyd
david.lloyd at redhat.com
Mon Feb 27 13:43:30 UTC 2017
I want to add an addendum to this. We don't consider this to be the
*best* solution, rather the very *minimum* to allow workarounds which
make up for a subset of what we still consider to be critical
deficiencies in the specification in the form of past rejected and
dismissed issues, which I will expound upon subsequently.
On 02/24/2017 09:16 AM, David M. Lloyd wrote:
> I am requesting that the #LayerPrimitives issue be re-opened.
> This issue requested the ability for Layer.Controller to perform the
> following operations, which Modules can already do for themselves (and,
> by extension, Layers can do as well using bytecode injection):
> • addExports(Module source, String packageName, Module target) -
> equivalent to Module#addExports(String packageName, Module target),
> "source" must be in the controller's corresponding layer
> • addUses(Module source, Class<?> service) - equivalent to
> Module#addUses(Class<?> service), "source" must be in the controller's
> corresponding layer
> These two methods should be added because requiring bytecode injection
> to perform these functions is unreasonably onerous, which alone should
> be enough to justify re-opening the issue.
> The following self-explanatory operations do not have corresponding
> methods on Module, and normally can only be done by editing the
> descriptor or using the Instrumentation#redefineModule(...) API to do so:
> • addOpensToAll(Module source, String packageName)
> • addExportsToAll(Module source, String packageName)
> It is not always possible for a container to know what packages need to
> be exported or opened to all when the module is built, especially in a
> dynamic deployment environment like ours. Note that
> Controller#addOpens(Module source, String packageName, Module target) is
> already an existent method on Controller thus is already deemed "safe".
> The following operations neither have corresponding methods on Module,
> nor can be done by editing the descriptor AFAIK:
> • addOpensToAllUnnamed(Module source, String packageName)
> • addExportsToAllUnnamed(Module source, String packageName)
> The latter is arguably not necessary since unnamed modules are usually
> not going to be bound by JPMS linkage, so from what I understand, the
> exports usually won't apply in this case anyway. It seems to me that
> the former method might be of use in some cases; having unnamed module
> code reflecting on module code does not seem very outlandish to me,
> especially in a container environment.
> This leaves addPackage(Module source, String packageName). This method
> is not available on Module and can only otherwise be done by editing the
> descriptor or using Instrumentation#redefineModule(...). However, if
> your loader does not yet know the complete set of packages (i.e. it's
> lazy), or the set of packages might be supplemented after the module is
> initially created, you either need this method, or you have to redesign
> your container's linkage strategy from the ground up. We definitely
> need this method. One OSGi implementer has indicated that they can live
> without it (by not implementing some optional pieces, and mandating
> strict behavior where other containers had flexibility previously) but
> I've also reached out to a few others to see if I can get more data
> about this. I know that JBoss OSGi does presently rely on this sort of
> functionality already; I am not sure if it is limited to fragment
> support or if there is more to it. I have a query out to the maintainer
> of that project (Arcadiy Ivanov) to get further information, but I
> understand he is traveling at the moment.
> However, the potential of the OSGi requirement is not a necessary
> condition for this method to be justified. We believe that it is also
> very useful when delivering a Java EE container; we have relied on this
> functionality for many years. There are not many Java EE certified
> vendors in the world, so I would consider this alone to be just as
> substantial a justification for the feature. Logically it is possible
> to deliver a Java EE container without it, just as it is possible to
> deliver an OSGi container without it, but this means the end of certain
> features which a massive number of users have relied upon.
> This excludes other possible uses, like: dynamic code discovery (via
> network for example), IDE code hot-deployment features which would
> require Instrumentation otherwise, etc.
> The patch itself (still viewable here ) is very small, mostly
> consisting of JavaDoc, and only utilizes existing functions in Jigsaw.
> It does not introduce any new implementation behavior, and is only
> available to Layer implementers, therefore I would consider the risk to
> be very small by any concrete or objective measure.
> These primitives also have the advantage of enabling an acceptable
> solution to the following issues (at minimum):
> • #NonHierarchicalLayers
> • #CyclicDependences (at least, within containers)
> • #MutableConfigurations
> And can be used to provide container-based solutions to several others
> as well. To me this looks like a very big reward for low risk.
> My patch also proposed a trivial one-line fix to remove a double null
> check from the existing Controller#addOpens(Module, String, Module)
> method. This may have been fixed upstream already, but because a storm
> has disabled my network connection, I cannot verify this easily at present.
> If the problem with the issue is the total set of methods, I'm OK with
> dividing the issue up and arguing the merits of each.
> I think this issue should be re-opened, and I think that doing so, with
> a view towards satisfactory resolution, is in the best interests of the
> community as well as the majority of the members of this expert group.
>  https://gist.github.com/dmlloyd/e3c114f0ac7595a93ecb63b1dbed5e00
More information about the jpms-spec-experts