迁移到 Java 9 或更高版本时是否需要切换到模块?

Is there any need to switch to modules when migrating to Java 9 or later?

我们目前正在从 Java 8 迁移到 Java 11。但是,升级我们的服务没有我们预期的那么痛苦。我们基本上只需要更改 build.gradle 文件中的版本号,服务就可以正常运行 运行。我们升级了库以及使用这些库的(微)服务。到目前为止没有问题。

是否需要实际切换到模块?恕我直言,这会产生不必要的成本。任何建议或进一步阅读 material 表示赞赏。

澄清一下,如果在不引入模块的情况下使用 Java 9+ 代码,会有什么后果吗?例如。它会变得与其他代码不兼容吗?

我只能告诉你我组织对此事的看法。对于我们正在进行的每个项目,我们 正在转向模块。我们正在构建的基本上是微服务+一些客户端库。对于微服务,过渡到 modules 的优先级较低:那里的代码已经以某种方式隔离在 docker 容器中,因此在其中“添加”模块似乎(对我们而言)不是很重要.这项工作进展缓慢,但优先级较低。

另一方面,客户端库是一个完全不同的故事。我无法告诉你我们有时会遇到的混乱情况。我将解释我之前讨厌的一点 jigsaw。您向客户端公开一个接口,供所有人使用。自动 interfacepublic - 暴露给世界。通常,我所做的是有一些 package-private classes,它们不暴露给使用该接口的客户端。我不希望客户使用它,它是内部的。听起来不错?错了。

第一个问题是,当那些 package-private classes 增长时,你想要更多 classes,保持一切隐藏的唯一方法是创建 class在相同包中:

  package abc:
        -- /* non-public */ Usage.java
        -- /* non-public */ HelperUsage.java
        -- /* non-public */ FactoryUsage.java
        ....

当它增长时(在我们的例子中它会增长),这些包太大了。你说搬到一个单独的包裹?当然可以,但是 HelperUsageFactoryUsage 将是 public,我们从一开始就试图避免这种情况。

第二个问题:我们的任何 user/caller 客户都可以创建 相同的包 名称并扩展那些隐藏的 classes。我们已经发生过几次了,很有趣。

modules 以一种漂亮的方式解决了这个问题:public 不再是 public;我可以通过 exports to 指令获得 friend 访问权限。这使我们的代码生命周期和管理变得更加容易。我们摆脱了 class 路径地狱。当然 maven/gradle 主要是为我们处理,但是当 出现 问题时,痛苦会非常真实。可能还有很多其他例子。

也就是说,过渡(仍然)不容易。首先,团队中的每个人都需要保持一致;二是有障碍。我仍然看到的最大的两个是:你如何分离每个模块,具体基于什么?我还没有确定的答案。第二个是split-packages,哦美丽的“不同模块导出相同的class”。如果您的图书馆发生这种情况,有一些方法可以缓解;但如果这些是外部库...那么 不那么容易。

如果您依赖 jarAjarB(单独的模块),但它们都导出 abc.def.Util,您会大吃一惊。不过,有办法解决这个问题。有点痛苦,但可以解决。

总的来说,自从我们迁移到模块(现在仍然如此)后,我们的代码变得很多 更清晰。如果你的公司是“代码优先”的公司,这很重要。另一方面,我曾参与过被高级架构师认为“太昂贵”、“没有实际收益”的公司。

没有

不需要切换到模块。

从来不需要切换到模块。

Java 9 及更高版本支持传统的 JAR 文件 传统的 class 路径,通过未命名模块的概念,并将 可能会一直这样做,直到宇宙热寂为止。

是否开始使用模块完全取决于您。

如果您维护一个变化不大的大型遗留项目, 那么这可能不值得。

如果您从事的大型项目已经变得难以维护 那些年模块化带来的清晰度和纪律性 可能是有益的,但也可能需要很多工作,所以想想 开始前请仔细阅读。

如果您要开始一个新项目,那么我强烈建议您从 如果可以的话,模块。到目前为止,许多流行的图书馆已经 升级 是modules,所以有一个很好的 您需要的所有依赖项都有可能已经可用 以模块化形式。

如果您维护一个库,那么我强烈建议您 如果您还没有将它升级为一个模块,并且如果所有 您的库的依赖项已转换。

这一切并不是说你不会遇到一些绊脚石 当经过 Java 8 时。但是,您确实遇到的人会, 可能与模块 本身 无关。最普遍的 自发布 Java 9 以来我们听说过的迁移问题 2017 与 版本语法的更改有关 string 删除或 内部API封装 (例如, sun.misc.Base64Decoder) public, 支持 多年来一直提供替代品。