Module API usage questions

Alan Bateman Alan.Bateman at oracle.com
Tue Jul 19 20:00:27 UTC 2016


On 19/07/2016 19:38, Paul Benedict wrote:

> I have a few questions regarding how to use the module API. Thanks for
> reading.
>
> 1) Is Configuration.empty() meant to be an immutable singleton or a mutable
> empty configuration? Is it supposed to be analogous to
> Collections::emptyList/Map where it's a stand-in? I am asking based on the
> javadoc alone.
Configurations are immutable. The primary use of empty() is to serve as 
the parent for the Configuration of the boot layer.

>
> 2) Must all modules that could ever be loaded be specified on the module
> path? I was hoping to find a hook where I could provide by own
> implementation of ModuleFinder that has all that knowledge self-contained.
> I think the answer may be Configuration::resolveRequires, but please
> confirm.
Yes, you probably want something like this:

Configuration parent = Layer.boot().configuration();
Configuration cf = parent.resolveRequires(ModuleFinder.of(), myfinder, 
Set.of("myroot"));

To resolve "myroot" and its transitive dependences to create a new 
configuration. The two finders that you are specify are the before and 
after finders. The details is in the javadoc. In this example then the 
before finder is empty (doesn't find any modules) so it will attempt to 
locate the modules in the parent configuration. If not found there then 
they will be located with "myfinder". Whether you use a before or after 
ModuleFinder will depend on whether you need to overriding modules in 
the parent configuration or not.

>
> 3) What is the difference between adding a concealed package and not adding
> the package at all? If no difference, I don't know why you would ever call
> ModuleDescriptor.Builder.conceals()
Concealed packages are packages that are not exported. If you don't add 
them then they will not be package of your module.

When creating a Configuration (like in the above) then they are 
important to know when doing post resolution checks. It's an error, an 
example, for your module M to have a package `p` and for it to read 
another module that exports package p to M.

It's also important at runtime that the VM knows all the packages in the 
module. Continuing the example, then suppose that class p.Foo is loaded. 
The VM knows that this is in module M because you told it in advance 
when defining the module to the VM. There is nothing in the the Foo 
class file to help.

>
> 4) The aforementioned method (and all the others mostly) throws ISE if the
> package is already concealed or exported and you try to change it. But does
> the API really need a once-and-done requirement? You couldn't pass the
> builder instance across a chain of decorators, for example, and have them
> tweak each according to their own rules.
There are a few warts in the Builder API that will be resolved soon. The 
original intention was to detect mis-uses as early as possible and not 
delay to the build() method. A package cannot be both concealed and 
exported at the same time for example. So assumed this will be cleaned up.

>
> 5) One of the criticisms (made to me) of scanning all packages for
> annotations (such as a theoretical @Exported on a package) was that it
> would take too much time. Okay.... However, the ModuleDescriptor is going
> to have an collection of all packages regardless because it provides
> packages() method. So is the data lazy or pre-initialized?
We use the ConcealedPackages class file attribute [1] as an optimization 
to avoid scanning. Also for the modules in the run-time image then we do 
a lot at link-time to minimize the cost of reconstituting the module 
descriptors at run-time.

>
> 6) If Layers cannot be torn-down and recreated, what is the recourse to
> modules that come and go dynamically? If you say "it is not supported",
> then I don't see how one could adapt Configuration/Layer to applications
> where it's acceptable to drop in new artifacts and have them spin-up. The
> artifacts I have in mind are EE artifacts. It just sounds like nothing will
> change in the EE world then because it's impossible to use these new
> features there.
Layers (think leaf layers) are intended to be discarded and 
re-instantiated (probably from a new configuration).

-Alan

[1] http://cr.openjdk.java.net/~mr/jigsaw/spec/lang-vm.html#jigsaw-2.3


More information about the jigsaw-dev mailing list