VSCodeのJavaプロジェクトをJava8からJava11に移行した話

### はじめに

Visual Studio Code(以下VSCode)でSpring Bootプロジェクトを開発しています。
Java開発と実行にJava8を使っていましたが、紆余曲折ありJava11に移行しました。

### 話はMicrosoftからの2年前の発表にさかのぼる

Microsoftから`VSCodeのJava開発にJDK11が必要となる`と発表される：

https://devblogs.microsoft.com/java/java-on-visual-studio-code-update-june-2020/

VSCode拡張機能`Language Support for Java`の新しいバージョンにJDK11が必要となり、
VSCodeを起動するたびに、Java11以降を求める警告が表示されるように：
```
Java 11 or more recent is required to run. Please download and install a recent JDK
```

### Java移行コストを加味し、現状維持を選択していた

根拠にしたのは、`redhat-developer`の`vscode-java`の下記issue:

https://github.com/redhat-developer/vscode-java/issues/1543#issuecomment-663382692


さすがVSCode開発環境を手放すわけにはいきませんので、

- VSCodeのJavaプロジェクトでJDK8を使いつづける(Java11警告を無視)
- Java関連のVSCode拡張機能は古いバージョンを指定して使用
例:
```
Language Support for Java(TM) by Red Hat v0.64.1
Debugger for Java v0.20.0
Extension Pack for Java v0.9.0
Spring Boot Tools v1.20.0
Spring Boot Extension Pack v0.0.8
Lombok Annotations Support for VS Code v1.0.1
```

VSCodeの`settings.json`例:

```
    "java.jdk.ls.java.home": "C:\\Program Files\\RedHat\\java-1.8.0-openjdk-1.8.0.322-2",
    "java.configuration.runtimes": [
        {
            "default": true,
            "name": "JavaSE-1.8",
            "path": "C:\\Program Files\\RedHat\\java-1.8.0-openjdk-1.8.0.322-2"
        },
    ],
    "spring-boot.ls.java.home": "C:\\Program Files\\RedHat\\java-1.8.0-openjdk-1.8.0.322-2",
```

### ある日、肝心なVSCodeデバッグ機能が使えなくなる

調べると、`Lombok`のVSCode拡張機能が勝手にバージョンアップされたのが原因でした。
Lombokとは、アノテーションによってセッターやゲッター、コンストラクターなどのクラスの機能を自動生成するためのライブラリ:

https://marketplace.visualstudio.com/items?itemName=vscjava.vscode-lombok

Spring BootプロジェクトではLombokを使ってアノテーションを付加していましたが、
LombokバージョンがVSCode拡張機能と一致しないためデバッグが機能しなくなっていました。

プロジェクトにLombokの新バージョンを指定し、デバッグはできるようにはなりましたが、
余計な調査に時間がかかってしまい、開発スケジュールが遅れることに。

VSCode拡張機能を古いバージョンのまま使用し続けるリスクを痛感しました。

### 暫定策として、VSCodeはJDK11を、プロジェクトはJDK8を使用してみる

VSCode拡張機能は最新版を使いたいので、VSCode側のみJDK11を使用してみることに。
根拠としたのは、`redhat-developer`の`vscode-java`の下記issue:

https://github.com/redhat-developer/vscode-java/issues/1543#issuecomment-663382692

VScodeの`settings.json`例:
```
    "java.jdk.ls.java.home": "C:\\Program Files\\Amazon Corretto\\jdk11.0.16_9",
    "java.configuration.runtimes": [
        {
            "default": true,
            "name": "JavaSE-1.8",
            "path": "C:\\Program Files\\RedHat\\java-1.8.0-openjdk-1.8.0.322-2"
        },
    ],
    "spring-boot.ls.java.home": "C:\\Program Files\\RedHat\\java-1.8.0-openjdk-1.8.0.322-2",
```

その結果、VSCode拡張機能とプロジェクトのSpring Bootバージョンが一致せず、
VSCodeのデバッグ機能が使用できないことが判明し、あえなく却下されました。

### 結局は、プロジェクト側もJDK11にバージョンアップすることに

Java8からJava11への移行方法は、Oracleマニュアルを参考にしました:

https://docs.oracle.com/en/java/javase/11/migrate/index.html#JSMIG-GUID-7744EF96-5899-4FB2-B34E-86D49B2E89B6

Javaプロジェクトは、ほぼpom.xmlの修正のみでJava8からJava11に移行できました。
VSCode開発環境は、拡張機能をすべて最新版に更新でき、デバッグも正常機能できました。

#### Spring Bootプロジェクトのpom.xmlの修正箇所(ご参考まで)

`spring-boot-starter-parent`のバージョンを`2.3.4.RELEASE`に変更
```
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.3.4.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>
```

`java.version`を`11`に変更
```
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>11</java.version>
		<jjwt.version>0.9.0</jjwt.version>
	</properties>
```

`dependencies`に以下を追加
```
		<dependency>
			<groupId>org.javassist</groupId>
			<artifactId>javassist</artifactId>
			<version>3.23.1-GA</version>
		</dependency>
		<dependency>
			<groupId>cglib</groupId>
			<artifactId>cglib-nodep</artifactId>
			<version>3.3.0</version>
		</dependency>
		<dependency>
			<groupId>javax.annotation</groupId>
			<artifactId>javax.annotation-api</artifactId>
			<version>1.3.2</version>
		</dependency>
		<dependency>
			<groupId>javax.xml.bind</groupId>
			<artifactId>jaxb-api</artifactId>
			<version>2.4.0-b180725.0427</version>
		</dependency>
		<dependency>
			<groupId>javax.validation</groupId>
			<artifactId>validation-api</artifactId>
			<version>2.0.0.Final</version>
		</dependency>
```

`plugins`に以下を追加
```
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.8.0</version>
				<configuration>
					<release>11</release>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-surefire-plugin</artifactId>
				<version>2.22.0</version>
				<configuration>
					<argLine>
						--illegal-access=permit
					</argLine>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-failsafe-plugin</artifactId>
				<version>2.22.0</version>
				<configuration>
					<argLine>
						--illegal-access=permit
					</argLine>
				</configuration>
			</plugin>
			<plugin>
```

### おわりに

VSCode開発環境でJavaプロジェクトをJava8からJava11に移行した話でした。
レガシーシステムのJava移行を検討されている方の一助になれば幸いです。