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

20

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

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

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

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


我已经在newmodule中声明了以下内容。
module newmodule {
    requires mymodule;
}

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

如何解决这个问题?

还有一个问题是,如果我没有将旧的非模块化代码模块化,所有旧的非模块化代码是否默认转换为Java 9中的自动模块?


1
不知道这些是不是Maven子模块?它们都是用IntelliJ编译的吗?我问这个问题的原因是,解决这个问题的一个明确方法是将“mymodule”作为一个显式模块,并在其中包含“module-info.java”(同时导出该包)。 - Naman
1
嗨,实际上我不想将名为“mymodule”的模块模块化,因为这是遗留代码。但我想在已经模块化的newmodule中使用mymodule中的Util.java。是的,这是一个Maven项目,并且我还在它的pom.xml中声明了自动模块名称来指定mymodule。抱歉我之前忘记提到这些了。 - learner
3
注意:根据您使用的JDK版本,'javac'错误可能会错误地将包名用作模块名,例如,“包_mypackage_在未命名模块中声明,但模块_mypackage_未读取它”,请参见[JDK-8233524](https://bugs.openjdk.java.net/browse/JDK-8233524)。 - Marcono1234
1个回答

15

解决这个问题的一种明显方法是将mymodule作为一个显式模块来创建。我认为这只是模块化的理想世界。

你可以通过在mymodule中包含一个module-info.java文件来实现,例如:

module mymodule {
    exports com.mymodule;
}

如果我没有将旧的非模块化代码模块化,那么所有旧的非模块化代码是否默认转换为Java 9中的自动模块?
未命名模块和自动模块的概念是为了帮助迁移并提供与现有类路径技术的兼容性。
一方面,您仍依赖于不是模块化的依赖项,并且您仍然希望它们成为模块化的依赖项,可以在模块路径上使用它们作为自动模块,由模块系统隐式定义,从而实现JPMS所期望的自下而上的迁移。
另一方面,未命名模块依赖于未在任何模块中定义的类型,并解析为仍在类路径中找到。这确保了每个已解析的类型都是某个模块的一部分(如果没有,则是未命名模块),并提供了兼容性,使依赖于类路径的现有应用程序的代码在模块系统上编译和运行类似。
你在代码中未能声明显式依赖的原因在文档中已经明确说明:
无名模块导出其所有包,这使得迁移更加灵活,如下所述。但这并不意味着命名模块中的代码可以访问无名模块中的类型。实际上,甚至无法声明对无名模块的依赖。这种限制是有意的,因为允许命名模块依赖类路径上的任意内容将使可靠的配置变得不可能。

1
@user10237300 我所知道的最简单的方法是将现有代码打包成jar文件,并将其作为依赖项引入到您的模块化代码中。有关“JPMS如何知道”...的详细说明,请参阅答案中分享的链接。有关确保使用正确的自动模块名称使用该工件的相关信息,请参考我的这个答案 - Naman
1
好的,基本上如果我在pom.xml(mymodule)中提到了自动模块名称,并在新模块的pom.xml中提到了maven依赖项,而这个新模块实际上是模块化的,那么mymodule应该作为自动模块导入new_module。我的想法正确吗?非常感谢你的帮助。因为我之前在项目中做了同样的事情,通过cmd编译得很好,但是通过intellij却出现了错误。 - learner
1
所以基本上,如果我在创建JAR文件时提到了清单条目,那么来自未命名模块的所有旧遗留代码都将转换为自动模块...但仅当该JAR文件可用于依赖它的应用程序的模块路径时。 - Naman
1
在已经进行模块化的 new_module 的 pom.xml 中提及 mymodule 的 Maven 依赖,然后 mymodule 就会被自动作为模块导入到 new_module 中。我的理解正确吗?除非您显式地将 mymodule 定义为一个模块应用,否则这是不正确的。 - Naman
1
是的,我的疑惑现在已经清楚了。非常感谢。但是我遇到了一些不同的问题,将会开启一个新的线程。 - learner
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接