This article is the 15th day article of Java Advent Calendar 2019.
I left it for about a year after the free support for Java 8 expired in January 2019, Since I have time this time, I updated to Java 11 which is the first LTS since 8 It is a memo at that time
I tried to start writing, but it seems that OpenJDK 8 will be supported until June 2023, so Maybe I should have just changed from Oracle JDK to OpenJDK ... But I've done it so I'll record it
Enter the following command to install the latest JDK
brew cask install adoptopenjdk
However, at present, JDK13 is included, so it is necessary to specify the version to include JDK11 which is the LTS version. Search for the published version
$ 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
Since I want to install JDK11 this time, specify the version with the following command and install it
brew cask install adoptopenjdk11
Change the existing PATH to JDK11
export JAVA_HOME=`/usr/libexec/java_home -v 11`
Check version
$ 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)
Open Project Structure with Command +; and specify JDK 11 for Project SDK and Project Language Lebel.
Gradle 4.4 does not support JDK 11, so it needs to be updated It seems that 5.0 and later versions are supported, but since it is a good idea, I will try to make it the current latest 6.0.1
If you update the version described in gradle / wrapper / gradle-wrapper.properties, the version of Gradle applied to the project will be changed. This time, just change the following 4.4 part to 6.0.1.
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-bin.zip
That alone will not propagate the changes to gradlew, so regenerate gradlew
./gradlew wrapper
Change various framework libraries to those compatible with JDK11 Basically everything is described in gradle.build, so you can modify it
The meaning of each specification is described in Official, so specify what you need.
sourceCompatibility = 11
targetCompatibility = 11
Updated because the jar specification method has changed See Official for details.
jar {
baseName = 'example'
version = '1.0.0-SNAPSHOT'
}
Changed what was above to below
bootJar {
archiveBaseName = "example"
archiveVersion = "1.0.0-SNAPSHOT"
}
Spring Boot 2.1.x or higher is required to use Java 11 Since it is a good idea, I will try to make it the latest 2.2.2 Basically, you can follow the Official Migration Guide.
buildscript {
ext {
springBootVersion = '1.5.13.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
SpringBoot no longer automatically applies the dependency management plugin, so add the plugin as well
apply plugin: 'io.spring.dependency-management'
Since the method of specifying the main class has changed, that has also changed
springBoot {
mainClassName = "jp.co.example.Application"
}
Update the library version while looking at MavenRepository
It is easier to specify the version of the library around Spring Boot with a variable However, please note that some versions may differ from the Spring Boot version.
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
Since the method of specifying the dependency has changed, if you normally specify only the version and update it, an error will occur if the method automatically generated by lombok at build time is not found Refer to Official and add the following specifications
compileOnly('org.projectlombok:lombok:1.18.10')
annotationProcessor('org.projectlombok:lombok:1.18.10')
Also, when using @Value, I get an error that deserialization in Jackson doesn't work. It can be avoided by creating a file called lombok.config directly under the project and describing the following. Other settings can be found in the Official Migration Guide (https://projectlombok.org/changelog).
lombok.addJavaxGeneratedAnnotation = false
lombok.addLombokGeneratedAnnotation = true
lombok.noArgsConstructor.extraPrivate = false
lombok.anyConstructor.addConstructorProperties = true
config.stopBubbling = true
jjwt
Because it relies on APIs that are obsolete in Java 11 when using some algorithms If you are using Java 8 and have migrated to Java 11, you need to add a dependency Add the following referring to Official
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')
Update to good Don't forget to update the libraries specified in other than dependencies. I forgot to update jacoco and wasted my time
This article will be used as a reference to fix the obsolete API.
When I try to build it, there are multiple obsolete classes around SpringBoot, so I will fix it Refer to Official Migration Guide
This time, only the classes around org.springframework.boot.autoconfigure.web that controlled the error message were targeted. The following method
@RequestMapping(value = "/error")
public ErrorResponse error(HttpServletRequest request, HttpServletResponse response) {
ServletRequestAttributes attributes = new ServletRequestAttributes(request);
Throwable error = errorAttributes.getError(attributes);
return convertException(error);
}
do this
@RequestMapping(value = "/error")
public ErrorResponse error(WebRequest request) {
Throwable error = errorAttributes.getError(request);
return convertException(error);
}
If you do so far, the build will pass for the time being, so run the test and check if degreasing has occurred There seems to be no problem this time We will postpone the resolution of Warn and aim to deploy the JDK11 compatible application to Docker for the time being.
Dockerfile only needs to change the base image This article will help you decide which image to choose. As recommended this time, select adoptopenjdk / openjdk11: alpine-slim
FROM adoptopenjdk/openjdk11:alpine-slim
If you are using a CI / CD tool, don't forget to change that setting as well. It is easy to forget to specify the base image when building the test environment.
SpringBootActuator
Note that the / actuator prefix has been added to all endpoints automatically generated by SpringBootActuator. Deploying doesn't work, especially when using / health For other changes, refer to this article.
With the above modifications, you should be ready to deploy for the time being. If any problem occurs, I will add it as appropriate Please let me know if there is something like "this way of writing is correct" or "this may cause a bug".
Install AdoptOpenJDK11 with homebrew on mac
Note on updating the version of Gradle wrapper
Memorandum of understanding when Spring Boot 1.5.10 → Spring Boot 2.0.0
Spring Boot 2.0 Migration Guide
Think about recommended Docker images after Java 11 release
Spring Boot 2.0 Actuator, 3 changes you need to know to get it working
What Java engineers should prepare for the Java 11 release
ObjectMapper can't deserialize without default constructor after upgrade to Spring Boot 2
Recommended Posts