白癜风在什么医院好 https://jbk.39.net/yiyuanfengcai/video_bjzkbdfyy/当我们一个接一个地升级OpenJDK版本时,我们遇到了Java平台的许多显著变更。而我们的迁移之路漫长且需有条不紊地推进,这意味着这些变更会给我们带来了很多挑战,但在这里我们只讨论其中的几个。
类路径与模块化
JavaSE9平台引入的重大变更之一就是Java平台模块系统(JavaPlatformModuleSystem,JPMS)。JPMS将JDK划分为多个模块,每个模块都是一组命名唯一且可重用的相关包。
好消息是,Java9仍然支持传统的类路径,它能与模块路径一起工作,并映射到一个被称为未命名模块的特殊模块上。因此,构成Salesforce应用程序类路径的所有JAR文件都会自动加入模块系统,从而导致了传统类路径和模块路径的混合。
实际上,Salesforce应用程序的整个类加载器层次结构都保留在Java9及更高版本中。它由我们的Web服务器和Servlet容器锚定,委托给OSGi类加载器,而OSGi类加载器又委托给Java运行时的内置类加载器。
然而,作为Jigsaw计划的一部分,Java9带来了一个影响类加载的重大变更。这是对授权标准覆盖机制(EndorsedStandardsOverrideMechanism,用于支持加载包含授权标准和独立技术实现的JAR文件)和扩展机制(ExtensionMechanism,用于支持加载包含扩展或可选软件包的JAR文件)的移除。由于Salesforce应用程序过去依赖于这两种机制,因此必须使用-module-path、-upgrade-module-path和-patch-module标志的组合,将所有受影响的JAR文件迁移到Salesforce应用程序的模块路径下。不过,这些非模块化的JAR文件都无需转换为模块:它们作为依赖项被放置在Salesforce应用程序的模块路径上,从而自动成为模块化的。此功能被称为自动模块化,创建它是为了减轻将现有应用程序转换为新模块系统的负担。
影响Salesforce应用程序的另一个变更是删除了Salesforce应用程序所依赖的JavaEnterpriseEdition(“JavaEE”)API。Java9开始将这些API分离到它们各自的模块中,这些模块被注解为不推荐使用,以便删除,这表明了在将来的版本中会删除它们的意图。这些模块包含在运行时镜像中,但默认情况下未启用。因而,它们必须通过--addmodules标识显式“激活”。
从Java11开始,这些模块不再包含在运行时中(参见JEP:删除JavaEE和CORBA模块)。相反,JavaEE和CORBA技术的独立版本作为Maven构件发布,并可以从第三方网站(如MavenCentral)上获取,我们从那里下载了它们并将它们添加到了Salesforce应用程序的模块路径中。
向后不兼容
在将Salesforce应用程序的Java运行时迁移到OpenJDK11时,我们发现了许多向后不兼容的变更。其中大多数都是“设计使然”,并且是涵盖在版本说明中了的,正如下面所要讨论的那样。(有一个true的回归影响了布尔型bean属性的内省;这是由OpenJDK实现本身的一个bug引起的,我们报告了这个bug,并且它已经被修复了。)
设计上向后不兼容变更的例子很明显,因为它会导致JVM在启动时中断,并出现如下的错误:
UnrecognizedVMoptionOptionError:CouldnotcreatetheJavaVirtualMachine.Error:Afatalexceptionhasoccurred.Programwillexit.
引发该错误的原因是Salesforce应用程序一直在使用一些Java9以后不再支持的垃圾回收(GC)选项。某些受影响的GC选项(例如UseParNewGC)在JDK8(JEP)中已被弃用了,而在Java9(JEP)中已经被移除了。其他的,包括PrintGCDateStamps和PrintGCTimeStamps在内,由于已经在Java9中重新实现了GC日志(请参阅JEP)以便使用JEP中引入的UnifiedJVMLogging框架,它们都变成非法的了。
接下来的挑战就变成,继续为仍运行在OpenJDK8上的Salesforce生产实例提供这些GC选项的支持,同时避免这些选项用在已经升级到OpenJDK11的Salesforce生产实例上。
我们采用了一种可扩展方法,在启动Salesforce应用程序之前,扩充负责组装该应用程序的JVM参数列表的ant目标,这样,当Java运行时被设置为OpenJDK11时,它会过滤掉(使用ant语法)所有不受支持的GC选项。事实证明,这种方法非常灵活,允许我们将选定的Salesforce生产实例升级到OpenJDK11,并在需要时回滚到OpenJDK8。一旦OpenJDK11成为新的默认Java运行时,并且所有的生产实例都已经成功迁移,过滤器就可以从ant目标中移除了。
虽然影响GC选项的变更明显破坏了Salesforce应用程序,但其他设计上的变更却以更微妙的方式对应用程序造成了破坏。其中一个变更影响了fork/join公共池线程的上下文类加载器,它不再继承任务提交线程的上下文类加载器,而是使用系统类加载器进行初始化。JDK9版本说明中涵盖了这一变更,并提供了恢复以前行为的解决方法。这一变更的影响在Salesforce应用程序中以许多不同的方式表现出来了。