最近はTypescriptの住人と化していますが、
新しい勉強としてデザインパーンの本を購入してサンプルを再現しようとしたところ、サンプルは全てjavaコードでした。
思ったのですが、Typescriptで言うところのnpmに相当するものってJavaだと何があるんでしょうか?
ぱっと見た感じではGradle
というのが最近のツールのように見えます。
また、nodeで言うところのnvmのように、
ローカルPCの環境に影響されずにjavaのバージョンを切り替えることは可能でしょうか?
nvm的なものは見当たりませんが、dockerのコンテナを使い分けることで同じことができそうです。
今回は以下の環境構築をゴールに解説していきます。
- dockerコンテナ上でjavaをコンパイルして実行できる
- gradleの設定にコンパイル設定を記述、シンプルなコマンドでビルドが完了するように
ディレクトリ構造
完成状態のディレクトリ構造を抜粋して先に載せておきます。
これらの各種コンポーネントについて解説していきます。
1 | docker/ |
環境作成
やるべきことは大まかには以下の通りです。
順番に作業していきます。
- dockerイメージの作成
- docker-composeの設定
- gradleの初期化
dockerコンテナ設定
今回はAdoptOpenJDK11を実行環境として採用します。
JDKの種類については以前の記事でも解説しています。
https://blog.oskn259.com/article/how_to_choose_jdk
本当はver17が良かったのですが、dockerイメージがまだ公開されていないようでした。
adoptopenjdk/openjdk11
こちらのイメージをベースにDockerfileを記述します。
1 | FROM adoptopenjdk/openjdk11 |
javaに関してはベースのイメージで完結しているので、追加の設定は必要ありません。
ベースのイメージに、gradleのインストール処理を加えています。
(Dockerfileは不慣れなのでもっと綺麗に書けるかもしれません)
Gradleのインストールは公式チュートリアルにある通り、
sdkmanを使用する形を採用しました。
sdkmanは開発に関わるツールのバージョン切り替えなどをしてくれるツールのようです。
docker-composeの設定
今回の開発環境ではdockerコンテナ内部での実行を考えていますが、
コードの編集はローカルPCでエディタを使ったほうが効率が良いです。
つまり、ローカルPCにあるコードをdockerコンテナ内部のディレクトリと同期させてやる必要があります。
このことは、以下のような指定でdockerコマンドを実行すれば実現できます。
1 | $ docker run -v <ローカルPC側のディレクトリ>:<コンテナ内部のディレクトリ> image-name /bin/bash |
このような指定により、両者のディレクトリの内容が同期され、一方の変更がもう一方に反映されるようになります。
毎回このコマンドを実行するのも面倒なので、docker-compose
の設定ファイルとしてまとめてしまいましょう。
今回作成したdocker-compose.yml
はこちら。
1 | version: '3.6' |
volumes
の箇所で、同期させるディレクトリを指定しています。
これにより、ローカルPCの作業ディレクトリが、コンテナ上の/usr/project
ディレクトリと同期します。
作成した設定を使用して、dokcerコンテナを起動しましょう。
1 | $ docker-compose create |
Gradleの初期設定
https://docs.gradle.org/current/samples/sample_building_java_applications.html
こちらの公式チュートリアル(ver 7.2)をもとに進めていきます。
Javaに限らずscalaなどの他言語や、ライブラリのビルドなど様々なオプションに向けたドキュメントがありますが、
今回はjava applicationの項目を選択してます。
まずはコンテナに入ります。docker exec
でログインした先は作業ディレクトリなので、
ここでgradle init
を実行します。
するといくつか質問されるので、チュートリアルに倣って入力しましょう。
1 | $ docker exec -i -t designpattern_java_1 bash |
gradle initの出力(展開)
1 | root@b4abb718cdc0:/usr/project# gradle init |
今回は、設定ファイルの言語としてKotlinを選択しています。
開発環境の使い方
以上の手順で準備は完了しました!
次はコードの実行や編集など、この開発環境をどのようにして使用するかを見ていきます。
開発環境の起動
以下のコマンドでdockerコンテナを起動しましょう。
作成手順においても起動の手順があるので、そこで起動されていればここはスキップできます。
1 | $ docker-compose create |
コードの実行
gradle init
で作成されたgradlew
にサブコマンドとしてrun
を渡すことでコードを実行できます。
これはコンテナ内部で実行することになるので、docker exec
コマンド経由で実行しましょう。
runの出力(展開)
初期状態では単にHello World!
と表示するコードが生成されますが、正しく動いていることが確認できます。
1 | oskn259@localpc$ docker exec -i -t designpattern_java_1 ./gradlew run |
また、配布用のビルド成果物が欲しい場合にはbuild
サブコマンドを実行すればapp/build/distributions
に圧縮ファイルが生成されます。
buildの出力(展開)
1 | oskn259@localpc$ docker exec -i -t designpattern_java_1 ./gradlew build |
ソースコードの編集
ここまでの設定で、app/src/main/java/designpattern/App.java
にjavaのmainメソッドが配置されます。
コーディングはここのディレクトリを起点に記述していくことになるでしょう。
ローカルPC側から編集できるので、vscodeで開発を進めていくことができます。
開発環境の停止
コンテナがVMに比べて軽いとはいえ、PCの負荷的にいつでも動かしていたいものではありません。
必要ない時は以下のコマンドで停止しましょう。
1 | $ docker-compose stop # 単にコンテナを停止する |
まとめ
今回はdockerコンテナを使用することで、
- javaのビルドをシンプルなコマンドで実行
- javaバージョンを作業環境に依存せず変更可能
- gradleバージョンについても同様に変更可能
という開発環境を作成しました。
簡単なアプリケーション作成はこの環境で十分賄えそうです。
実際のサービス開発においては、gradle build --scan
のような便利機能や、テストの実行についても設定を追加していくのが良さそうですね。