1

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?

3
  • 2
    The Jakarta xml bind code uses this method in jakarta.xml.bind.ModuleUtil.delegateAddOpensToImplModule Commented Feb 14 at 8:18
  • @greg-449 Exactly what I was looking for; if you add it as an answer I'll accept it. Commented Feb 14 at 18:33
  • 2
    You don’t need an addOpens call at runtime when you already have an appropriate opens declaration in your module-info. But some things are not expressible in the opens declaration. For example, you may have to open to a non-modular library. You can’t open to the unnamed module in your declaration, but you can at runtime. Likewise, you may have to open to dynamically loaded code, modular or not, which is not present at module layer initialization. Commented Mar 20 at 11:04

2 Answers 2

2

The 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.

Sign up to request clarification or add additional context in comments.

Comments

0

Mostly:

  1. 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.

  2. 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.

3 Comments

Perhaps I was not clear. I'm aware of the command line option. I'm asking about the java.lang.Module#addOpens(String, Module) method, which builds on top of that, as near as I can tell (you have to use module-info's opens clause (or the command line option) to even get started here).
@LairdNelson I have edited the answer to include some additional notes on why that method exists.
“the OpenJDK has been breaking stuff left and right” —I would argue that newer JDKs have been exposing broken stuff in applications, which Sun/Oracle warned for many years was not safe to do.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.