一个Java模块可以从另一模块中导出名称为包子包的包吗?

时间:2019-01-25 18:30:20

标签: java java-9 java-module jigsaw java-package

所以我知道,在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 个答案:

答案 0 :(得分:2)

在@RoddyoftheFrozenPeas的建议下,我创建了一个多模块的示例项目来演示此处的行为。 tl; dr是它有效!您确实可以做到这一点。为了证明我还在正确使用模块,我尝试了我知道不起作用的第一件事,并且确实遇到了阻止它运行的错误。

我已经创建了this GitHub 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

我认为这应该是链接重复问题的答案,因为现有答案只是说“没有子包”,而没有提供任何明确允许这样做的工作示例或文档。但是,由于链接的重复问题本身被标记为与子包装无关的问题的重复,因此我无法在此处发布此答案(这是一个封闭的问题)。因此,我将其发布在这里。