将 Java 8 项目迁移到 Java 11

Mfs*_*ggs 5 java java-8 java-11

我们有一个使用 Java 8 构建的存储库。存储库中有多个休息服务。我们想迁移到 Java 11 并试图找出最好的方法。我们正在考虑逐个模块进行。例如,将一项服务更改为 Java 11,而其余服务仍为 Java 8。我们不确定 Maven 是否支持这一点?

Dul*_*ren 5

免责声明:这不是答案,而只是我最近经历的部分报告。如果您觉得它不符合 SO 标准,请随意标记此答案。

Maven 支持吗?

是的,使用编译器插件 3.8.0/3.8.1

然而,这种迁移需要额外的小心。

最近,我们通过从 ORACLE JDK 8 迁移到 OPENJDK 11 做了类似的事情。由于我们有数百个具有不同任务的存储库,我们面临着各种各样的问题。仅引用我在电子邮件中收到的标记为 [jdk11_migration] 的一些内容:

  • 很明显,但我想强调的是,为了从 java 8 迁移到 11,我们还必须满足 java 9 和 10 的要求

  • 一些像 cobertura 这样的 Maven 插件不支持 Java 11,我猜他们永远不会支持它。在某些情况下,这些插件已经到了废弃的生命周期阶段。解决方案是以个案的方式寻找替代方案。例如,我们用 Jacoco 替换了 cobertura。

  • rt.jar 和 tools.jar 已被删除!您从他们那里明确引用的所有内容都可能会损坏。

  • 一些我们不应该在 java 9 或更少中使用的类现在在 java 11 中不再存在。我说的是访问 sun.*、sun.misc 等包中的类。解决方案是寻找一对一的替换或重构代码以避免使用。

  • 反射通常是最后一个要使用的项目,对于这些情况,在 Java 9 及更高版本中,我们会收到如下警告消息:

    WARNING: An illegal reflective access operation has occurred
    WARNING: Illegal reflective access by ...
    WARNING: Please consider reporting this to the maintainers of ...
    WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
    WARNING: All illegal access operations will be denied in a future release
    
    Run Code Online (Sandbox Code Playgroud)

尽管这不是一个完全的解决方案,但有一个标志可以消除此警告 --illegal-access=permit 。这在使用surefire Maven 插件时尤为重要。

  • Java 9 引入了模块系统,然后“现在”我们有包冲突的现象。例如,诸如“包 org.w3c.dom 可从多个模块访问:,java.xml”之类的消息。解决方法是找到冗余包含的来源(特别是重复的maven依赖或依赖的依赖)并删除它。

虽然这对我们来说不是问题,但我只是注意到您的存储库主要由 REST 组件组成。您可能会遇到 ClassNotFound 问题,例如 javax.xml.bind 等基本上已从 Java 标准版中删除的包。您可以通过将它们显式包含在 pom.xml 中来修复它。

幸运的是,您可能会在 SO 或 Internet 上为您在迁移中发现的每个问题找到好的问题和答案。有一些野外迁移指南是很好的起点。特定问题,如混淆和 IDE 集成,可能需要一点时间,但至少根据我的经验,这种迁移比我想象的要轻松。


xce*_*sco 3

我的建议是升级整个项目。尝试拥有一些 Java8 和一些 Java11 模块可能非常困难。正如你已经知道的,从Java9开始模块出现。答案很笼统,所以很难给出详细的答复。我想:

  • 你的项目是用maven管理的
  • 你有很多文物(罐子)
  • 你正在使用一些库或框架(谁说Spring?)
  • 您正在使用源版本控制(例如 Git 或 Subversion)
  • 您有一个多模块项目
  • 您编写的代码适用于 Java8 和 Java11 平台

我建议的计划:

  1. 在 SVC for Java11 项目版本上创建一个分支并开始处理它。
  2. 为通用定义创建父模块
  3. 将 Maven 插件和所有库升级到最新版本。对于 Maven 编译器,设置 Java11 目标(仅最新版本的 Maven 编译器插件支持 Java11)。
  4. 为每个模块定义导出的包(并指定需要哪些包)
  5. 如果有很多模块,则从其中的几个开始,然后包括剩余的模块。

如果它可以帮助你,让我们看看github 上的这个简单项目(它针对 Java11,它是一个多模块 Maven 项目)。

希望能帮助到你。