在我的多模块项目中,我仅为少数模块创建了module-info.java
。在使用maven-compiler-plugin:3.7.0
进行编译时,我会收到下一个警告:
[警告] *检测到必需的基于文件名的自动模块。请不要 将此项目发布到公共工件库! *
这是什么意思?那是因为我只有几个模块module-info.java
而不是整个项目吗?
答案 0 :(得分:10)
显式模块(即具有module-info.java
的模块)只能访问它所需的模块代码(暂时忽略implied readability)。如果所有依赖关系都是模块化的,那就太棒了,但如果不是这样的话呢?如何引用非模块化的JAR?
Automatic modules就是答案:任何以模块路径结束的JAR都会变成一个模块。如果JAR不包含模块声明,则模块系统会创建一个具有以下属性的自动模块:
Maven依赖于该机制,一旦创建了module-info.jar
,它就会将所有依赖项放在模块路径上。
有两种方法可以推断自动模块的名称:
在第一种情况下,名称是由维护者故意挑选的,因此可以假设它是稳定的(例如,当项目模块化时它不会改变)。第二个在整个生态系统中显然是不稳定的 - 并非所有项目设置都会导致其依赖项的文件名完全相同。
这是什么意思?
警告的原因是您的某些依赖项是自动模块并且未在清单中定义其未来的模块名称。相反,它们的名称来自文件名,这使它们不稳定
那为什么不稳定的名字会出现这样的问题呢?假设您的库已使用requires guava
发布,我的框架将使用requires com.google.guava
发布。现在有人在我的框架中使用你的库,突然他们需要在模块路径上使用模块 guava 和 com.google.guava 。这个问题没有轻松的解决方案,因此需要加以防范!
如何?例如,通过阻止开发人员发布依赖于基于文件名的自动模块的工件。
答案 1 :(得分:3)
[警告] *检测到必需的基于文件名的自动模块。请不要 将此项目发布到公共工件库! *
是因为我只有几个模块有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;
}
(您需要单独在模块声明中specify the transitive dependencies)
我做了一些很棒的事情,明确地说出我的努力: -
module modular.com.foo.bar {}
我最终打破了任何依赖库的代码,最终以模块化的方式依赖于你的代码。
注意 :我同意不练习在生产中使用SNAPSHOT,但最终你可能会依赖仍处于开发阶段的工件。< / p>
编辑 :来自@khmarbaise的评论
据了解,人们希望发布工件但是 如果他们不知道你会被击败的后果 未来就是这样。
Maven希望明确表示此情况下的警告非常明确 严重的可能反而是失败,但那将是一个 糟糕的用户体验。
处理这个问题的理想方法是库所有者计划将他们的工件迁移到JDK9,并且自下而上遍历树,在这种情况下,命名/显式模块将是唯一不需要自动化的方面。模块名称和此类警告。
答案 2 :(得分:0)
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!
答案 3 :(得分:0)
当我在我的module-info.java文件中从我的模块本身添加一个类时,我得到了警告,我必须这样做才能在netbeans中调试我的测试文件,但是显然这是错误的,因为它不是一个模块..
module net.my.package.xy
{
requires java.logging;
requires java.naming;
requires javax.jms.api;
//THAT GENERATES THE WARNING:
exports net.my.package.xy.MyClass;
}