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

Cof*_*Pro 93 java java-platform-module-system java-11

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

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

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

Mar*_*old 159

不。

无需切换到模块。

从来没有必要切换到模块。

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

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

如果您维护一个没有太大变化的大型遗留项目,那么它可能不值得付出努力。

如果您从事多年来难以维护的大型项目,那么模块化带来的清晰度和纪律性可能会有所帮助,但它也可能需要大量工作,因此在开始之前请仔细考虑。

如果您要开始一个新项目,那么我强烈建议您尽可能从模块开始。到目前为止,许多流行的库都已升级为 modules,因此很有可能您需要的所有依赖项都已经以模块化形式提供。

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

所有这些并不是说您在通过 Java 8 时不会遇到一些绊脚石。然而,您遇到的那些可能与模块本身无关。我们听说过,因为我们的Java 9在2017年发布的最常见的迁移问题有做更改版本字符串的语法和对去除或内部API的封装例如sun.misc.Base64Decoder),针对公众,支持更换有可用多年。


Eug*_*ene 33

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

另一方面,客户端库是一个完全不同的故事。我不能告诉你我们有时遇到的混乱。我将解释我以前讨厌的一点jigsaw。您向客户端公开一个接口,供每个人使用。自动地interface就是public- 暴露于世界。通常,我所做的是有一些package-private类,这些类不暴露给客户端,使用该接口。我不希望客户使用它,它是内部的。听起来不错?错误的。

第一个问题是,当这些package-private类增长时,您需要更多类,隐藏所有内容的唯一方法是在同一个包中创建类:

  package abc:
        -- /* non-public */ Usage.java
        -- /* non-public */ HelperUsage.java
        -- /* non-public */ FactoryUsage.java
        ....
Run Code Online (Sandbox Code Playgroud)

当它增长时(在我们的例子中是这样),这些包太大了。你说搬到一个单独的包?当然,而是那时,HelperUsage并且FactoryUsage将是public我们尽量避免从一开始。

问题二:我们客户端的任何用户/调用者都可以创建相同的包名并扩展那些隐藏的类。它已经发生在我们身上几次了,有趣的时光。

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

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

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

总的来说,自从我们迁移到模块(现在仍然这样做),我们的代码变得更加清晰。如果您的公司是“代码优先”的公司,这很重要。另一方面,我参与过的公司被高级架构师视为“太贵”,“没有真正的好处”。

  • 感谢各位的煽动!所以我得到的是,模块化带来了我们在以前的版本中所缺少的急需的访问限制。我绝对可以看出这对图书馆有什么用处。如果服务通过 REST/AMQP/等进行通信。这又不是什么大问题,或者更确切地说,没有任何好处?也许我们不能武断地说*所有* java 9+ 代码都应该是模块化的?那么我们应该将其视为“工具”本身吗?不过还是很有趣。 (4认同)
  • “第二个问题:我们客户的任何用户/调用者都可以创建*相同的包*名称并扩展这些隐藏类。” 早在 Java 9 之前,就可以[密封](https://docs.oracle.com/javase/tutorial/deployment/jar/sealman.html) 包来防止这种情况发生。(我碰巧认为模块是一个很好的主意,我在所有项目中都使用它们。我只是想指出这个特定的用例不需要它们。) (3认同)