新卒1年目、現場に入ってすぐのこと・・・
先輩 :「この手順書をみて環境構築してください」
わたし:「はい!」
わたし:JRE?Maven?なんかエラーがたくさん出るけど・・・なんとか手順書通りに進めたら成功したぞ!よかった〜
END.
......というような感じで、環境構築で使用しているコマンドや手順の意味を理解せずに進めてしまっていました。
「初めはわからなくて大丈夫だよ」という言葉に甘えて、ふわふわしたまま四年が過ぎてしまいました......。
しかし、Javaに触れる現場では何度も目にする単語ーーJDK、JRE、JVM。どれも「Javaっぽい名前」なので、頭の中が混乱してくる🌀
今回は、まずJavaのプログラムがどうやって動くのかから、順番に整理して復習していきます。
Javaのプログラムは、どうやって動いているのか
Javaに限らず、プログラムというものは書いたそのままでは動きません。必ず「翻訳」の工程を通ります。
Javaの場合は、次の三段階で実行されます。
①.java(人間が書く)
↓ javac
②.class(バイトコード)
↓ JVM
③機械語(CPUが実行できる命令)
①人間が書くプログラム(.java)
.java は、人間が読み書きしやすいように作られた言語です。
if や for、クラスやメソッドといった構文は、人が理解できるかどうかを優先して作られています。
でも、コンピュータはこのままでは実行できません。
なぜなら、CPUは人の言葉を理解できないからです。
②バイトコードに変換される(.class)
そこで登場するのが Javaの特徴の一つである「バイトコード」です。
発者が記述した.javaファイルを、「Javaコンパイラ」である javac(Java Compiler)というツールが読み込み、「バイトコード」が書き込まれた.classファイルに変換します。
バイトコードは、特定のCPUに依存せず、JVM(Java仮想マシン)が理解できるように書かれた命令セットです。
バイトコードは人間とCPUの間を橋渡しするような仲介役なのです。
③実行時に機械語へ変換される
最終的にプログラムを実行するのはCPUです。 CPUが理解できるのは機械語だけです。
Javaでは、バイトコードをそのままCPUに渡すのではなく、 JVM (Java仮想マシン)が実行時に、その環境に合った機械語へ翻訳しながら実行します。
これがJavaの大きな特徴です。
***
まずはバイトコードという共通の形にしておき、それぞれの環境にあるJVMが翻訳して実行する。
これによって、Javaの基本理念である「Write Once, Run Anywhere.(一度書けば、どこでも動く)」を実現できるというわけです。
Windowsで作った .class が、macOSやLinuxでも動くのは、
この仕組みを前提に設計されているからです。
JDK / JRE / JVM の関係
この三つは密接に関わりあっています。
JVM(Java Virtual Machine)はプログラムを実行するための仮想マシンです。
JDK(Java Development Kit)は、開発に必要なキット一式で、JREもこの中に含まれています。
JRE(Java Runtime Environment)は、Javaで作られたアプリを動かすために必要な実行環境です。
ベン図にするとこんな感じ。
ビルドについて
つづいてビルドについて解説します。
ビルドというのは、
- ソースをコンパイルする
- テストを動かす
- 必要なライブラリを集める
- 配布できる形にまとめる
こうした作業をまとめて行うこと全体を指します。
Ant、Maven、Gradleといったビルドツールは、
この流れを自動でやってくれる道具です。
Ant / Maven / Gradle の違い
Ant(Apache Ant)
Antは、最も古くから存在するビルドツール。特徴: 手続き型。
設定ファイル(build.xml)に、どのタスクをどの順番で実行するかを詳細に記述します。
メリット
・自由度が高いゼロからビルド手順を細かく定義できるため、特殊なビルド処理や独自のタスクを組み込みやすい。
デメリット
・冗長になりがち単純なコンパイルやテストでも、XMLで全ての手順を書く必要があり、ファイルが膨大になりやすい。
・依存関係の管理が手動
外部ライブラリ(jarファイル)のダウンロードや配置を開発者が手動で行う必要がありました。
Maven(Apache Maven)
Mavenは、Antの反省点から生まれたビルドツール。特徴: 規約ベース。プロジェクトのフォルダ構成やビルドのライフサイクル(コンパイル→テスト→パッケージングなど)があらかじめ決まっています。
メリット:
・シンプルpom.xmlに記述するのは、主にプロジェクト情報と外部ライブラリの依存関係だけで済むため、ファイルが簡潔になる。
・依存関係の自動管理
外部のリポジトリ(Maven Centralなど)からライブラリを自動でダウンロードし、管理する仕組みを作りました。
・一貫性
規約に従うので、どのMavenプロジェクトでも同じ構造になり、他の人が参加しやすい。
デメリット:
・柔軟性が低い規約から外れた複雑なビルド処理や、特殊なタスクの組み込みが難しい(プラグインに依存する)。
・ビルドが遅いことがある
変更がないモジュールでも再ビルドする傾向があり、ビルド時間が長くなりがち。
Gradle
Gradleは、AntとMavenの長所を取り入れて誕生した新しいビルドツール。特徴:コードベース。
設定ファイル(build.gradle)をXMLではなく、GroovyやKotlinというプログラミング言語で記述します。これにより、柔軟性と簡潔さを両立しています。
メリット:
・高い柔軟性
プログラミング言語で記述するため、複雑なビルドロジックやカスタムタスクを簡単に組み込めます(Antの良さを踏襲)。
・高速なビルド
変更された部分だけを再ビルドするインクリメンタルビルドや、ビルドキャッシュの仕組みがあり、高速です(Mavenの弱点を克服)。
・依存関係の管理
Mavenと同じく自動管理できますが、さらに柔軟な制御が可能です。
デメリット:
・学習コスト
GroovyやKotlinというDSL(ドメイン固有言語)を学ぶ必要があり、XMLベースのMavenよりは導入ハードルが少し高い。
まとめ
Javaが実行されるまでの過程についてまとめました。
新卒1年目から一連の知識を理解するのは早いと思いますが、Javaを理解してきたころにもっと勉強しておけばよかったな〜と思う場面はちょこちょこありました。(ビルドのことよくわからずにとりあえずでGradleリフレッシュしたり・・・)
これまでなんとなくで使っていたツールの理解が深まれば幸いです。


