"Required filename-based automodules detected." 警告是什么意思?

What does "Required filename-based automodules detected." warning mean?

在我的多模块项目中,我只为几个模块创建了 module-info.java。在使用 maven-compiler-plugin:3.7.0 编译期间,我收到下一个警告:

[WARNING] * Required filename-based automodules detected. Please don't publish this project to a public artifact repository! *

这是什么意思?那是因为我只有几个模块 module-info.java 而不是整个项目吗?

[WARNING] * Required filename-based automodules detected. Please don't publish this project to a public artifact repository! *

是不是因为我只有几个模块带有 module-info.java 而不是整个项目?

不,不是因为 module-info.java 上列出的几个模块,而是 maven-compiler-plugin 为找到的所有 automatic modules 生成的在模块图中。


什么意思?

坚持不发布当前项目可能是因为自动模块预计将由其所有者转换为命名或显式模块,然后发布到存储库,这也可能导致更改其模块名称。另外需要注意的一点是,根据Maven的进度文档~> Java+9+-+Jigsaw,他们还没有完全准备好JDK9兼容的插件版本。


只是为了描绘这样一个用例的例子。考虑一下这些行 -

  • 我发布了一个神器 com-foo-bar:1.0.0-SNAPSHOT:jar
  • 我的另一个项目com-xyz:1.0.0依赖它。
  • 最终你的一个项目依赖于 com-foo-bar 通过 com-xyz
  • 传递
  • 您计划模块化您的代码并使用类似

    的东西
    module your.module {
        requires com.foo.bar;
        requires com.xyz;
    }
    

    (需要在模块声明中单独

  • 一切正常,但直到我决定模块化我的库。
  • 现在,我做的第一件事是命名我的模块
  • 我做了一些很棒的事情来明确地表达我的努力:-

    module modular.com.foo.bar {}
    
  • 我最终打破了任何依赖库的代码,最终以模块化的方式破坏了任何依赖于你的库的代码。

注意:我同意不在生产中练习使用 SNAPSHOT,但在某些情况下最终你会依赖一个工件仍处于开发阶段。


编辑:来自@khmarbaise

的评论

Its understood that people would wish to publish to artifactories but if they are not aware of the consequences you will be beaten in the future by this.

Maven would like to make it clear that the WARNING in this case is very serious which could have instead been a FAILURE but that would had been a bad user experience to deal with.

处​​理这个问题的理想方法是库所有者计划将他们的工件迁移到 JDK9 并且树是自下而上遍历的,在这种情况下 named/explicit 模块将是唯一没有需要自动模块名称和此类警告。

自动模块回顾

一个显式模块(即带有 module-info.java 的模块)只能访问它需要的模块代码(暂时忽略 implied readability)。如果所有依赖项都模块化了,那就太好了,但如果不是呢?如何引用非模块化的 JAR?

Automatic modules 是答案:任何在模块路径上结束的 JAR 都会变成一个模块。如果 JAR 不包含模块声明,模块系统会创建一个具有以下属性的自动模块:

  • 推断名称(这是这里的重要部分)
  • 读取所有其他模块
  • 导出所有包

Maven 依赖于该机制,一旦您创建 module-info.jar 它会将所有依赖项放在模块路径上。

自动命名

有两种方法可以推断出自动模块的名称:

  • 清单中的条目
  • 根据JAR文件名猜测

在第一种情况下,名称是维护者故意选择的,因此可以假定它是稳定的(例如,当项目模块化时它不会改变)。第二个显然在整个生态系统中不稳定 - 并非所有项目设置都会导致其依赖项的文件名完全相同。

What does it mean?

出现警告的原因是您的一些依赖项是自动模块不要在清单中定义它们未来的模块名称。相反,它们的名称来源于文件名,这使得它们不稳定。

稳定名称

那么为什么不稳定的名称会成为这样的问题呢?假设您的库以 requires guava 发布,而我的框架以 requires com.google.guava 发布。现在有人将你的库与我的框架一起使用,突然他们在模块路径上需要模块 guavacom.google.guava 。这个问题没有无痛的解决方案,所以需要预防!

怎么样?例如,通过阻止开发人员发布依赖于基于文件名的自动模块的工件。

带有 maven-compiler-plugin v3.7.0 的是信息性消息。不确定为什么将其视为警告...

这是我使用 module-info.java 构建基于 Java 10 的项目时得到的结果:

[INFO] Required filename-based automodules detected. Please don't publish this project to a public artifact repository!