[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