Может ли один модуль Java экспортировать пакет, имя которого является подпакетом пакета из другого модуля?

Итак, я знаю, что в модулях Java 9 (Project Jigsaw) разделенные пакеты не допускаются. То есть следующие модули не могут одновременно экспортировать пакет с одинаковым именем и одновременно использоваться во время выполнения:

Модуль 1

module com.example.foo {
    exports com.example.foo;
}

Модуль 2

module com.example.foo {
    exports com.example.foo;
}

Не разрешено (или, по крайней мере, они не могут работать одновременно). Но что мне не понятно, так это то, как субпакеты входят в игру. Если один модуль экспортирует пакет com.example.foo, может другой пакет экспорта com.example.foo.bar? Например, я хочу сделать следующее:

Модуль 1

module com.example.foo {
    exports com.example.foo;
    exports com.example.foo.exceptions;
    exports com.example.foo.util;
}

Модуль 2

module com.example.foo.impl1 {
    requires com.example.foo;
    exports com.example.foo.impl1;
}

Модуль 3

module com.example.foo.impl2 {
    requires com.example.foo;
    exports com.example.foo.impl2;
}

Это разрешено? Смогут ли все три модуля использоваться вместе во время выполнения? Или тот факт, что модуль com.example.foo экспорт com.example.foo исключить другой модуль (com.example.foo.impl1) от экспорта пакета с именем подпакета (com.example.foo.impl1)?

1 ответ

По предложению @RoddyoftheFrozenPeas я создал мультимодульный пример проекта, чтобы продемонстрировать здесь поведение. TL; Dr в том, что это работает! Вы действительно можете сделать это. Чтобы доказать, что я также правильно использовал модули, я попробовал первое, что, как я знал, не сработало, и у меня действительно были ошибки, которые мешали его запуску.

Я создал этот GitHub Gist, где вы можете увидеть полный исходный код (я никогда не буду его удалять), который показывает, как я настроил проект. Символы подчеркивания в именах файлов gist указывают на каталоги (вы не можете использовать косую черту). Проект оформлен следующим образом:

- root
  - com-example-foo
    - src
      - module-info.java
      - com
        - example
          - foo
            - SalutationProvider.java
  - com-example-foo-impl1
    - src
      - module-info.java
      - com
        - example
          - foo
            - implone
              - StandardOutHelloer.java
  - com-example-foo-impl2
    - src
      - module-info.java
      - com
        - example
          - foo
            - impltwo
              - StandardErrHelloer.java

Он хорошо компилируется, и вот результат его запуска:

$ java -Dfile.encoding=UTF-8 -p out/production/com-example-foo-impl1:out/production/com-example-foo -m com.example.foo.implone/com.example.foo.implone.StandardOutHelloer
Hello, World!

$ echo $?
0

$ java -Dfile.encoding=UTF-8 -p out/production/com-example-foo-impl2:out/production/com-example-foo -m com.example.foo.impltwo/com.example.foo.impltwo.StandardErrHelloer
Hello, World!

$ echo $?
15

Я полагаю, что это должен быть ответ на связанный дублирующий вопрос, потому что существующий ответ просто говорит, что "нет такого понятия, как подпакеты", без предоставления каких-либо рабочих примеров или документации, в которой говорится, что это явно разрешено. Однако, поскольку связанный дублирующий вопрос сам по себе помечен как дубликат несвязанного вопроса о подпакетах, я не могу опубликовать этот ответ там (это закрытый вопрос). Поэтому я выкладываю это здесь.

Другие вопросы по тегам