将SpringBoot1.5 + Gradle4.4 + Java8 + Docker环境升级为适用于Java11的环境
这篇文章是2019年Java圣诞日历的第15天的文章。
首先,
自从2019年1月免费提供的Java 8支持到期以来,大约一年时间里一直没有更新,但由于现在有时间了,我们进行了更新,更新至Java 11,这是自Java 8之后的首个LTS版本。以下是当时的备忘录。
她打算开始写下去,但据说OpenJDK8会得到支持直到2023年6月,所以只需将OracleJDK更换为OpenJDK就好了……但既然已经完成了,还是将其记录下来吧。
JDK的更新
安装AdoptOpenJDK11
输入下面的命令即可安装最新的JDK。
brew cask install adoptopenjdk
但是,由于当前情况下已经安装了JDK13,所以要安装LTS版的JDK11就需要指定版本。
因此,需要搜索已发布的版本。
$ brew search adoptopenjdk
==> Casks
adoptopenjdk adoptopenjdk11-openj9-jre adoptopenjdk12-openj9 adoptopenjdk13-jre adoptopenjdk8 adoptopenjdk8-openj9-large
adoptopenjdk10 adoptopenjdk11-openj9-jre-large adoptopenjdk12-openj9-jre adoptopenjdk13-openj9 adoptopenjdk8-jre adoptopenjdk9
adoptopenjdk11 adoptopenjdk11-openj9-large adoptopenjdk12-openj9-jre-large adoptopenjdk13-openj9-jre adoptopenjdk8-openj9
adoptopenjdk11-jre adoptopenjdk12 adoptopenjdk12-openj9-large adoptopenjdk13-openj9-jre-large adoptopenjdk8-openj9-jre
adoptopenjdk11-openj9 adoptopenjdk12-jre adoptopenjdk13 adoptopenjdk13-openj9-large adoptopenjdk8-openj9-jre-large
因为我想要安装的是JDK11,所以请使用以下命令指定版本进行安装。
brew cask install adoptopenjdk11
将已经设置的路径更改为JDK11。
export JAVA_HOME=`/usr/libexec/java_home -v 11`
确认版本
$ java -version
openjdk version "11.0.5" 2019-10-15
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.5+10)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.5+10, mixed mode)
在IntelliJ的ProjectSDK中指定JDK11
使用快捷键 Command + ; 打开项目结构,将项目SDK和项目语言级别设置为JDK11。
请更新Gradle
由于Gradle4.4不支持JDK11,所以需要进行更新。
5.0及更高版本似乎支持,但为了一举而成,现在将其更新为最新版本6.0.1。
更新gradle-wrapper.properties文件
只需更新 gradle/wrapper/gradle-wrapper.properties 文件中所示的版本,就可以更改应用于项目的 Gradle 版本。这次只需将其 4.4 部分更改为 6.0.1。
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-bin.zip
更新gradlew。
只有这样的话,gradlew的更改就无法传播,因此需要重新生成gradlew。
./gradlew wrapper
更新gradle.build文件
将各种框架和库逐步改为适应JDK11,基本上所有的更改都在gradle.build文件中进行,只需要修改它即可。
更改Java版本的指定
由于每个指定的含义都在官方文件中明确说明,只需指定所需物品。
sourceCompatibility = 11
targetCompatibility = 11
将Gradle版本更新为6系的方式进行修改。
由于jar文件的指定方式已经改变,因此需要进行更新。请参考官方网站获取详细信息。
jar {
baseName = 'example'
version = '1.0.0-SNAPSHOT'
}
将上述的内容改为以下
bootJar {
archiveBaseName = "example"
archiveVersion = "1.0.0-SNAPSHOT"
}
更改SpringBoot的版本
要使用Java 11,需要Spring Boot 2.1.x或更高版本。
既然如此,我们就尝试升级到最新的2.2.2版本。
基本上,按照官方的迁移指南即可。
buildscript {
ext {
springBootVersion = '1.5.13.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
由于SpringBoot不再自动应用依赖关系管理插件,因此需要手动添加插件。
apply plugin: 'io.spring.dependency-management'
由于主类的指定方法发生了变化,所以也需要进行修改。
springBoot {
mainClassName = "jp.co.example.Application"
}
更新图书馆的版本
一边查看Maven仓库,一边更新库的版本。
SpringBoot相关的库
在处理SpringBoot库时,通过使用变量来指定版本会更加方便。然而,需要注意的是,有些库的版本可能与SpringBoot的版本不匹配。
dependencies {
compile("org.springframework.boot:spring-boot-starter-web:${springBootVersion}")
compile("org.springframework.boot:spring-boot-starter-jdbc:${springBootVersion}")
compile("org.springframework.boot:spring-boot-starter-security:${springBootVersion}")
compile("org.springframework.boot:spring-boot-starter-actuator:${springBootVersion}")
testCompile("org.springframework.boot:spring-boot-starter-test:${springBootVersion}")
testCompile("org.springframework.security:spring-security-test:5.2.1.RELEASE")
}
翻译为中文后,以下为一个选项:
翱翔
由于依赖关系的设定方式已经改变,如果只是按照常规方式指定版本并更新,那么在编译时会出现找不到由lombok自动生成的方法的错误。
请参考官方指南,并添加以下设定。
compileOnly('org.projectlombok:lombok:1.18.10')
annotationProcessor('org.projectlombok:lombok:1.18.10')
另外,使用 @Value 时,会导致 Jackson 的反序列化功能无法正常工作的错误发生。
可以通过在项目根目录下创建 lombok.config 文件并添加以下内容来解决该问题。
有关其他设置的详细信息,请参阅官方迁移指南。
lombok.addJavaxGeneratedAnnotation = false
lombok.addLombokGeneratedAnnotation = true
lombok.noArgsConstructor.extraPrivate = false
lombok.anyConstructor.addConstructorProperties = true
config.stopBubbling = true
jjwt (JSON Web Token) 是一种开放标准的身份验证令牌。
由于一些算法依赖已在Java11中废弃的API,在从Java8迁移到Java11时,需要添加以下依赖关系,请参考官方文档。
compile('javax.xml.bind:jaxb-api:2.3.0')
compile('com.sun.xml.bind:jaxb-core:2.3.0')
compile('com.sun.xml.bind:jaxb-impl:2.3.0')
其他
请记得在更新 “dependencies” 以外指定的库时,也要做好更新工作,不要像忘记更新 Jacoco 一样浪费时间。
适配已废弃的Java 11 API。
参考此篇文章对已被废止的API进行修复。
修正已被SpringBoot 2.0废弃的类。
编译后,会出现多个在SpringBoot中已经废弃的类,所以需要进行修正。
可以参考官方的迁移指南进行修正。
只有控制错误消息的 org.springframework.boot.autoconfigure.web 相关类才是本次的目标
以下方法可以修改
@RequestMapping(value = "/error")
public ErrorResponse error(HttpServletRequest request, HttpServletResponse response) {
ServletRequestAttributes attributes = new ServletRequestAttributes(request);
Throwable error = errorAttributes.getError(attributes);
return convertException(error);
}
这样做
@RequestMapping(value = "/error")
public ErrorResponse error(WebRequest request) {
Throwable error = errorAttributes.getError(request);
return convertException(error);
}
我来试试
到目前为止做到这一步,至少可以顺利构建,所以现在要运行测试以确保没有发生任何退化。
这次似乎没有什么问题。
暂时搁置警告的处理,目的是将已经适配JDK11的应用程序打包到Docker中进行部署。
修改Dockerfile
这些Dockerfile只需要更改基础镜像即可。
选择哪个镜像可以参考这篇文章。
这次的推荐选择是adoptopenjdk/openjdk11:alpine-slim。
FROM adoptopenjdk/openjdk11:alpine-slim
其他
修改CircleCI的设置
在使用CI/CD工具时,切勿忘记更改其配置。例如,在构建测试环境时,经常容易忘记指定基础镜像等内容。
春季启动器行为
在Spring Boot Actuator自动创建的所有端点上都添加了/actuator的前缀,所以需要注意。特别是如果使用/health端点,部署可能会出现问题。可以参考本文中的其他变更点。
最后
在以上的修改下,理论上应该已经可以部署了
如果出现问题,我会随时进行补充
如果您发现“这种写法更正确”或者“这样可能会出bug”等情况,请务必告诉我
请提供更多的上下文或具体的内容,这样我可以更好地为您提供翻译。
使用Homebrew在Mac上安装AdoptOpenJDK11。
关于Gradle Wrapper版本更新的备忘录
把Spring Boot 1.5.10 升级到 Spring Boot 2.0.0 的时候的备忘录
Spring Boot 2.0 迁移指南
龙目岛项目
考虑 Java 11 发布后推荐的 Docker 镜像。
为了让Spring Boot 2.0的Actuator能够先暂时运行,有三个变更点是需要了解的。
准备 Java 11 发布的必要步骤, Java 工程师需要做的事情。
升级到Spring Boot 2之后,ObjectMapper无法进行反序列化操作,因为缺少默认构造函数。
龙目岛更新日志