“检测到必需的基于文件名的自动模块。”警告意味着什么?

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

[警告] *检测到必需的基于文件名的自动模块。 请不要将此项目发布到公共工件库! *

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

自动模块回顾

显式模块(即具有module-info.java的模块)只能访问它所需的模块代码(暂时忽略隐含的可读性 )。 如果所有依赖项都是模块化的,那就太好了,但如果它们不是,那该怎么办呢? 如何引用非模块化的JAR?

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

  • 推断名称(这是重要的一点)
  • 读取所有其他模块
  • 导出所有包裹

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

自动名称

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

  • 进入清单
  • 从JAR文件名猜测

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

这是什么意思?

警告的原因是您的某些依赖项是自动模块, 并且未在清单中定义其未来的模块名称。 相反,它们的名称来自文件名,这使它们不稳定

名字稳定

那么为什么不稳定的名字会出现问题呢? 假设您的库已发布, requires guava ,我的框架将发布, requires com.google.guava 。 现在有人在我的框架中使用你的库,突然他们需要在模块路径上使用模块guavacom.google.guava 。 这个问题没有轻松的解决方案,因此需要加以防范!

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

[警告] *检测到必需的基于文件名的自动模块。 请不要将此项目发布到公共工件库! *

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

不,这不是因为module-info.java上列出的一些模块,而是由模块图中找到的所有自动模块maven-compiler-plugin生成的。


这是什么意思?

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


只是为这样一个用例描绘一个例子。 想想这些线 –

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

     module your.module { requires com.foo.bar; requires com.xyz; } 

    (您需要分别在模块声明中指定传递依赖项 )

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

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

注意 :我同意不练习在生产中使用SNAPSHOT,但最终你可能会依赖仍处于开发阶段的工件。


编辑 :来自@khmarbaise的评论

据了解,人们希望发布工具,但如果他们不知道后果,你将在未来被殴打。

Maven想清楚地说明在这种情况下警告是非常严重的,而这可能是一个失败,但这将是一个糟糕的用户体验来处理。

解决这个问题的理想方法是库所有者计划将他们的工件迁移到JDK9,并且自下而上遍历树,在这种情况下,命名/显式模块将是唯一的方面,而不需要自动模块名称和这样的警告。

使用maven-compiler-plugin v3.7.0它是一条信息性消息。 不确定为什么你认为这是一个警告……

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

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