[module-imports] Importing java.se?
Alex Buckley
alex.buckley at oracle.com
Wed Jul 17 00:06:09 UTC 2024
On 7/12/2024 5:27 AM, Tagir Valeev wrote:
> I'm playing with module imports and tried to import java.se module:
>
> import module java.se;
>
> class Test {
> void main() {
> ArrayList<String> list;
> }
> }
>
> Building (23-ea+31-2337) yields the following errors: ...
>
> I'm not sure I understand the first error "unnamed module does not
> read". Importing java.se is described in JEP 476 text [1], so I
> assume that it's something allowed. Is the current behavior intended?
> If yes, then the JEP text should probably not mention java.se as an
> allowed example to import.
As you say, the JEP uses java.se as the poster child for "aggregator"
modules that have no packages of their own and exist solely to arrange
access to packages in other modules.
Unfortunately, we overlooked how java.se is no longer (since JDK 11) in
the default set of root modules for the unnamed module. See
https://bugs.openjdk.org/browse/JDK-8205169. This means that an
implicitly declared class, being in the unnamed module, cannot refer to
java.se in `import module ...`.
(Bear in mind that `import module ...` is not another way of spelling
`requires ...`. Every import declaration -- whether of com.foo.Type, or
com.foo.*, or module com.foo -- operates in the environment set up by
the module system. If your program has a module declaration, then the
module system sets up the environment according to your `requires ...`
directives. If your program is in the unnamed module, then its
environment is the default set of root modules for the unnamed module.
You can augment the default set with --add-modules, but that's not for
beginners.)
I confess to being a little sad about the inability to `import module
java.se` in an implicitly declared class, because aggregator modules
like java.se are the de facto solution for module renaming/refactoring.
In the JEP, we should clarify the "It is sometimes useful ..." paragraph
by adding: "Note that `import module java.se` is only possible in a
compilation unit of a named module that already `requires java.se`. In a
compilation unit of the unnamed module, such as one that implicitly
declares a class, it is not possible to use `import module java.se`."
> The second error is caused by the fact that java.se
> does not declare explicitly that it transitively requires java.base.
This is technically true, but it's missing the forest for the trees. The
compilation unit that contains your implicitly declared class *already*
has `import module java.base` at the top, per JEP 477. (And java.base is
certainly in the default set of root modules for the unnamed module.) I
think the trouble with java.se has led javac to forget that java.base
(and hence ArrayList) is imported.
Alex
More information about the amber-spec-experts
mailing list