Java 9 迁移问题 - package com.mymodule 在未命名模块中声明,模块 'newmodule' 不读取它

我创建了一个具有以下结构的多模块项目

    myproject
      |- mymodule
         |- src
            |- main
               |- java
                  |- com
                     |- mymodule
                        |- Util.java

      |-newmodule
         |-src
           |-main
             |-java
               |-com
                 |-newmodule
                    |- Main.java
             |-module-info.java

现在我想使用Util.java这是模块化模块newmodule中的非模块化代码。我已经在newmodule中声明了以下

module newmodule {
    requires mymodule;
}

项目编译正常,但Intellij显示模块未找到,并且包com.mymodule在未命名模块中声明,模块“newmodule”不读取它。

如何解决此问题?

还有一个问题,如果我甚至没有模块化的旧式遗留模块,那么所有旧的非模块化代码在java 9中是否默认变成自动模块?


答案 1

解决此问题的一个明确方法是将 也作为显式模块。我会说,这将是模块的理想世界。mymodule

你可以通过包括一个in来做到这一点,比如 -module-info.javamymodule

module mymodule {
    exports com.mymodule;
}

如果我甚至没有模块化的旧遗留模块,那么所有旧的非模块化代码在java 9中都会默认变成自动模块吗?

未命名模块自动模块的概念都是为了帮助迁移并提供与现有类路径技术的兼容性。

一方面,模块的依赖关系本身仍然不是模块化的,您仍然依赖于它们是一体的,可以在模块系统的模块路径上使用它们来隐式定义它们,当被视为自动模块时,并桥接JPMS期望的自下而上的迁移。

另一方面,未命名模块依赖于未在任何模块中定义的类型,并且已解析为仍可在类路径上找到。这确保了解析的每个类型都是某个模块的一部分(如果没有,那么未命名的模块),并且还提供了兼容性,使得依赖于类路径的现有应用程序的代码也可以在模块系统上以类似的方式编译和运行。


为什么你无法在代码中声明显式依赖关系的原因在文档中清楚地说明了:

未命名的模块将导出其所有包。这样可以灵活地迁移,如下所述。但是,这并不意味着命名模块中的代码可以访问未命名模块中的类型。实际上,命名模块甚至不能声明对未命名模块的依赖关系。此限制是有意为之,因为允许命名模块依赖于类路径的任意内容将使可靠的配置变得不可能。


答案 2

推荐