Docker、Gradleを使用したJavaの開発環境の構築について

# 初めに
本記事は以下のものを参考にしています。

https://blog.oskn259.com/article/docker_container_gradele

# 目的
Docker、Gradleを使用したJavaの開発環境の構築を行います。

# 事前準備
本記事では、VSCodeとDockerを事前にインストール必要があるのでインストールをしてください。
以下からそれぞれインストールを行ってください。

https://code.visualstudio.com/download

https://matsuand.github.io/docs.docker.jp.onthefly/get-docker/

# 使用環境
```:# 使用環境
VSCode
Docker
Java11
Gradle7
```

# 環境構築手順
環境構築手順は、以下の手順で行います。
```:# 環境構築手順
手順1 : 開発環境の構築
手順2 : Gradleでプロジェクトの作成
手順3 : デバッグを行えるようにする。
```
# 手順1 : 開発環境の構築
手順1では以下のことを行います。
```:# 手順1で行うこと
(1) 最低限のファイル・フォルダを作成
(2) Dockerfileの作成
(3) docker-compose.ymlの作成
(4) Dockerイメージの作成・コンテナの起動
```
## (1) 最低限のファイル・フォルダを作成
以下のshを任意の場所で実行してください。
```: init.sh
#!/bin/bash
echo -n "任意のプロジェクト名を入力してください:"

read PROJECTNAME

mkdir $PROJECTNAME

touch $PROJECTNAME/Dockerfile

touch $PROJECTNAME/docker-compose.yml

#devcontainer関連を作成
mkdir $PROJECTNAME/.devcontainer

touch $PROJECTNAME/.devcontainer/devcontainer.json

mkdir $PROJECTNAME/src

#VSCodeを起動
cd $PROJECTNAME
code .
```
本記事では、プロジェクト名を「Java_App」で作成しています。
以下のようなファイル・フォルダが作成されるはずです。
![スクリーンショット 2022-05-23 22.14.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2663952/17a9f44a-6cc9-3ec8-c5b5-684deb8d16ce.png)

## (2) Dockerfileの作成
Dockerfileを以下のように修正してください。(コピペでOK)
```:./Dockerfile
FROM adoptopenjdk/openjdk11

RUN apt-get update
RUN apt-get -y install curl
RUN apt-get -y install zip
RUN curl -s "https://get.sdkman.io" | bash
RUN echo ". $HOME/.sdkman/bin/sdkman-init.sh; sdk install gradle" | bash
WORKDIR /java_project/
```
## (3) docker-compose.ymlの作成
docker-compose.ymlを以下のように修正してください。(コピペでOK)
```:./docker-compose.yml
version: '3.6'
services:
  java:
    container_name: java
    build: ./
    tty: true
    volumes:
      - ./src:/java_project/
```
## (4) Dockerイメージの作成・コンテナの起動
```:# 実行コマンド
docker-compose build
docker-compose up -d
```

## (5) 動作確認
まずはJavaが正常にインストールされているか確認しましょう。以下のコマンドを実行してください。
```:# 実行コマンド
java --veriosn
```
以下のようなメッセージが表示されたら成功です。
```:# Javaのバージョン確認
openjdk 11.0.15 2022-04-19
OpenJDK Runtime Environment Temurin-11.0.15+10 (build 11.0.15+10)
OpenJDK 64-Bit Server VM Temurin-11.0.15+10 (build 11.0.15+10, mixed mode)
```
まずはGradleが正常にインストールされているか確認しましょう。以下のコマンドを実行してください。
```:# 実行コマンド
gradle -v
```
以下のようなメッセージが表示されたら成功です。
```:# Gradleのバージョン確認
------------------------------------------------------------
Gradle 7.4.2
------------------------------------------------------------

Build time:   2022-03-31 15:25:29 UTC
Revision:     540473b8118064efcc264694cbcaa4b677f61041

Kotlin:       1.5.31
Groovy:       3.0.9
Ant:          Apache Ant(TM) version 1.10.11 compiled on July 10 2021
JVM:          11.0.15 (Eclipse Adoptium 11.0.15+10)
OS:           Linux 5.10.76-linuxkit amd64

```
手順1はここまでです。お疲れ様です。

# 手順2 : Gradleでプロジェクトの作成
```:# 手順2で行うこと
(1) Gradleプロジェクトの作成
(2) 動作確認
```
## (1) Gradleプロジェクトの作成
アプリを開発するためにGradleプロジェクトの作成を行いましょう。
```:# 実行コマンド
gradle init
```
順に、「2 => 3 => 1 => 1 => no =>[何も入力せずにEnter] => appを入力」 の順番です。
```:gradle init時の選択内容
Select type of project to generate:
  1: basic
  2: application
  3: library
  4: Gradle plugin
Enter selection (default: basic) [1..4] 2

Select implementation language:
  1: C++
  2: Groovy
  3: Java
  4: Kotlin
  5: Scala
  6: Swift
Enter selection (default: Java) [1..6] 3

Split functionality across multiple subprojects?:
  1: no - only one application project
  2: yes - application and library projects
Enter selection (default: no - only one application project) [1..2] 1

Select build script DSL:
  1: Groovy
  2: Kotlin
Enter selection (default: Groovy) [1..2] 1

Generate build using new APIs and behavior (some features may change in the next minor release)? (default: no) [yes, no] no

Select test framework:
  1: JUnit 4
  2: TestNG
  3: Spock
  4: JUnit Jupiter
Enter selection (default: JUnit Jupiter) [1..4] 1

Project name (default: java_project): [何も入力せずにEnter]
Source package (default: java_project): app

> Task :init
Get more help with your project: https://docs.gradle.org/7.4.2/samples/sample_building_java_applications.html

BUILD SUCCESSFUL in 49s
2 actionable tasks: 2 executed
```
成功すると「BUILD SUCCESSFUL」となり、以下のようにsrc直下にファイルやフォルダが作成されます。

# (2) 動作確認
「./src/app/src/main/java/app/App.java」を見ると「Hello World!」を表示するプログラムになっているので実行して動作確認します。

```:./src/app/src/main/java/app/App.java
/*
 * This Java source file was generated by the Gradle 'init' task.
 */
package app;

public class App {
    public String getGreeting() {
        return "Hello World!";
    }

    public static void main(String[] args) {
        System.out.println(new App().getGreeting());
    }
}
```
以下のコマンドを実行してください。
```:# 実行コマンド
./gradlew run
```
以下のように「Hello World!」が表示されば成功です。(初回のみ少し実行に時間がかかります)
```:# 成功時のメッセージ
Downloading https://services.gradle.org/distributions/gradle-7.4.2-bin.zip
...........10%...........20%...........30%...........40%...........50%...........60%...........70%...........80%...........90%...........100%

> Task :app:run
Hello World!

BUILD SUCCESSFUL in 4m 20s
2 actionable tasks: 2 executed
```
手順2はここまでです。お疲れ様です。

# 手順3 : デバッグを行えるようにする。
```:# 手順3で行うこと
(1) 拡張機能のインストール
(2) devcontainer.json の修正
(3) デバッグできるか確認
```
## (1) 拡張機能のインストール
コンテナ内のソースをVSCodeで参照できるように、以下の拡張機能をインストールしてください。
![スクリーンショット 2022-05-23 23.40.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2663952/713719c6-7a44-41cd-df03-05dd027dba92.png)

## (2) devcontainer.json の修正
「./.devcontainer/devcontainer.json」を以下のように修正してください。(コピペでOK)
```:./.devcontainer/devcontainer.json (Macを使用しているの場合)
{
    "name": "java_gradle",
    "workspaceFolder": "/java_project",
    "dockerComposeFile": "../docker-compose.yml",
    "settings": { 
        // Macの場合
        "terminal.integrated.defaultProfile.osx": "/bin/bash"     
    },
    "service": "java", //attachするコンテナはspringを指定
    "extensions": [
        "vscjava.vscode-java-pack", // JavaExtensionPack
        "gabrielbb.vscode-lombok" //Lombok Annotations Support For VS Code
    ]
}
```
Windows(WSL)を使用している場合は以下で問題ないかと思いますが動作確認は実施していないので間違っていたらすみません・・・。
```:./.devcontainer/devcontainer.json (Windowsを使用しているの場合)
{
    "name": "java_gradle",
    "workspaceFolder": "/java_project",
    "dockerComposeFile": "../docker-compose.yml",
    "settings": { 
        // Windows(WSL)の場合(おそらく・・・動作確認はしていません。)
        "terminal.integrated.defaultProfile.linux": "/bin/bash",        
    },
    "service": "java", //attachするコンテナはspringを指定
    "extensions": [
        "vscjava.vscode-java-pack", // JavaExtensionPack
        "gabrielbb.vscode-lombok" //Lombok Annotations Support For VS Code
    ]
}
```
## (3) デバッグできるか確認
VSCodeの左下にある 「><」をクリックしてください。
![スクリーンショット 2022-05-24 0.47.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2663952/08247ba7-e61c-56b0-c679-9a243e1a6581.png)

そして、「Reopen in Container Remote-Containers」 を選択してください。
![スクリーンショット 2022-05-24 0.48.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2663952/dbed014c-acc0-79f5-9afa-d9c9243364b4.png)

以下のようにjavaコンテナ上のGradleプロジェクト(手順2で作ったもの)を参照できているはずです。
![スクリーンショット 2022-05-24 0.51.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2663952/bb824785-9835-de94-7253-d07797d860cf.png)

※Macを使用の場合は、Remote Containerの起動に時間がかかるようです。
https://www.keisuke69.net/entry/2021/09/15/104532

VSCodeの拡張機能は以下のものがインストールされているはずです。もし、インストールされていない場合は手動でもインストールできると思います。(Remote-Container上の拡張機能)
![スクリーンショット 2022-05-24 0.41.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2663952/2b7387c3-648a-5230-65f7-0eb41d82913d.png)

8行目でブレイクポイントつけて、Run|DebugのDebugで起動してみましょう。
![スクリーンショット 2022-05-24 0.59.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2663952/a41d8be7-e6a8-4cb2-d2c9-9a4b8c377626.png)

以下のように8行目で止まれば成功です。
![スクリーンショット 2022-05-24 1.01.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2663952/2842c368-860a-8388-ca1e-3163221bc3c8.png)

開発環境の構築からDebug環境の構築まで完了です。お疲れ様です。

# 最後に
自分がつまづいたとことについて記載します。
「devcontainer.json」の"workspaceFolder","dockerComposeFile","service"は「docker-compose.yml」と同じものを指定しないとワークスペースが見つからないとなってしまいますのでご注意ください。

今回の構築したものは以下のgithubに公開しております。参考までに・・・

https://github.com/T-H9703EnAc/Java_App

ここまでご覧いただきありがとうございます。