"exports" directive does not open module's resources for dependent modules

Alexander Udalov alexander.udalov at jetbrains.com
Fri Sep 15 12:14:21 UTC 2017


It looks like exporting a package from a (non-open) module with an
"exports" directive is not enough to ensure that
Module.getResourceAsStream on that module would load resources from
the module. Surprisingly, adding an "opens" directive for the same
package to the module declaration allows resources to be found.

I've put up a simple project to demonstrate this issue:
https://github.com/udalov/jigsaw-resources-are-not-exported

I'm wondering whether this is a bug or expected behavior? I would
expect that exporting a package would also open it not only for uses
of reflection, but for resource loading. I can't find anything related
to resources in the JLS, but p.7.7 "Module Declarations" gives a clear
impression that the "exports" directive gives a superset of
functionality of the "opens" directive in this regard.

Looking at the implementation of Module.getResourceAsStream, I see
that it calls Module.isOpen(String, Module) which returns false in
case the package name is exported by an "exports" directive. Which
raises another question: is Module.isOpen supposed to return whether
the package has been explicitly opened by an "opens" directive (or via
being in an open module)? Or is it supposed to also return true if the
package has been opened as a consequence of the fact that it's
exported (e.g. by an "exports" directive)? If the former is true, I
suppose there may be other usages of Module.isOpen, including in the
JDK, which (incorrectly) do not also check if the package name is
exported with Module.isExported.

The real-world case where I met this issue is in kotlin.stdlib where
we store metadata of Kotlin declarations in resource files per package
(only of those declarations which are not representable by JVM class
files), and kotlin.reflect (which is another module) reaches out to
those resource files in kotlin.stdlib. To make them reachable thus
along with every "exports XXX" in kotlin.stdlib's module declaration
I'm adding "opens XXX to kotlin.reflect", which looks cumbersome.

Thanks!

Alexander


More information about the jigsaw-dev mailing list