VS Code の Remote Containers で Java 12 開発環境を構築

以前 VS Code の Remote Development を試した時は VirtualBox の仮想マシンをターゲットに環境を作りました。

blog.kondoumh.com

Remote Development では Docker コンテナもターゲットマシンに使えます (Remote - Containers) 。

marketplace.visualstudio.com

特定の言語・フレームワークをインストールしたコンテナイメージを用意しておけば、面倒な環境構築をスキップして開発を開始できます。

前から気になっていた VS Code の Java 拡張の使い勝手も知りたいと思い、Java 12 環境を Docker - Containers で作ってみました。Docker Desktop for macOS を使用しています。

Java 環境用のフォルダを作成し、VS Code で開きます。

コマンドパレットで、Remote-Containers: Add Development Container Configuration Files を選択

f:id:kondoumh:20190921173515p:plain

選択メニューから Java 12 openjdk:12-jdk を選択

f:id:kondoumh:20190921173539p:plain

.devcontainer というフォルダが作成され、設定の JSON ファイルや Dockerfile が生成されます。ポップアップの Reopen in Container をクリック。

f:id:kondoumh:20190921173607p:plain

コンテナのビルドが始まります。

f:id:kondoumh:20190921173647p:plain

コンテナが起動されると、接続状態になります。

f:id:kondoumh:20190921173831p:plain

この状態で docker ps するとコンテナが起動していました。

$ docker ps
CONTAINER ID        IMAGE                                       COMMAND                  CREATED              STATUS              PORTS               NAMES
347c4633b941        vsc-java-a10e83bc1108453baed86ae69c6ee569   "/bin/sh -c 'echo Co…"   About a minute ago   Up About a minute                       ad

.devcontainer が配置されるフォルダはホストマシンにボリュームマウントされていますので、コンテナが破棄された後もファイルは残ります。

VS Code のターミナルを開いて、Java のバージョン情報や OS の情報を見てみます。

f:id:kondoumh:20190921180541p:plain

ちゃんと openjdk 12.0.2 がインストールされていて、OS は Oracle Linux Server 7.6 であることがわかります*1

コンテナ側にインストールされた Extension を確認すると、Java Extension Pack と Maven for Java はインストール済みになっていました。

f:id:kondoumh:20190921211358p:plain

フォルダを追加してコマンドパレットから Java: Create Java Project を実行します。

f:id:kondoumh:20190922001327p:plain

追加したフォルダを選択して OK を押します。

f:id:kondoumh:20190922001522p:plain

プロジェクト名を入れて Enter を打つと別ウィンドウが起動して、Java プロジェクトを開きます。このウィンドウもコンテナにアタッチされています。コンソールアプリなので、main 関数の上に表示されている Run をクリックすると実行されます。

f:id:kondoumh:20190922002139p:plain

ブレークポイントを追加して、Debug をクリックするとデバッグモードで実行しデバッグが可能です。

f:id:kondoumh:20190922002434p:plain

コード書いてみると補間はばっちり。import も自動追加されたりします。

f:id:kondoumh:20190922002737p:plain

ひとまず、Java 12 環境を作ってコードを書き始めることができました。

次は Spring Boot のプロジェクトを作ってみます。

コンテナには Maven CLI はインストールされていないようです。Dockerfile を見ると Maven や Gradle をインストールするスクリプトがコメントアウトされています。有効化してイメージをリビルドします。

f:id:kondoumh:20190921205804p:plain

コンテナが再起動され使えるようになりました。

f:id:kondoumh:20190921210550p:plain

コマンドパレットから Maven: Create Maven Project を実行します。

f:id:kondoumh:20190922004326p:plain

maven-archetype-quickstart を選択して、バージョンを選択

f:id:kondoumh:20190922005744p:plain

先ほどのフォルダを選択します。

f:id:kondoumh:20190922010105p:plain

archetype の処理が流れて groupId, artifactId などのプロンプトが出るので適当に入力していくとプロジェクトが作成されます。

f:id:kondoumh:20190922010153p:plain

生成されたプロジェクトの pom.xml を編集して、Spring Boot 用の設定をします。

  :
  <name>hello-springboot</name>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.8.RELEASE</version>
  </parent>
  :
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    :

src/main/java/hello/App.java を編集してエンドポイントを追加、Boot アプリのエントリーポイントを追加します。

package hello;

import java.net.http.HttpRequest;

import org.springframework.boot.*;
import org.springframework.boot.autoconfigure.*;
import org.springframework.web.bind.annotation.*;

@RestController
@EnableAutoConfiguration
public class App 
{
    @RequestMapping(value = "/{name}", method = RequestMethod.GET)
    String hello(@PathVariable("name") String name) {
        return "Hello World! " + name + "\n";
    }

    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}

ターミナルを分割し、片方で mvn spring-boot:run でアプリを起動、片方で curl でエントリーポイントにリクエストを送ってみます。

f:id:kondoumh:20190922012852p:plain

無事にレスポンスが取得できました。

実行しているコンテナは、VS Code のウィドウを閉じると破棄されます。

コンテナには vscode という non-root ユーザーも登録されていて、devcontainer.json の runArgs のコメントを解除すれば、vscode ユーザーで利用することも可能です。

{
    "name": "Java 12",
    "dockerFile": "Dockerfile",
          :
    "runArgs": [ "-u", "vscode" ],
          :
}

コンテナの設定については、公式ドキュメントが充実しています。

code.visualstudio.com

以上、Remote Containers の Java 開発環境、使い勝手としては IntelliJ IDEA や Eclipse に劣らない感じで、軽快な動作が素晴らしいです。Java 専用 IDE で便利プラグインを多用していると物足りないかもしれませんが。

コンテナを使うと開発準備も楽ですし、Dockerfile を配布すればメンバーの環境も統一できます。複数バージョンの JDK 混在させて切替えたりしなくてもよくなりますね。VS Code がコンテナの管理をかなり賢くやってくれるのが素敵です。

先日 .NET Core を試した時は、ローカル環境に .NET Core SDK をインストールしていました。

blog.kondoumh.com

これも C# (.NET Core) の Dev Container Configuration が提供されているのでこちらを使った方が手軽でした。

*1:RHEL 7.6 ベースです