Missing module discovery functionality in Jigsaw/JPMS API?

Luke Hutchison luke.hutch at gmail.com
Sun Dec 24 23:31:15 UTC 2017


I am the author of Fast Classpath Scanner
<https://github.com/lukehutch/fast-classpath-scanner/>. I am trying to
extend this library to work with JDK 9, and I'm running into a lot of
apparent shortcomings of the JPMS API.

These are the main issues I have come across so far:

(1) Automatic modules from the legacy classpath cannot be found using
ModuleFinder.ofSystem() (because they are not system modules), or using
ModuleLayer.boot().modules() (because this list does not include unnamed
modules).

(2) I would guess then that unnamed modules are in their own layer, but the
Layer API only allows you to look at parent layers, not child layers -- so
it is not even possible to enumerate all layers in the system. Why is there
no call for enumerating all layers, and/or for reading child layers?

(3) ModuleLayer.boot().configuration().findModule(name) cannot find unnamed
automatic modules either, because name cannot be null (and using the empty
string doesn't return unnamed layers).

(4) From within a class in a traditional (non-module) jar on the classpath,
using getClass().getModule(), does return a Module reference for the
unnamed module. However, there is no API that I can find for getting a
ModuleReference from a Module object, if the module is unnamed. For
example, the following should work if the module is named, but does not
work if the module is unnamed:

    Optional<ModuleReference> moduleReference =
        module
            .getLayer()
            .configuration()
            .findModule(module.getName())
            .map(ResolvedModule::reference);

(5) ModuleFinder.of(path) would find the module, if the path were known.
But there is no way to get the path from the Module reference obtained
using getClass().getModule() -- you need a ModuleReference object to get
the URI of the module, and you cannot get a ModuleReference, as described
in (4) above.

(6) Having to specify a path when calling ModuleFinder.of(), as shown in
(5), defeats the purpose of having a classpath and/or module path that is
specified outside of program code. I imagine it is primarily useful for
dynamic loading of modules, but what I'm interested in is the static
classpath / module path.

(7) Module has a method Set<String> getPackages(), which allows you to
enumerate package names within a module, but it does not have a method for
listing resource names within each package. For that, again you need a
ModuleReference, and then you can call ModuleReference#open() to get a
ModuleReader, then ModuleReader#list() to list the resources in the module.
Why is there no open() method in Module, and/or why is it not possible to
get a ModuleReference directly from a Module?

It seems like there are lots of obvious omissions in the API, from an
enumeration / scanning point of view. Or am I missing something?

Thanks,
Luke Hutchison


More information about the jigsaw-dev mailing list