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