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

Stephen Felts stephen.felts at oracle.com
Fri Sep 15 12:32:25 UTC 2017


"opens" is a superset of "exports".


-----Original Message-----
From: Alexander Udalov [mailto:alexander.udalov at jetbrains.com] 
Sent: Friday, September 15, 2017 8:14 AM
To: jigsaw-dev <jigsaw-dev at openjdk.java.net>
Subject: "exports" directive does not open module's resources for dependent modules

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