【Java環境構築】Windows+Scoop+VSCode で開発環境を構築する

ここ数年は Java の IDE として IntelliJ IDEA を使ってきましたが、近年 VSCode の Java 開発体験も順調に向上していると耳に入っていて、どんなものか触ってみたくなった。
ついでに環境構築手順も残しておこうと思い、投稿に至った記事です。

# 前提条件

Windows 10 Pro 22H2
※ Win 10 or 11 であれば OK

# 環境構築の方針

1. JDK のインストールは最新の LTS を Scoop でインストールする
1. WSL や Docker は使わず、Windows OS のローカル環境に JDK を置く
1. Maven にて簡単なコマンドラインアプリを jar でビルドする
1. JUnit のテストコードからエディタ上でデバッガのステップ実行ができる
1. 上記 1~4 の方針に沿う限り、 [VSCode 公式ドキュメント](https://code.visualstudio.com/docs/java/java-tutorial) の内容に準拠する

# VSCode のインストール

VSCode 公式では「Coding Pack for Java」というインストーラーが提供されており、これを使えば VSCode + JDK + Java 開発に必要な拡張機能群を一括でセットアップできます。
ただ、今回は Scoop でインストールした JDK を管理したいので、個別でインストールすることにします。

ということで、 PowerShell を起動して以下のコマンドを実行。

```powershell:VSCode のインストール
winget install Microsoft.VisualStudioCode
```

:::note info
VSCode を Scoop でインストールしない理由は、VSCode 自身で自動更新の機能を持っているためです。
Scoop でインストールしたアプリは `scoop update` で更新したいので、そういったアプリ（他にもブラウザとか Windows Terminal とか）は Scoop ではインストールせず、 winget でインストールすることにしています。[^1]
[^1]: winget と scoop の使い分けする背景については[別記事](https://qiita.com/nimzo6689/items/ff83da73f8ddef6b3087)に書きました。
:::

# JDK のインストール

では、 Scoop を使ってインストールしていきます。
以下、Scoop 全然使ったことない人向けの Scoop セットアップ手順です。

と言っても、[公式](https://scoop.sh/)のトップページに２行で記載されているコマンドを PowerShell で実行するだけです。

```powershell:Scoop未設定の方向け
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Invoke-RestMethod -Uri https://get.scoop.sh | Invoke-Expression
```

では、 JDK をインストールします。
JDK は様々なディストリビューションがありますが、ここでは Eclipse Temurin JDK をインストールします。
Scoop 公式のトップページにて「temurin 21」で検索すると出てきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114728/3b858795-1849-df5a-95f0-d42cb06ead37.png)

Temurin JDK は無償で商用利用でき、かつ、 LTS として長期サポート版があり、 Eclipse Foundation からの提供というネームバリューの高さがあって、人気な JDK です。

```powershell:Temurin JDK LTS のインストール
scoop bucket add java
scoop install java/temurin21-jdk

# Scoop であれば、コンソールの再起動は不要で PATH が自動で通ります！
java -version
#=> openjdk version "21.0.5" 2024-10-15 LTS
#=> ...

# JAVA_HOME 環境変数も自動で登録されます。
# scoop update temurin21-jdk で更新してもこの JAVA_HOME のパスは変わりません！
$env:JAVA_HOME
#=> C:\Users\nimzo6689\scoop\apps\temurin21-jdk\current
```

Scoop でインストールすると、 JAVA_HOME 環境変数の追加や bin ディレクトリに PATH を通す作業も自動で行ってくれます。

こういうパッケージ管理ツールで JDK をインストールすると、本当に最新版がインストールされているのか気になるかもですが、 Scoop の java/\* で管理されているアプリは毎日 4 時(UTC なので、日本時間では 13 時)に最新版がインストールされるよう、マニフェストファイルの更新をしているので、あまり心配はないです。

# Maven のインストール

Maven も同様に Scoop でインストールします。

```powershell
scoop install main/maven

mvn --version
#=> Apache Maven 3.9.9 ...
```

Gradle 派の方は `scoop install gradle` で同様にインストールできます。
正直好みの問題ですが、 Android のアプリ開発とは違い、バッグエンド側はまだまだ Maven が主流なので、Maven を使う前提で進めます。

# VSCode 拡張機能のインストール

続いて、 Java 開発に必要な拡張機能をインストールします。
一番オーソドックスなのは「Extension Pack for Java」という Microsoft 社が提供しているいくつかの拡張機能をまとめた Extension Pack で一括インストールすることだと思うので、これを使います。

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

各拡張機能の役割は以下です。
詳細な使い方については公式ページに GIF 動画付きで載っているので、そちらをご参照ください。

**Language Support for Java™ by Red Hat**

コードナビゲーションや補完入力、リファクタリング、コードスニペットの機能を提供。

https://code.visualstudio.com/docs/java/java-editing

https://code.visualstudio.com/docs/java/java-refactoring

**Debugger for Java**

IDE でよくあるデバッガーの機能を提供しています。

https://code.visualstudio.com/docs/java/java-debugging

**Test Runner for Java**

JUnit のコードをエディタから起動できます。テスト結果の確認にも便利です。

https://code.visualstudio.com/docs/java/java-testing

**Maven for Java**

Maven アーキテクチャのディレクトリ構成に沿ったひな形を生成できます。
また、 clean, test, package などの mvn コマンドもエディタから実行可能です。

https://code.visualstudio.com/docs/java/java-build

**Gradle for Java**

＜未使用なので割愛＞

**Project Manager for Java**

Java プロジェクト専用のファイルエクスプローラーが利用できます。
要するに 他の Java IDE と同じような表示が VSCode でできるということ。

https://code.visualstudio.com/docs/java/java-project

**Visual Studio IntelliCode**

いわゆる AI アシスタントです。
今は GitHub Copilot が主流ですが、それより前に導入されていた Microsoft 製の AI アシスタントです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114728/f33d7532-dcc4-e7cf-c7de-20eaee7c3128.png)

IntelliCode は Ctrl + Space キーで起動でき、表示される補完候補の中で星マーク（★）が付いているものが AI による推奨項目です。コードの文脈を理解して適切な候補を提示してくれます。
現在は GitHub Copilot のような高度な AI 支援ツールが主流となっていますが、セキュリティポリシーなどの理由で Copilot が使用できない環境も存在するため、そういったツールが使用できない人たちの救いにはまだまだなりそうです。

ちなみに、星マークが付いていない候補は最初に紹介した「Language Support for Java™ by Red Hat」が提供している機能で IntelliSense と呼ばれており、こちらは静的解析によって候補を表示しています。

# Maven プロジェクトの作成

Maven のディレクトリ構成に沿って、プロジェクトのひな形を作成します。
その前に VSCode をフォルダで開いていない方はフォルダで開く必要があります。Java に限った話ではないですが、VSCode で LSP 動かすとき、フォルダを開かないと機能しないですよね。

フォルダで開けたら、 Command Palette (Ctrl+Shift+P) にて、「Java: Create Java Project」とタイプし、 Enter をして実行します。

project type を聞かれるので、 Maven を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114728/264824dd-f892-ebe6-f7d4-172d5424ddef.png)

次は、archetype を聞かれるので、「No Archetype」を選択します。
その後、 project の groupId と artifactId は自由に決めて大丈夫です。この記事ではデフォルトの「com.example」と「demo」のままとしました。
Destination Folder は開いているフォルダのままとしています。

これで Maven のプロジェクトのひな形が作成できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114728/6f513c10-fc5a-a4a6-47e8-bfe04c068308.png)

:::note info
ここで注意したいのは、 Destination Folder が仮に `~/repos/java-projects` だった場合、**開かれるフォルダは java-projects で、その配下に demo（artifactId で指定したもの）フォルダが新規で作成されます**。おそらく、Destination Folder 配下に複数の Maven プロジェクトが配置されることを見込みしてこういう仕様にしている気がします。（pom.xml は細かく分けろというメッセージ性を感じる）

そのため、単純に単一の pom プロジェクトしか作成したくない、かつ、 src フォルダはプロジェクトの直下に置きたい、という場合は、作成した demo フォルダで開き直す必要があります。
:::

また、上の画像はエクスプローラービューに標準で表示されるファイルツリービューですが、「JAVA PROJECTS」というファイルツリービューも利用できます。Java 開発時はこちらの方が便利です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114728/27641090-17be-5433-a100-a2a3ea9a672b.png)

ただ、上記の画像にある通り、使用している Java のバージョンが「JRE System Library [JavaSE-17]」になっているので、こちらを 21 に切り替えます。

pom.xml を開いて、`maven.compiler.source` と `maven.compiler.target` の値を 17 から 21 に変更して保存すれば OK です。

```diff_xml:pom.xml
    <properties>
+        <maven.compiler.source>21</maven.compiler.source>
+        <maven.compiler.target>21</maven.compiler.target>
    </properties>
```

保存すると以下のメッセージが VSCode から出るので、 Yes か Always を選択します。すると Java のバージョンが「JRE System Library [JavaSE-21]」に切り替わったことが確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114728/38ce041c-6c33-539b-e428-02601010e15c.png)

Java プログラムを実行するときは、 main メソッドの上にコードレンズで `Run|Debug` と表示されるので、その Run をクリックすればターミナルが自動で起動して java コマンドで実行してもらえます。

以下のように、Hello, World! とコンソールに出力されることが確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114728/ed3517c0-46e6-47df-3808-7e103e44a34e.png)

# デバッガでステップ実行

ブレークポイントを貼って、「F5」でデバッグ実行できます。
main メソッドであれば、メソッド上の `Run|Debug` からでも実行可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114728/d94933b6-31c5-dfb9-43f2-c3c00e5fa2b7.png)

# JUnit コードの実行

ひな形で生成されている tests パッケージ配下の JUnit コードも、エディタから実行できます。
まず、 JUnit5 を pom.xml に追加します。

```diff_xml:pom.xml
    </properties>

+    <dependencies>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter</artifactId>
+            <version>5.10.1</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
</project>
```

次にテスト対象となる Calculator.java とテストコードを実装する CalculatorTest.java を作成します。

```java:Calculator.java
package com.example;

public class Calculator {
    public int divide(int dividend, int divisor) {
        if (divisor == 0) {
            throw new IllegalArgumentException("割る数に0は利用できません。");
        }
        return dividend / divisor;
    }
}
```

```java:CalculatorTest.java
package com.example;

import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;

class CalculatorTest {
    private final Calculator calculator = new Calculator();

    @Test
    void 割り切れる数で商が計算できる() {
        assertEquals(4, calculator.divide(12, 3));
    }

    @Test
    void 割り切れない数で商が計算できる() {
        assertEquals(2, calculator.divide(12, 5));
    }

}
```

テストコードを実行するときはコードエディタの左側に表示されているチェックマークからクラス単位やメソッド単位で実行できます。
テスト結果は Testing ビューが見やすいです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114728/fc932190-efa9-8cbd-9cf3-0b82278f8ec4.png)

# jar ファイルのビルド

Maven で jar ファイルのビルドをする際も、 GUI で可能です。
まず、pom.xml に jar ファイルを出力するためのプラグインを追加します。

```diff_xml:pom.xml
    </dependencies>

+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <version>3.4.2</version>
+                <configuration>
+                    <archive>
+                        <manifest>
+                            <mainClass>com.example.Main</mainClass>
+                            <addClasspath>true</addClasspath>
+                        </manifest>
+                    </archive>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
</project>
```

ナビゲーションバーのエクスプローラービューにて、「Maven Projects」が表示されているので、そこから package を実行すれば target ディレクトリ内に jar ファイルが生成されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114728/d8a51c93-ab2f-ef7d-9cfe-98e67d219429.png)

生成された jar ファイルを `java -jar` コマンドで実行すると、Hello world! が出力されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114728/95829d3e-e0a3-4ce7-6a60-d91ad24aae41.png)