JDK8升级高版本JDK指南
没耐心的可以直接跳到后面的实战准备工作下载新版本的JDK
从JavaSE下载下载并安装新的JDK版本。在重新编译之前运行你的程序
尝试在最新的JDK版本上运行您的应用程序。大多数代码和库无需任何更改即可在新版本上运行,但可能有一些库需要升级。
当您运行应用程序时,请查看来自JVM的有关过时VM选项的警告。如果VM无法启动,则查找RemovedGCOptions。
如果您的应用程序成功启动,请仔细查看您的测试并确保其行为与您一直使用的JDK版本相同。例如,一些早期采用者注意到他们的日期和货币格式不同。请参阅默认使用CLDR区域设置数据。
要使您的代码在最新的JDK版本上运行,请了解每个JDK版本中的新功能和更改。有关JDK17中的新功能和更改的详细信息,请参阅JDK17中的新增功能新功能和增强功能。有关JDK16中的新功能和更改的详细信息,请参阅JDK16中的新增功能新功能和增强功能。有关JDK15中的新功能和更改的详细信息,请参阅JDK15中的新增功能新功能和增强功能。有关JDK14中的新功能和更改的详细信息,请参阅JDK14中的新增功能新功能和增强功能。有关JDK13中的新功能和更改的详细信息,请参阅JDK13中的新增功能新功能和增强功能。有关JDK12中的新功能和更改的详细信息,请参阅JDK12中的新增功能新功能和增强功能。有关JDK11中的新功能和更改的详细信息,请参阅JDK11中的新增功能新功能和增强功能。有关JDK10中的新功能和更改的详细信息,请参阅JDK10中的新增功能。有关JDK9的所有新功能的完整列表,请参阅JDK9中的新增功能。有关JDK9中更改的详细信息,请参阅JDK9发行说明。
即使您的程序看起来运行成功,您也应该完成本指南中的其余步骤并查看问题列表。更新第三方库
对于您使用的每个工具和第三方库,您可能需要一个支持最新JDK版本的更新版本。
检查第三方库和工具供应商的网站,了解每个库或工具的版本,这些库或工具设计用于最新的JDK。如果存在,则下载并安装新版本。
如果您使用Maven或Gradle构建应用程序,请确保升级到支持最新JDK版本的最新版本。
如果您使用IDE开发应用程序,那么它可能有助于迁移现有代码。NetBeans、Eclipse和IntelliJIDE都有可用的版本,包括对最新JDK的支持。
您可以在OpenJDKwiki上的QualityOutreach上查看使用OpenJDK构建的许多免费开源软件(FOSS)项目的测试状态。如果需要,编译您的应用程序
使用新版本的JDK编译器编译您的代码将简化向新版本的迁移,因为代码可能依赖于已被确定为有问题的API和特性。但是,这不是绝对必要的。
如果您需要使用JDK11和更高版本的编译器编译代码,请注意以下几点:如果您()在源代码中使用下划线字符作为单字符标识符,那么您的代码将无法在JDK11及更高版本中编译。它会在JDK8中生成警告,并从JDK9开始生成错误。
举个例子:
staticObjectnewObject();
此代码从编译器生成以下错误消息:
MyClass。java:2:error:asofrelease9,isakeyword,andmaynotbeusedasalegalidentifier。如果您将sourceandtarget选项与一起使用javac,请检查您使用的值。
支持的sourcetarget值为17(默认值)、16、15、14、13、12、11、10、9、8和7。
在JDK8中,不推荐设置source和target的值为1。55或更早的值,如果设置这样值有警告。在JDK9及更高版本中,这些值会直接抛出Error。
javacsource5target5Sample。javawarning:〔options〕bootstrapclasspathnotsetinconjunctionwithsource5error:Sourceoption5isnolongersupported。Use6orlater。error:Targetoption1。5isnolongersupported。Use1。6orlater。
使用新的release标志而不是sourcetarget选项。请参阅JavaDevelopmentKitToolSpecifications中的javac。
release标志的有效值和sourcetarget选项相同。
javac命令可以识别和处理大于等于JDK1。0。2版本源文件。
请参阅JEP182:停用javacsource和target选项的策略。
JDK的内部API,例如sun。misc。Unsafe在JDK11及更高版本中仍然可以访问,但大多数JDK的内部API在编译时无法访问。您可能会收到编译错误,表明您的应用程序或其库依赖于内部API。
识别依赖关系,请运行Java依赖关系分析工具。如果可能,请更新您的代码以使用支持的替换API。
您可以使用addexports和addopens选项作为临时解决方法来编译引用JDK内部类的源代码。有关这些选项的更多信息,请参阅JEP261:JDK中的模块系统和强封装。您可能会看到比以前更多的弃用警告。在您的代码上运行jdeps
在您的应用程序上运行该jdeps工具以查看您的应用程序和库所依赖的包和类。如果您使用内部API,则jdeps可能会建议替换以帮助您更新代码。
要查找对内部JDKAPI的依赖关系,请jdeps使用该jdkinternals选项运行。例如,在调用了sun。misc。BASE64Encoder的类上运行jdeps,您将看到:
jdepsjdkinternalsSample。classSample。classJDKremovedinternalAPISamplesun。misc。BASE64EncoderJDKinternalAPI(JDKremovedinternalAPI)Warning:JDKinternalAPIsareunsupportedandprivatetoJDKimplementationthataresubjecttoberemovedorchangedincompatiblyandcouldbreakyourapplication。PleasemodifyyourcodetoeliminatedependencyonanyJDKinternalAPIs。ForthemostrecentupdateonJDKinternalAPIreplacements,pleasecheck:https:wiki。openjdk。java。netdisplayJDK8JavaDependencyAnalysisToolJDKInternalAPISuggestedReplacementsun。misc。BASE64EncoderUsejava。util。Base64since1。8
如果您使用Maven,则有一个jdeps可用的插件。
有关jdeps语法,请参阅jdepsJava开发工具包工具规范。
但是注意:jdeps是静态分析工具,代码的静态分析可能无法提供完整的依赖关系列表。比如如果代码使用反射来调用内部API,则jdeps无法发出警告。
迁移
JDK8和更高版本的JDK之间发生了重大变化。
每个新的JavaSE版本都会引入一些与以前版本的二进制、源代码和行为不兼容的问题。JDK9及之后的JavaSE平台的模块化带来了许多好处,但也带来了许多变化。仅使用官方JavaSE平台API和受支持的特定于JDK的API(supportedJDKspecificAPIs)的代码应继续工作而无需更改。使用JDK内部API的代码应继续运行,但应迁移以使用受支持的API。
某些API在其默认行为中已被设置为不可访问、删除或更改。编译或运行应用程序时可能会遇到问题。请参阅已删除的工具和组件以及安全更新。
以下部分描述了将JDK8应用程序迁移到更高版本的JDK时应注意的JDK包中的更改。
查看运行应用程序时可能遇到的更改列表。JDK中的强封装
一些工具和库使用反射来访问仅供内部使用的JDK部分。这种反射的使用会对JDK的安全性和可维护性产生负面影响。为了帮助迁移,JDK9到JDK16允许这种反射继续进行,但发出有关非法反射访问的警告。但是,JDK17是强封装(stronglyencapsulated)的,所以默认情况下不再允许这种反射。访问API的非public字段和非public方法的代码java。将抛出InaccessibleObjectException。
请注意,所有JDK版本(包括JDK17)中的工具和库都可以使用sun。misc和sun。reflect包进行反射。
java启动选项illegalaccess允许在JDK9到JDK16中使用反射调用JDK内部Api。您可以指定以下参数:illegalaccesspermit:允许类路径上的代码反映java。JDK8中存在的包的内部结构。对任何此类元素的第一次反射访问操作会导致发出警告,但在此之后不会发出警告。illegalaccesswarn:导致为每个非法反射访问操作发出警告消息。illegalaccessdebug:导致为每个非法反射访问操作显示警告消息和堆栈跟踪。illegalaccessdeny:禁用所有非法反射访问操作,但由其他命令行选项启用的操作除外,例如addopens。
许多工具和库已更新以避免依赖JDK内部Api,而是使用在JDK8和17之间引入的标准JavaAPI。同时illegalaccess启动选项在JDK17中已过时。在JDK17中使用此启动器选项,无论是使用permit,warn,debug或deny,除了发出警告消息外没有任何作用。
如果您无法获取或部署较新版本的工具和库,则有两个命令行选项可让您授予对旧版本工具和库的特定内部API的访问权限:addexports:如果您有一个较旧的工具或库需要使用已被强封装的内部API,则使用addexports运行时选项。您还可以addexports在编译时使用来访问内部API。addopensjava。:如果您有一个较旧的工具或库需要通过反射访问API的非public字段和非public方法,请使用该addopens选项。
请参阅JEP403:默认情况下强封装JDK内部。
addexports
如果您有一个较旧的工具或库需要使用已被强封装的内部API,请使用addexports运行时选项。您还可以addexports在编译时使用来访问内部API。
该addexports选项的语法是:
addexports(,)
其中和是模块名称,是包的名称。
addexports如果目标模块读取源模块,该选项允许目标模块中的代码访问源模块的命名包中的类型。
作为一种特殊情况,如果是ALLUNNAMED,则源包将导出到所有未命名的模块,无论它们最初存在还是稍后创建。例如:
addexportsjava。managementsun。managementALLUNNAMED
此示例允许所有未命名模块中的代码(类路径上的代码)访问java。managementsun。management。
如果类路径上的代码使用反射API(setAccessible(true))尝试访问java。API的非公共字段和方法,则代码将失败。默认情况下,JDK17不允许这样做。但是,您可以使用该addopens选项来允许这样做。有关更多信息,请参见addopens部分。
如果在类路径上运行的应用程序oldApp必须使用模块的未导出com。sun。jmx。remote。internal包java。management,则可以通过以下方式授予它所需的访问权限:
addexportsjava。managementcom。sun。jmx。remote。internalALLUNNAMED
您还可以使用AddExportsJAR文件清单属性:
AddExports:java。managementsun。management
谨慎使用该addexports选项。您可以使用它来访问库模块甚至JDK本身的内部API,但这样做的风险由您自己承担。如果该内部API更改或被删除,那么您的库或应用程序将失败。
参见JEP261:模块系统。
addopens
一些工具和库使用反射API(setAccessible(true))尝试访问java。API的非公共字段和方法。默认情况下,这在JDK17上不再可能,但您可以使用addopens命令行上的选项为特定工具和库启用它。
addopens语法如下:
addopens(,)
无论模块声明如何,此选项都允许打开给。
作为一种特殊情况,如果是ALLUNNAMED,则源包将导出到所有未命名的模块,无论它们最初存在还是稍后创建。例如:
addopensjava。managementsun。managementALLUNNAMED
此示例允许类路径上的所有代码访问java。managementsun。management包中公共类型的非公共成员。新版本字符串方案
JDK10对JDK9中引入的版本字符串方案引入了一些小的更改,以更好地适应基于时间的发布模型。JDK11及更高版本保留了JDK10中引入的版本字符串格式。
如果您的代码依赖于版本字符串格式来区分主要、次要、安全和补丁更新版本,那么您可能需要更新它。
新版本字符串的格式为:
FEATURE。INTERIM。UPDATE。PATCH
添加了用于解析、验证和比较版本字符串的简单JavaAPI。看java。lang。Runtime。Version。
请参阅Java平台中的版本字符串格式,标准版安装指南。
有关JDK9中引入的版本字符串的更改,请参阅JEP223:新版本字符串方案。
有关JDK10中引入的版本字符串更改,请参阅JEP322:TimeBasedReleaseVersioning。已安装的JDKJRE映像的更改
对JDK和JRE进行了重大更改。更改了JDK和JRE布局
安装JDK后,如果查看文件系统,您会注意到目录布局与JDK9之前的版本不同。
JDK11及更高版本
JDK11及更高版本没有JRE映像。请参阅Java平台中JDK的已安装目录结构,标准版安装指南。
DK9和JDK10
以前的版本有两种类型的运行时映像:JRE,它是JavaSE平台的完整实现,以及JDK,它将整个JRE包含在一个jre目录中,以及开发工具和库。
在JDK9和JDK10中,JDK和JRE是两种类型的模块化运行时映像,包含以下目录:bin:包含二进制可执行文件。conf:包含。properties、。policy和其他类型的文件,供开发人员、部署人员和最终用户编辑。这些文件以前在lib目录或其子目录中找到。lib:包含动态链接的库和JDK的完整内部实现。
在JDK9和JDK10中,仍然有单独的JDK和JRE下载,但每个都有相同的目录结构。JDK映像包含历史上在JDK中发现的额外工具和库。没有jdk与jre包装器目录,并且二进制文件(例如java命令)不重复。
请参阅JEP220:模块化运行时映像。新的类加载器实现
JDK9和更高版本维护了自1。2版本以来存在的类加载器的层次结构。但是,为了实现模块系统,进行了以下更改:应用程序类加载器不再是URLClassLoader而是一个内部类。它是既不是JavaSE也不是JDK模块的模块中的类的默认加载器。扩展类加载器已重命名;它现在是平台类加载器。JavaSE平台中的所有类都保证通过平台类加载器可见。仅仅因为一个类通过平台类加载器可见并不意味着该类实际上是由平台类加载器定义的。JavaSE平台中的一些类是由平台类加载器定义的,而其他类是由引导类加载器定义的。应用程序不应依赖于哪个类加载器定义了哪个平台类。在JDK9中实现的更改可能会影响创建类加载null器(即引导类加载器)作为父类加载器并假定所有平台类对父类可见的代码。可能需要更改此类代码以使用平台类加载器作为父级(请参阅ClassLoader。getPlatformClassLoader)。平台类加载器不是URLClassLoader,而是一个内部类。引导类加载器仍然内置在Java虚拟机null中,由ClassLoaderAPI。它定义了一些关键模块中的类,例如java。base。因此,它定义的类远少于JDK8中的类,因此部署Xbootclasspatha或创建类加载null器作为父级的应用程序可能需要如前所述进行更改。删除了rt。jar和tools。jar
以前存储在librt。jar、libtools。jar中的类和资源文件libdt。jar以及各种其他内部JAR文件以更有效的格式存储在lib目录中特定于实现的文件中。
删除rt。jar和类似文件会导致以下方面的问题:从JDK9开始,ClassLoader。getSystemResource不返回指向JAR文件的URL(因为没有JAR文件)。相反,它返回一个jrtURL,该URL命名存储在运行时映像中的模块、类和资源,而不显示映像的内部结构或格式。
例如:
ClassLoader。getSystemResource(javalangClass。class);
在JDK8上运行时,此方法返回以下形式的JARURL:
jar:file:usrlocaljdk8jrelibrt。jar!javalangClass。class
模块化的镜像(modularimage)不包含任何JAR文件,因此这种形式的URL没有意义。在JDK9及更高版本上,此方法返回:
jrt:java。basejavalangClass。class
java。security。CodeSourceAPI和安全策略文件使用URL来命名要被授予特定权限的代码库的位置。请参阅Java平台中的策略文件语法,标准版安全开发人员指南。运行时组件需要的特定权限当前使用文件URL的方式定义在confsecurityjava。policy文件中(Componentsoftheruntimesystemthatrequirespecificpermissionsarecurrentlyidentifiedintheconfsecurityjava。policyfilebyusingfileURLs)。旧版本的IDE和其他开发工具需要能够枚举存储在运行时映像中的类和资源文件,并通过打开和读取rt。jar类似文件来直接读取它们的内容。这对于模块化镜像是不可能的。移除了扩展机制
在JDK8及更早版本中,扩展机制使运行时环境可以查找和加载扩展类,而无需在类路径上专门命名它们。从JDK9开始,如果您需要使用扩展类,请确保JAR文件位于类路径上。
在JDK9和JDK10中,如果设置了系统属性或目录存在,javac编译器和java启动器将退出。要另外检查特定于平台的系统范围目录,请指定命令行选项。如果目录存在且不为空,这将导致发生相同的退出行为。扩展类加载器保留在JDK9(及更高版本)中,并被指定为平台类加载器(参见java。ext。dirslibextXX:CheckEndorsedAndExtDirsgetPlatformClassLoader。)但是,在JDK11中,此选项已过时,使用时会发出警告。
以下错误表示您的系统配置为使用扩展机制:
libextexists,extensionsmechanismnolongersupported;Useclasspathinstead。。Error:CouldnotcreatetheJavaVirtualMachine。Error:Afatalexceptionhasoccurred。Programwillexit。
如果设置了java。ext。dirs系统属性,您将看到类似的错误。
要修复此错误,请删除ext目录或java。ext。dirs系统属性。
请参阅JEP220:模块化运行时映像。删除了经认可的标准覆盖机制
java。endorsed。dirs系统属性和libendorsed目录将不再存在。如果检测到任何一个,编译器和启动器将退出javac。java
从JDK9开始,您可以使用可升级模块或将JAR文件放在类路径中实现类似功能。
此机制旨在让应用程序服务器覆盖JDK中使用的组件。要更新的包将被放入JAR文件中,系统属性java。endorsed。dirs会告诉Java运行时环境在哪里可以找到它们。如果未指定此属性的值,则使用默认值JAVAHOMElibendorsed。
在JDK8中,您可以使用XX:CheckEndorsedAndExtDirs命令行参数来检查系统上任何位置的此类目录。
在JDK9及更高版本中,如果设置了java。endorsed。dirs系统属性或libendorsed目录存在,javac编译器和java启动器将退出。
以下错误意味着您的系统配置为使用认可的标准覆盖机制:
libendorsedisnotsupported。EndorsedstandardsandstandaloneAPIsinmodularformwillbesupportedviatheconceptofupgradeablemodules。Error:CouldnotcreatetheJavaVirtualMachine。Error:Afatalexceptionhasoccurred。Programwillexit。
如果设置了java。endorsed。dirs系统属性,您将看到类似的错误。
要修复此错误,请删除libendorsed目录或取消设置java。endorsed。dirs系统属性。
请参阅JEP220:模块化运行时映像。删除了macOS特定的功能
从JDK9开始删除了macOS特定功能。特定于平台的桌面功能
该类包含对Apple特定的和包java。awt。Desktop中API的替换。新的API取代了macOSAPI,并且独立于具体操作系统。com。apple。eawtcom。apple。eio
com。apple。eawt和包中的APIcom。apple。eio是封装的,因此您将无法在JDK9或更高版本中针对它们进行编译。但是,它们在运行时仍可访问,因此编译为旧版本的现有代码继续运行。apple最终,使用andcom。apple包及其子包中的内部类的库或应用程序将需要迁移到新的API。
com。apple。concurrent和包被删除,apple。applescript没有任何替换。
请参阅JEP272:特定于平台的桌面功能。移除AppleScript引擎
AppleScript引擎,特定于平台的javax。script实现,已在JDK中删除,没有任何替换。
AppleScript引擎在最近的版本中几乎无法使用。该功能仅在JDK7或JDK8中有效,系统上已经有Apple版本的AppleScriptEngine。jar文件。Windows注册表项更改
Java11及更高版本的安装程序会在安装JDK时创建Windows注册表项。对于JDK16,安装程序会创建以下Windows注册表项:HKEYLOCALMACHINESOFTWAREJavaSoftJDKHKEYLOCALMACHINESOFTWAREJavaSoftJDK16
如果安装了两个版本的JDK,则会创建两个不同的Windows注册表项。例如,如果JDK15。0。1与JDK16一起安装,则安装程序会创建另一个Windows注册表项,如下所示:HKEYLOCALMACHINESOFTWAREJavaSoftJDKHKEYLOCALMACHINESOFTWAREJavaSoftJDK16HKEYLOCALMACHINESOFTWAREJavaSoftJDK15。0。1部署
Java部署技术在JDK9中被弃用,并在JDK11中被删除。
JavaApplet和WebStart功能,包括AppletAPI、Java插件、JavaApplet查看器、JNLP和JavaWebStart(包括javaws工具)在JDK9中均已弃用
使用jlinkJDK9引入的工具来打包和部署专用运行时,而不是依赖于预安装的系统JRE。
删除了启动时JRE版本选择功能
从JDK9开始,删除了请求不是在启动时启动的JRE的JRE版本的能力。
现代应用程序通常使用JavaWebStart(JNLP)、本机OS打包系统或活动安装程序进行部署。这些技术有自己的方法来管理所需的JRE,方法是根据需要查找或下载和更新所需的JRE。这使得启动器的启动时可以选择已过时JRE版本。
在以前的版本中,您可以指定启动应用程序时要使用的JRE版本(或版本范围)。可以通过命令行选项和应用程序JAR文件中的清单条目来选择版本。
从JDK9开始,javalauncher修改如下:version:如果在命令行上给出了选项,则发出错误消息并退出。JREVersion如果在JAR文件中找到清单条目,则发出警告消息并继续。
请参阅JEP231:删除启动时JRE版本选择。垃圾收集的变化将G1设为默认垃圾收集器删除了部分GC选项
以下GC组合将导致您的应用程序在JDK9及更高版本中无法启动:DefNewCMSParNewSerialOldIncrementalCMS
CMS的前台模式也已被删除。删除的命令行标志是Xincgc、XX:CMSIncrementalMode、XX:UseCMSCompactAtFullCollection、XX:CMSFullGCsBeforeCompaction和XX:UseCMSCollectionPassing。
命令行标志XX:UseParNewGC不再有效。该ParNew标志只能用于CMS和CMS需要ParNew。因此,该XX:UseParNewGC标志已被弃用,并且在未来的版本中删除。
请参阅JEP214:删除JDK8中已弃用的GC组合。
删除了永久代
JDK8中删除了永久代,相关的VM选项会导致打印警告。您应该从脚本中删除这些选项:XX:MaxPermSizesizeXX:PermSizesize
在JDK9及更高版本中,JVM会显示如下警告:
JavaHotSpot(TM)64BitServerVMwarning:IgnoringoptionMaxPermSize;supportwasremovedin8。0
使用了永久代参数的工具可能必须更新。
请参阅JEP122:删除永久代和JDK9发行说明删除的API、功能和选项。GC日志输出的更改
垃圾收集(GC)日志使用JVM统一的日志框架,新旧日志存在一些差异。您正在使用的任何GC日志解析器都可能需要更改。
您可能还需要更新JVM日志记录选项。所有与GC相关的日志记录都应使用gc标签(例如Xlog:gc),通常与其他标签结合使用。和选项已被弃用XX:PrintGCDetails。XX:PrintGC
请参阅JavaDevelopmentKitToolSpecifications和JEP271:UnifiedGCLogging中的使用JVMUnifiedLoggingFramework启用日志记录。正则表达式匹配中的行为变化
java。util。regex。Pattern用方括号定义正则表达式中的字符类。例如,〔abc〕匹配a,b,或c。否定字符类是用紧跟在左大括号后面的插入符号定义的。例如,〔abc〕匹配除a,b,或之外的任何字符c。
在JDK8及更早版本中,否定字符类不会否定嵌套字符类。例如,〔ab〔cd〕ef〕匹配c但不匹配a,或者e因为它们不在嵌套类中。运算符一个接一个地应用。在此示例中,在嵌套之前应用了否定运算符。在JDK8及更早的版本中,运算符仅应用于字符类中的最外层字符,而不应用于到嵌套的字符类。这种行为令人困惑且难以理解。
但是,在JDK9及更高版本中,否定运算符应用于所有嵌套字符类。例如,〔ab〔cd〕ef〕不匹配c。
为了进一步解释,请考虑以下正则表达式:
〔adcf〕
在JDK8中,首先应用运算符,因此该示例被解释为〔ad〕与〔cf〕。这匹配eandf但不匹配a,b,c,ord。
在JDK9及更高版本中,首先应用运算符,因此该示例被解释为〔ad〕〔cf〕。这匹配a,b,e和f但不匹配cord。
作为最佳实践,寻找使用字符类的正则表达式以及否定、交集和嵌套类的某种组合。可能需要调整这些正则表达式以考虑更改的行为。
后续步骤如果需要,使用javac工具release中的新标志交叉编译到平台的旧版本。利用IDE的建议来使用最新功能更新代码。通过运行静态分析工具jdeprscan查看您的代码是否使用了已弃用的API。正如本指南中已经提到的,可以从JDK中删除API,但必须提前通知。熟悉多版本JAR文件等新功能(请参阅jar)。实战目标
使用JDK17构建hutool,新建springboot工程并调用JDK17调用hutool中的功能。步骤
先用JDK17直接构建,修改pom。xml,将JDK版本修改为17
首先确保已经安装配置好JDK17:这里使用了更高版本的19
运行mvncleancompile进行编译
编译失败,因为javax。xml包已经被移除。
在hutoolcorepom。xml中添加javax。xml的依赖
javax。xml。bindjaxbapiartifactId2。3。0com。sun。xml。bindjaxbcoreartifactId2。3。0com。sun。xml。bindjaxbimplartifactId2。3。0
重新编译,全部编译成功
执行mvninstallDmaven。javadoc。skiptrue执行单元测试并本地安装hutool,执行单元测试在这里很重要,因为不能保证升级JDK之后,代码逻辑不受影响。
对于Unabletomakeprotectednativejava。lang。Objectjava。lang。Object。clone()throwsjava。lang。CloneNotSupportedExceptionaccessible:modulejava。basedoesnotopensjava。langtounnamedmodule5a65309b错误,明显是因为Java9开始的模块系统强封装造成的,我们需要添加addexports。
org。apache。maven。pluginsmavensurefirepluginartifactIdaddopensjava。basejava。langALLUNNAMEDargLine
添加上面插件和配置之后,java。lang。CloneNotSupportedException不再出现,现在来处理java。lang。OutOfMemoryError:unabletocreatenativethread:possiblyoutofmemoryorprocessresourcelimitsreached。这个错误是因为要创建的线程数超过了系统的限制,调大即可。
解决这个错误之后,出现modulejava。basedoesnotopensjava。util。regextounnamedmodule15615099
继续添加opens
出现新的错误,这是因为JDK移除了javax。activation,添加依赖就好
添加如下依赖
出现新的错误java。lang。NoSuchFieldException:modifiers
因为JDK12开始,field字段不再有modifiers,所以更改代码以满足要求
再次重新构建,出现新的错误
添加opens:
再次构建,出现如下错误
debug之后发现,这个错误是因为高版本jdk使用MemberName来判断field的modifier,让前面代码中修改失败,所以只能先暂时跳过这个测试并不使用这个功能,等待项目组更新版本支持高版本JDK。
至此构建全部成功
新建SpringBoot工程
引入之前构建在本地的hutool
编写一个简单的测试类:
RestControllerpublicclassTestController{GetMapping(test{plainText})publicResponseEntitytest(PathVariable(plainText)StringplainText){inthashHashUtil。apHash(plainText);returnResponseEntity。ok(hash);}}
启动应用进行测试:
关于阿里高层副总裁贾扬清事件的不同思考近期关于阿里技术副总裁贾扬清隔离期结束离开上海的事情,网络上舆情沸腾,从他脸书对这个行为的描述上看,确实让人有点费解。一、阿里自从马云上海外滩金融峰会事件之后,负面新闻层……
西亚卡姆32分9助攻猛龙大胜活塞猛龙11897大胜活塞,后者遭遇5连败。斯科蒂巴恩斯继续缺阵。范弗里特、西亚卡姆、阿奴诺比上来命中4记三分,巴顿连突带罚,命中三分,猛龙207开局。艾维三分,怀斯曼扣篮,……
觉察情绪,随时调整心向光明,让心灵自由呼吸修炼路上默默蜕变不要让一些习惯性的郁闷情绪荒芜了当下珍贵的时间,要随时敏锐的觉察,但凡有一丝觉察到那样的萌芽,立即警醒自己,顷刻间从那种情绪中走出来,一定要让自己活在现实中,精神抖擞的做好眼下……
丧期过后萌娃长期行居丧礼仪真的是好事吗?是每有大事,必有祥瑞吗?中国似乎有这样的文化传统!但我在下文种讲述的现象,绝对不是祥瑞!最近各大网站频频有作者报道小萌娃跪祭已故爷爷(奶奶)的故事,这不,安徽宣城也……
勇敢一些,因为我们终将失去一切这个浮躁而复杂的世界,大到茫茫宇宙,小到生物细胞,人类终究只是匆匆过客。所以,放下你的担忧和焦虑,把握这有限的时间,不妨大胆一点去爱,去追求一个梦想,或者翻越一座高山,反……
8月值得入手的曲面屏手机推荐价格也不贵高性价比一个比一个好用越来越多的手机开始出曲面屏手机了,价格也是越来越低了,以前曲面屏手机都是旗舰机的代表,现在很多中端机型也开始使用曲面屏了,让广大民众也使用的起曲面屏手机,今天我就推荐三款8月值……
64岁麦当娜裹着棉被出街?染了粉色头发扮嫩,离开滤镜也显老64岁的麦当娜可真是始终保持着18岁的心态,在滤镜和PS的效果之下,麦当娜也总是在社交平台上呈现出少女的模样。麦当娜之前的小男友几乎都是20多岁,所以看得出来这个老太太多么时髦……
SQL优化篇如何成为一位写优质SQL语句的绝顶高手!标准结构化查询语言简称SQL,编写SQL语句是每位后端开发日常职责中,接触最多的一项工作,SQL是关系型数据库诞生的产物,无论是什么数据库,MySQL、Oracle、SQLSe……
大S与具俊晔闪婚后首晒照,逆龄成18岁少女,锁骨处爱的纹身曝5月5日,大S与具俊晔闪婚后,首度在社交网公开近照,她与朋友聚会,只涂抹了口红就出门,皮肤白得发光,逆龄成18岁少女。照片中的大S穿着露肩上衣,随意将头发扎起来,戴着闪亮……
交友不慎,我的5000元奖金没了来说是非者,定是是非人。今日在你面前说他人,明日自会在他人面前说你。别再相信所谓的闺蜜基友知己了,往往说出秘密的,都是身边自认为最亲近的人。无论多熟多信任的人……
秦州区简介秦州区简介秦州区,隶属甘肃省天水市,位于甘肃省东南部,是天水市委、市政府所在地。秦州区地处中纬度地带,属温带大陆性季风气候。秦州之名始于三国,是中国最早设置的郡县之一,已……
大牌时尚你能看懂就是我输向来在贵字的道路上一去不回头的奢侈大牌们,近日换了个全新打法开始比烂了你能信?大牌之所以是大牌,因为它们首先是一种会讲故事的艺术品,其次才是消费品。普通人与这些虚渺……