I am familiar with the Java Platform Module System.
The javadoc for Module#addOpens
sketches out a use case that I cannot translate into the real world:
This method can be used for cases where a consumer module uses a qualified opens to open a package to an API module but where the reflective access to the members of classes in the consumer module is delegated to code in another module. Code in the API module can use this method to open the package in the consumer module to the other module.
I confess I am too stupid to make the leap from this description to the real world. I can see that this has to do with expanding deep reflective access in some fashion, but I'm not sure what that fashion is, particularly given the method description itself:
If this module [the "consumer module"? maybe?] has opened a package to at least the caller module [the "API module"? maybe?] then update this module to open the package to the given module [the "other module"? maybe?].
I have a vague and almost certainly wrong sense this is related to, say, my module (the "consumer module"?) opening a package to something like Servlet (the "API module"?), without knowing at runtime that the implementation of Servlet in play is actually (say) Tomcat, so, if my code wishes, it (I think?) may call this method and thus somehow allow Tomcat (the "other" module?) to do reflective things without knowing that it is, in fact, Tomcat (and not, say, Jetty) doing those reflective things, and without having to have an extra opens com.foo.bar to Tomcat
in module-info
as well as opens com.foo.bar to Servlet
.
(I'm also not sure where the "delegation" is supposed to be happening; Servlet can't "delegate" anything to Tomcat in this scenario.)
But given Lookup
call site sensitivity restrictions I am not sure how this is supposed to work, or where and when in my code in this scenario I am supposed to make this sort of call, or why, if I've already added an opens
statement, I must now also do something programmatic. I understand the motivating goal of integrity and that permission must be granted for reflective access and that this is supposed to somehow make things easier, but I can't get there concretely.
In short: is there actually a concrete use case for this feature? If so, what is it? How does it work?
I am familiar with the Java Platform Module System.
The javadoc for Module#addOpens
sketches out a use case that I cannot translate into the real world:
This method can be used for cases where a consumer module uses a qualified opens to open a package to an API module but where the reflective access to the members of classes in the consumer module is delegated to code in another module. Code in the API module can use this method to open the package in the consumer module to the other module.
I confess I am too stupid to make the leap from this description to the real world. I can see that this has to do with expanding deep reflective access in some fashion, but I'm not sure what that fashion is, particularly given the method description itself:
If this module [the "consumer module"? maybe?] has opened a package to at least the caller module [the "API module"? maybe?] then update this module to open the package to the given module [the "other module"? maybe?].
I have a vague and almost certainly wrong sense this is related to, say, my module (the "consumer module"?) opening a package to something like Servlet (the "API module"?), without knowing at runtime that the implementation of Servlet in play is actually (say) Tomcat, so, if my code wishes, it (I think?) may call this method and thus somehow allow Tomcat (the "other" module?) to do reflective things without knowing that it is, in fact, Tomcat (and not, say, Jetty) doing those reflective things, and without having to have an extra opens com.foo.bar to Tomcat
in module-info
as well as opens com.foo.bar to Servlet
.
(I'm also not sure where the "delegation" is supposed to be happening; Servlet can't "delegate" anything to Tomcat in this scenario.)
But given Lookup
call site sensitivity restrictions I am not sure how this is supposed to work, or where and when in my code in this scenario I am supposed to make this sort of call, or why, if I've already added an opens
statement, I must now also do something programmatic. I understand the motivating goal of integrity and that permission must be granted for reflective access and that this is supposed to somehow make things easier, but I can't get there concretely.
In short: is there actually a concrete use case for this feature? If so, what is it? How does it work?
Share Improve this question edited Feb 14 at 2:47 Laird Nelson asked Feb 14 at 2:39 Laird NelsonLaird Nelson 16.2k21 gold badges78 silver badges136 bronze badges 2 |2 Answers
Reset to default 2The Jakarta xml bind code uses this method in jakarta.xml.bind.ModuleUtil.delegateAddOpensToImplModule
Source code is here
In the JDK Javadoc code TagletManager
in jdk.javadoc.internal.doclets.formats.html.taglet
also uses this.
Mostly:
Patching
If you want to 'edit' a module 'in place' via patching (you call into its private methods or otherwise modify it at runtime, instead of forking it from source, editing that source, and releasing a modified fork), you can access the internals of the thing you are patching/extending by using
--add-opens
.Legacy
It's a term with negative overtones but that's not intended here: Lots of things are possible only with reflection and the OpenJDK has been breaking stuff left and right by making that no longer possible. Sometimes, an adequate replacement is available. But sometimes, there is not.
--add-opens
can restore functionality without requiring a library author to conjure a rabbit out of a hat.
Usually you do these things on the command line, but when an existing system is set up with the appropriate --add-opens
switches whenever it is started, and later on refactors their app a bit and the actual module that ends up hosting the code that needs the 'opens' rights is some sub module, then you can use the addOpens
method on Module
to 'extend the umbrella' of your module's additional opens rights to your submodule. This way, e.g. your bootup scripts or your cronjobs or whatnot (the place where the actual java --add-opens
command is written that starts your app) then does not need to be modified.
jakarta.xml.bind.ModuleUtil.delegateAddOpensToImplModule
– greg-449 Commented Feb 14 at 8:18