Java とか Kotlin をやることになったら知っておきたい単語や仕組み
はじめに
「明日からきみは Java ね」って言われたとき、これくらい知っていれば大丈夫だろう内容をまとめました。
この記事は初心者エンジニアで Java 系に触れているひとのフォローアップや、Java 系以外の実務経験ならあるというひとへの読み物的なまとめです。
文法解説や設計論、ツール紹介などはありません。
項目は多いですが、ひとつひとつは軽くまとめてあります。
「必要に応じて詳細を調べられる」という入り口のところまでさくさくと紹介します。
この記事の内容を覚える必要はありませんし、最初の最初はあまり理解できなくても大丈夫です。
必要になったとき「そういえばそんなこと聞いたような」くらいに思えれば、きっと普段のお仕事や気持ちがちょっとらくになるはずです。
コンパイルと実行
暗記して自分の手でできるようになる必要はありませんが、大前提として知っておきましょう。
javac コマンドと java コマンド
.java
ファイルをコンパイルして .class
ファイルを作るのが javac
コマンドです。
.class
ファイルは java
コマンドで実行します。
試してみましょう。
次のファイルを作ります。
public class Hello {
public static void main(String[] args) {
System.out.println("Hello");
}
}
javac
コマンドでコンパイルし、java
コマンドで実行します。
$ ls
Hello.java
$ javac Hello.java # コンパイル
$ ls
Hello.class Hello.java
~~~~~~~~~~~
^ new
$ java Hello # 実行
Hello
実行できました。
.java
ファイルが複数の場合は、javac
コマンドですべての .java
ファイルを指定します。
試してみましょう。
public class Hello {
public static void main(String[] args) {
Message message = new Message();
System.out.println(message.word());
}
}
public class Message {
public String word() {
return "Hello from Message";
}
}
javac
コマンドにふたつの .java
ファイルを指定してコンパイルすると、ふたつの .class
ファイルができます。
java
コマンドで実行するのは main
文があるクラスです。
$ ls
Hello.java Message.java
$ javac Message.java Hello.java # コンパイル
$ ls
Hello.class Hello.java Message.class Message.java
~~~~~~~~~~~ ~~~~~~~~~~~~~
^ new ^ new
$ java Hello # 実行
Hello from Message
2 ファイルを実行するだけでめんどくさいので、実際の開発で javac
コマンドや java
コマンドを直接使うことはまずありません。
Gradle ( 後述 ) というビルドツールを使います。
まとめ
- ✏️
.java
ファイルをjavac
コマンドでコンパイルすると.class
ファイルになる - ✏️
.class
ファイルをはjava
コマンドで実行する - ✏️ 規模が大きくなるとやってられないので、Gradle というビルドツールを使う
JAR と WAR
配布やデプロイに関係するファイルです。
自分の手で作ったり触ったりすることはほとんどありませんが、知っておくと運用環境の構成理解やエラー時の判断がスムーズになります。
JAR ( Java Archive )
JAR は Java Archive の略で、クラスファイルやリソースファイルやメタデータをまとめた圧縮ファイルです。
Hello.jar
ファイルを作るには、クラスファイル ( Hello.class
, Message.class
) とマニフェストファイル ( MANIFEST.MF
) を作ってから jar
コマンドでアーカイブします。
試してみましょう。
Manifest-Version: 1.0
Main-Class: Hello
$ jar cfm Hello.jar MANIFEST.MF Hello.class Message.class # JAR 作成
$ ls
Hello.class Hello.jar Hello.java MANIFEST.MF Message.class Message.java
~~~~~~~~~
^ new
.jar
ファイルは java
コマンド + -jar
オプションで実行します。
$ java -jar Hello.jar
Hello from Message
JAR になっていれば、.class
ファイルが数千あろうと持ち運びしやすくなります。
JAR はライブラリの配布や実行環境へのデプロイなどで使われています。
ちなみに実体としては ZIP ファイルなので、unzip
コマンドなどで展開できます。
WAR ( Web Application Archive )
WAR は Web Application Archive の略で、Apache Tomcat などのサーブレットコンテナ ( Web アプリケーションの Java 実行環境 ) で動かすための圧縮ファイルです。
java -jar Foo.jar
のようにコマンドラインで動かすアプリケーションではなく、Apache Tomcat などに乗せて Web サービスとして動かしたいときに用います。
まとめ
- ✏️ コマンドラインで実行するのが JAR
- ✏️ サーブレットコンテナで実行するのが WAR
- ✏️ どっちもただの圧縮ファイルで、
.class
ファイルなどが入っている
JVM と JRE と JDK
よく聞くやつですね。
コンパイルや実行におけるバージョン指定を理解するには、このセクションの理解が不可欠です。
JVM ( Java Virtual Machine )
JVM は Java Virtual Machine の略で、Java プログラムを実行するための仮想マシンのことです。
JVM があることで、Microsoft Windows と macOS のように OS 差異があるプラットフォームでも同じコードが実行できます。
1990 年くらいは異なるプラットフォーム間の互換性問題はいまよりずっと大変で、それを解決する設計が JVM だったんです。
Java プログラムが動いているところには JVM がいます。
JRE ( Java Runtime Environment )
JRE は Java Runtime Environment の略で、Java プログラム実行環境のことです。
JVM と、標準ライブラリや各種設定ファイルなどで構成されています。
たとえば System.out.println
メソッドを使うには lava.lang
パッケージが必要です。
これらパッケージのクラスは JRE の一部として提供されています。
ところで 2019 年に JRE だけのインストールはできなくなったようです。
この記事を書くまで知りませんでした。 [1]
JDK ( Java Development Kit )
JDK は Java Development Kit の略で、Java プログラムを開発するために必要なもの一式です。
コンパイラ ( javac
) やアーカイブツール ( jar
) などと、JRE ( と JVM ) で構成されています。
つまり開発するには JDK が必要ということです。
まとめ
- ✏️ JVM は Java プログラムを動かす仮想マシン
- ✏️ JRE は JVM + 標準ライブラリなど
- ✏️ JDK は JRE + コンパイラなど
「きみの PC に Java の開発環境をセットアップして」って言われたら、JDK を入れろという意味ですね。
Java と Kotlin
簡単に Kotlin について整理します。
Java と Kotlin は違う言語と思って片方に専心するより、少しでも両方知っていたほうが楽になると思います。
すぐ両方習得する必要はありませんが、言語間で流用可能な話題が識別できるようになるといろいろ捗ります。
Kotlin とは
Kotlin は JetBrains ( IntelliJ IDEA を作ってる会社 ) が開発したプログラミング言語です。
手っ取り早く Kotlin の開発がしたければ、無料版の IntelliJ IDEA か Android Studio を使うのが簡単です。
Java との互換性があり、Java と同じく JVM 上で動作します。
Kotlin のコンパイルと実行
.java
ファイルをコンパイルする javac
コマンドがあるように、.kt
ファイルをコンパイルする kotlinc
コマンドがあります。
試してみましょう。
fun main() {
println("Hello Kotlin")
}
$ ls
Hello.kt
$ kotlinc Hello.kt -d . # コンパイル
$ ls
Hello.kt HelloKt.class META-INF
~~~~~~~~~~~~~ ~~~~~~~~
^ new ^ new
$ java HelloKt # 実行
Hello Kotlin
.kt
ファイルもコンパイルすると .class
ファイルになり、java
コマンドで実行します。
Kotlin コードと Java コードの混在
.java
ファイルと .kt
ファイルは、どちらもコンパイルすれば .class
ファイルになると確認しました。
ここからなんとなく想像がつくと思いますが、Java と Kotlin は混在できます。
試してみましょう。
( 出力は長いので折りたたんでいます )
Kotlin コードで Java コードを使う例
fun main() {
val message = Message()
println(message.word())
}
public class Message {
public String word() {
return "Hello Kotlin -> Java";
}
}
$ ls
Hello.kt Message.java
$ javac Message.java # まず Java をコンパイル
$ ls
Hello.kt Message.class Message.java
~~~~~~~~~~~~~
^ new
$ kotlinc Hello.kt -cp . -d . # Kotlin をコンパイル
$ ls
Hello.kt HelloKt.class META-INF Message.class Message.java
~~~~~~~~~~~~~ ~~~~~~~~
^ new ^ new
$ java -cp . HelloKt # 実行
Hello Kotlin -> Java
Java コードで Kotlin コードを使う例
public class Hello {
public static void main(String[] args) {
Message message = new Message();
System.out.println(message.word());
}
}
class Message {
fun word(): String {
return "Hello Java -> Kotlin"
}
}
$ ls
Hello.java Message.kt
$ kotlinc Message.kt -d . # まず Kotlin をコンパイル
$ ls
Hello.java META-INF Message.class Message.kt
~~~~~~~~ ~~~~~~~~~~~~~
^ new ^ new
$ javac -cp . Hello.java # 次に Java をコンパイル
$ ls
Hello.class Hello.java META-INF Message.class Message.kt
~~~~~~~~~~~
^new
$ java -cp . Hello # 実行
Hello Java -> Kotlin
たとえば Kotlin プロジェクトで Java のライブラリを使うことはとてもよくあります。
Kotlin コードと Java コードの変換
IntelliJ IDEA は、とくに設定や指示をせずとも .kt
ファイルに Java コードをペーストするとその場で変換してくれます。
貼り付けた瞬間にガチャガチャっと一瞬で書き換わるので、ちょっと見ものです。
ここで言いたいのは、Java ( Kotlin ) の調べ物をしているときに見つけたコードが Kotlin ( Java ) だったとしても役立てられるということです。
多少文法が違うくらいなので、読み取れることや使えるコードを見落とさないといいですね。
まとめ
- ✏️ Kotlin も JVM で動く
- ✏️ Kotlin コードと Java コードは混在可能
- ✏️ 調べ物やナレッジは上手に Java - Kotlin 間で活用できるといい
Spring
厳密には Spring という名前のフレームワークはありません。
Spring Framework か Spring Boot が正確なフレームワーク名です。
そしてそのふたつは違うフレームワークです。
Spring と言った場合は Spring Framework / Spring Boot やエコシステム全体を指す単語として使われている場合や、単に暗黙の了解として略している場合などがあります。
Spring Framework
Web アプリケーションを開発するためのフレームワークです。
2000 年代にできて広まりました。
公式ページで SUPPORT を見るとわかるとおり、まだまだ現役です。
Spring Security, Spring Data, Spring Batch のような周辺ライブラリを追加するとどんどん機能が増えるフレームワークです。
Spring Framework は、一般には WAR を作り Apache Tomcat などのサーブレットコンテナにデプロイします。
Spring Boot
Spring Framework から派生し 2010 年代後半に広まったフレームワークです。
同じく Web アプリケーションの開発に使います。
Spring Boot は、一般には JAR を作り JVM の上で動かします。
この JAR に Apache Tomcat のようなサーブレットコンテナが入っていて、JAR 単体で Web サーバとして動くようになっています。
JAR を作ってそれだけを持ち運びコマンド実行で Web サーバになるので、Docker のようなコンテナ技術と相性がよいです。
Spring に関する調べ物
普段の口語で Spring と言っているのは問題ありませんが、場面によっては Spring Framework と Spring Boot の違いを認識しておくと無駄な事故がなくなります。
Spring 関係の調べ物をするときは、上手に情報の取り捨て選択をできるとかなり効率が変わります。
AI を活用して読み替えをサポートしてもらったり、AI への指示をより正確にできるといいですね。
この辺だけでも意識しておくといいでしょう。
- Java / Kotlin
- Spring Framework / Spring Boot
- Java Config / XML Config
拾える情報が多いとも言えるし、難しいとも言える点ですね。
当然内容や程度によりますが、参考までに個人的な感覚を記します。
Java / Kotlin
- 言語にこだわらず情報を拾えるとよい
- Spring の観点で言えば、どちらかに限定されるサンプルコードはあまりない
- 「サンプルコード Java じゃん」って即閉じするのは高確率で損
Spring Framework / Spring Boot
- 内容による
-
@Autowired
みたいな Spring のコアコンセプトは同じ場合が多い - 起動やその周辺設定は違うと思ったほうがいい
- デプロイや運用ノウハウはかなり違う
Java Config / XML Config
@Configuration
のようなアノテーションによる設定を Java Config と言います。
( 正式には Java-based Configurations )
昔の Spring Framework は XML で設定していたんですが、今は型安全だし IDE の機能が使えるので Java Config が主流です。
- 基本的には Java Config の記事を読めばいい
- XML のサンプルは、読み替えうんぬんではなく単純に古い内容の場合が多い
まとめ
- ✏️ Spring Framework は、WAR を作って Apache Tomcat などに乗せて動かす
- ✏️ Spring Boot は、JAR を作って
java
コマンドで動かす - ✏️
spring java
とかで調べると思っている情報になりにくいので、単語は正確に - ✏️ Java, Kotlin, Spring Framework, Spring Boot の情報は取り捨て選択が効率化のカギ
Gradle
Gradle は Java や Kotlin などのビルドツールです。
先述した javac
コマンドに大量のファイルやオプションをいい感じで指定してくれたり、テスト実行やライブラリ管理をしてくれたりするツールです。
昨今 Java や Kotlin の開発をするときは、ほぼ間違いなく Gradle を使います。
Gradle についてもう少し具体的に知りたいひとは、あわせて書いたもうひとつの記事も参考にしてください。
インストール
たとえば macOS なら brew
コマンドでインストールできますが、必ずしも gradle
コマンドをインストールする必要はありません。
IntelliJ IDEA のプロジェクト新規作成機能で Gradle 形式を選ぶと、Gradle 本体を含むプロジェクトが作成されます。
プロジェクトルートにある gradlew.bat
と gradlew
が Gradle のコマンド ( Microsoft Windows 用と macOS 用 ) です。
このコマンドごと git に commit して管理し、コンパイルやテスト実行はこれで行います。
つまり git clone
をすると Gradle のコマンドも同時に手に入るということです。
僕は 10 年以上 Java や Kotlin で開発していますが、自分の PC で brew install gradle
したことは一度もありません。
もちろん brew install gradle
と gradle init
でもプロジェクトを作成できるので、好みや必要に応じてそちらを使っても大丈夫です。
設定ファイル
Gradle の設定は build.gradle
というファイルを Groovy という言語で書いていました。
最近は build.gradle.kts
というファイルを Kotlin で書けるようにもなりました。
できることは同じです。
そういうことを知っていると、build.gradle
と build.gradle.kts
の読み替えや流用などもできるようになりそうですね。
設定ファイルを使い、依存ライブラリの管理やコンパイル設定などを行います。
設定ファイルが JSON のような構造化データではなくスクリプトファイルなので、Kotlin ないし Groovy でちょっとしたコードも書けちゃいます。
この記事では、具体的な設定項目については割愛します。
いくつかある設定ファイルの用途の違いなどは、もうひとつの記事 をご覧ください。
よく使うタスク
Gradle では、Gradle で実行する処理をタスクと呼びます。
標準で使えるタスクとプラグイン追加で使えるようになるタスクのほか、自作のタスクも追加できます。
ここでは標準で使えるタスクをいくつか紹介します。
test タスク
JUnit などの自動テストを実行するタスクです。
$ ./gradlew test
-i
をつけると HTML のレポートが生成されます。
$ ./gradlew test -i
ケース別の実行時間が出ているほか、ケース別にページが分かれている点がただのテキスト出力とは違います。
テストケースをちゃんと書いていれば、簡単な仕様書にもなります。
build タスク
コンパイルして JAR を作るタスクです。
出力先や形式は build.gradle.kts
で設定します。
$ ./gradlew build
.java
ファイルが 5000 くらいあろうともこれだけでビルドできるのだから、Gradle は必要不可欠ですね。
ところで build
タスクは test
タスクや jar
タスクを連続実行しており、-x
で一部タスクを除外できます。
知っていると次のように「テストはおいといて、JAR が作れるかだけ確認したい」という操作ができます。
$ ./gradlew build -x test
tasks タスク
実行できるタスクの一覧を表示するタスクです。
$ ./gradlew tasks
出力
> Task :tasks
------------------------------------------------------------
Tasks runnable from root project 'xxxxxxxxxxxxx'
------------------------------------------------------------
Build tasks
-----------
assemble - Assembles the outputs of this project.
build - Assembles and tests this project.
buildDependents - Assembles and tests this project and all projects that depend on it.
buildNeeded - Assembles and tests this project and all projects it depends on.
classes - Assembles main classes.
clean - Deletes the build directory.
jar - Assembles a jar archive containing the classes of the 'main' feature.
testClasses - Assembles test classes.
Build Setup tasks
-----------------
init - Initializes a new Gradle build.
updateDaemonJvm - Generates or updates the Gradle Daemon JVM criteria.
wrapper - Generates Gradle wrapper files.
Documentation tasks
-------------------
javadoc - Generates Javadoc API documentation for the 'main' feature.
Help tasks
----------
buildEnvironment - Displays all buildscript dependencies declared in root project 'xxxxxxxxxxxxx'.
dependencies - Displays all dependencies declared in root project 'xxxxxxxxxxxxx'.
dependencyInsight - Displays the insight into a specific dependency in root project 'xxxxxxxxxxxxx'.
help - Displays a help message.
javaToolchains - Displays the detected java toolchains.
kotlinDslAccessorsReport - Prints the Kotlin code for accessing the currently available project extensions and conventions.
outgoingVariants - Displays the outgoing variants of root project 'xxxxxxxxxxxxx'.
projects - Displays the sub-projects of root project 'xxxxxxxxxxxxx'.
properties - Displays the properties of root project 'xxxxxxxxxxxxx'.
resolvableConfigurations - Displays the configurations that can be resolved in root project 'xxxxxxxxxxxxx'.
tasks - Displays the tasks runnable from root project 'xxxxxxxxxxxxx'.
Verification tasks
------------------
check - Runs all checks.
test - Runs the test suite.
Rules
-----
Pattern: clean<TaskName>: Cleans the output files of a task.
Pattern: build<ConfigurationName>: Assembles the artifacts of a configuration.
プラグインで入れたタスクや滅多に実行しないタスクは忘れがちなので、雑に調べるのに意外と便利です。
ライブラリ管理
細かい設定方法などは もうひとつの記事 に切り出しました。
さわりだけ整理します。
設定方法
build.gradle.kts
の dependencies
ブロックに、ライブラリの名称とバージョンを記載します。
dependencies {
implementation("org.apache.commons:commons-lang3:3.17.0")
}
このように依存ライブラリを設定すると、プロジェクトで対象のクラスを import
して使えるようになります。
追加したライブラリは読めるけど書けない
build.gradle.kts
で依存ライブラリを設定すると、そのライブラリの JAR がダウンロードされます。
たとえば PHP の Composer では vendor/
ディレクトリに .php
ファイルがダウンロードされますが、Gradle では .java
ファイルはダウンロードされません。
IDE でジャンプしてライブラリのコードを読めるのは、IDE が JAR 内の .class
ファイルをデコンパイルして Java コードを再現しているからです。
だから「ライブラリに print
入れて変数見てみよ」みたいな編集はできないのです。
dependencies タスク
ライブラリの依存関係を可視化するタスクです。
$ ./gradlew dependencies
> Task :dependencies
------------------------------------------------------------
Project 'xxxxxxxxxxxxxxxxxxxxxxxxxx'
------------------------------------------------------------
compileClasspath - Compile classpath for main.
+--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.21
| +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.21
| | +--- org.jetbrains.kotlin:kotlin-stdlib-common:1.8.21
| | \--- org.jetbrains:annotations:13.0
| \--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.21
| \--- org.jetbrains.kotlin:kotlin-stdlib:1.8.21 (*)
+--- org.springframework.boot:spring-boot-starter-web -> 3.1.1
| +--- org.springframework.boot:spring-boot-starter:3.1.1
| | +--- org.springframework.boot:spring-boot:3.1.1
| | | +--- org.springframework:spring-core:6.0.10
| | | | \--- org.springframework:spring-jcl:6.0.10
| | | \--- org.springframework:spring-context:6.0.10
| | | +--- org.springframework:spring-aop:6.0.10
| | | | +--- org.springframework:spring-beans:6.0.10
| | | | | \--- org.springframework:spring-core:6.0.10 (*)
| | | | \--- org.springframework:spring-core:6.0.10 (*)
| | | +--- org.springframework:spring-beans:6.0.10 (*)
| | | +--- org.springframework:spring-core:6.0.10 (*)
| | | \--- org.springframework:spring-expression:6.0.10
| | | \--- org.springframework:spring-core:6.0.10 (*)
# 以下 5000 行ほど切り捨て
自分が追加した org.springframework.boot:spring-boot-starter-web
が、連動してどんなライブラリを追加したかまでわかります。
どのバージョンが実際に使われているか調べたり、ライブラリに脆弱性報告があがったとき「明示はしてないが使っているだろうか」と調べたりするときに必須のタスクです。
この記事では「dependencies
タスクで使っているライブラリを調べられる」まで知っていれば十分です。
Toolchain
Toolchain とは、プロジェクトのビルドに使用する JDK を管理する機能です。
settings.gradle.kts
と build.gradle.kts
に次のように書いておくと、そのプロジェクトのために JDK 16 を自動でインストールしてくれます。
plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version "0.9.0"
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(16)
}
}
ところで、Gradle を実行する JDK とプロジェクトで使われる JDK について知らないと混乱しやすいので整理しておきます。
gradlew
コマンドの実行には、JDK が必要です。
この JDK はローカルマシンにインストールしたものです。
実行された Gradle は、プロジェクトのコンパイルなどに使う JDK を build.gradle.kts
の Toolchain 設定に従ってインストールしてから使います。
Toolchain の設定をちゃんとしているプロジェクトなら、自分の PC には Gradle をキックするだけのそれなりに新しい JDK が入っていればほぼ大丈夫です。
ビルドバージョンの設定は類似項目が多く、知らないと意図通り設定できません。
詳細は もうひとつの記事 をご覧ください。
まとめ
- ✏️ Gradle はコンパイルやライブラリ管理をいい感じでやってくれるツール
- ✏️
gradlew.bat
かgradlew
を使う - ✏️
build.gradle.kts
( かbuild.gradle
) を使って設定する - ✏️ いろいろタスクがあるので、困ったら
tasks
を実行する - ✏️ 依存ライブラリの JAR を取得し、それを使い自分のコードをビルドし JAR ( など ) を作る
- ✏️ Gradle そのものの実行に JDK が必要、プロジェクトで使う JDK は Toolchain で設定する
Android アプリケーション
Kotlin と冠する単語や Java に類する単語が今の自分に必要なのかを判断できるように、簡単に単語だけ見ておきます。
開発
2019 年に Google が Android 開発の推奨言語を Kotlin と発表した ( 公式サポート開始は 2017 年 ) ので、最近の開発は Kotlin が主流でしょう。
その前は Java でした。
ビルドツールに Gradle を使う点や、Java と Kotlin の互換性やコンパイルについてなど基本的なところは同じです。
実行環境
Android アプリケーションは JVM ではなく ART ( Android Runtime ) という実行環境上で動作します。
Java および Kotlin のコードをクラスファイルにコンパイルするところまでは同じです。
そのあとさらに R8 コンパイラと D8 コンパイラによって DEX ( Dalvik Executable ) というファイル形式に変換されます。
それをマニフェストファイルや画像などと一緒にパッケージして、APK ( Android Package ) というファイルを作ります。
ストアで配布されているのは APK ファイルですね。
Android 端末は、APK の中にある DEX をうまいこと変換して ART 上で実行しています。
「うまいこと変換」の部分に興味があるひとは、Android + AOT ( Ahead-Of-Time ) コンパイルや JIT ( Just-In-Time ) コンパイルという単語で調べられます。
ちなみに Dalvik は Android 5 より前にデフォルトのランタイムとされていた仮想マシンです。
Kotlin/Native
Kotlin/Native という Kotlin コードをネイティブコードにコンパイルする技術を使うと、JVM なしで動くアプリケーションを作れます。
対応プラットフォームは Microsoft Windows, macOS, Linux, Android, iOS, WebAssembly などです。
JVM に依存しないデスクトップアプリを作ったり、モバイルアプリを作ったりできます。
Kotlin Multiplatform
Kotlin Multiplatform を用いると、iOS と Android のように異なるプラットフォームから使うコードを Kotlin で共通化できます。
Android / iOS アプリケーションを開発する際、コアロジックや API 実行などの共通処理を Kotlin で実装し共有できるようになります。
Kotlin コードを iOS で動かすためには Kotlin/Native が使われます。
まとめ
- ✏️ Android アプリケーションは JVM ではなく ART で動いている
- ✏️ Kotlin/Native を使うと、JVM 非依存のアプリケーションを作れる
- ✏️ Kotlin Multiplatform を使うと、複数プラットフォームで Kotlin コードを共有できる
ほか
知らなくてもいいけど、知ってるとふとしたときに役立つことです
知らなくてもいいです。
Java のバージョン
上記ページの Java Release Support Timeline を見てみると、2014 年リリースの 8 と 2017 年リリース 9 の間で方針転換されています。
8 までは大型アップデートは不定期で、どのバージョンも LTS とされていました。
9 からは方針が変わり、半年ごとアップデートになりました。
LTS は 11, 17, 21 のようにとびとびです。
( 11 から 3 年ごとに LTS という計画で始まり、2 年ごとに変わったようです )
あと、歴史的事情により 8 を 1.8 と書くことがあります。
最近は普通に 17 などと書くのであまり見なくなりましたが、知らないとちょっと混乱しますね。
ビルドバージョン
クラスファイルは javap
コマンドで解析できます。
そのなかにある major version: 61
が、このクラスファイルが動く JVM のバージョンです。
$ javap -v Message.class
Classfile /xxxxx/xxxxxxx/xxxxxx/Message.class
Last modified 2025/02/19; size 283 bytes
SHA-256 checksum 0a7d766xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxbc35afa8f
Compiled from "Message.java"
public class Message
minor version: 0
major version: 61
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #9 // Message
super_class: #2 // java/lang/Object
interfaces: 0, fields: 0, methods: 2, attributes: 1
略
これも知らないと読めないのですが、この数字は 44 を引いて読むと決まっています。
61 と書いてあるので、JVM 17 以上で動くクラスファイルです。
ごくまれにビルドバージョンと実行環境のバージョンが合わず、調べる羽目になるんですよね。
JDK 選び
まず前提として、Java は ( 2010 年に Sun Microsystems を買収した ) Oracle 社がメンテナンスしています。
その Oracle 社は 2019 年に Oracle JDK 11 を有償化し、2021 年に Oracle JDK 17 を無償化しました。
もともと Oracle JDK とは別に OpenJDK というオープンソースの JDK がありましたが、この時期にそれをもとにいろいろなベンダが JDK の提供を始めました。
Amazon Corretto や Microsoft Build of OpenJDK などがそれで、それぞれのクラウド環境では標準の JDK とされています。
ベンダの違いで基本的な機能の差はほとんどなく、違うのはサポートの期限や範囲・ライセンス・相性のいいクラウド環境などの部分です。
よく見かけるのは、次のようなものです。
名前 | ベンダ | 特徴 |
---|---|---|
Oracle JDK | Oracle | 商用サポートがある |
OpenJDK | Oracle Red Hat IBM など |
Oracle OpenJDK や Red Hat OpenJDK のように、各ベンダがそれぞれ提供している サポートや特徴もそれぞれ |
AdoptOpenJDK | Eclipse Foundation | 有償化に対する代替として有名 |
Amazon Corretto | Amazon | AWS ならこれにしておけばいい |
Microsoft Build of OpenJDK | Microsoft | Azure ならこれにしておけばいい |
デプロイ先に合わせる形で選べばおおむね問題ないです。
Maven Repository
ライブラリ置き場のことです。
大半のライブラリはここ ( の Central Repository ) からダウンロードして使っています。
依存追加するときの正式名称がわからなかったり、どんなバージョンがあるか知りたいときに確認します。
詳細ページでは「Gradle 使ってるならこのコードをコピペすると依存追加できるぞ」と書いてあり、そのまま貼り付ければ依存追加できます。
Maven と pom.xml
Maven ( mvn
コマンド ) は、Gradle の前の時代に使われていたビルドツールです。
設定ファイルは pom.xml
です。
要するにこういうことです。
旧 | 新 |
---|---|
Maven | Gradle |
mvn |
gradlew など |
pom.xml |
build.gradle.kts など |
新たにプロジェクトを作るとき Maven を採用することはまずありません。
古いライブラリや Stack Overflow の古い投稿でまれに見かけるので、そのときに「あぁ Gradle 的なやつね」くらいで脳内置換できれば十分です。
おわりに
「J なんとか」みたいな似た単語が多かったり、「歴史的背景により」みたいなのが多いんですよね。
個人的にはもし今から「Spring やれ」って言われたら、こういうことを知りたいなと思います。
「今知っておくべきこと」「もう知らなくていいこと」「交換可能なこと」の識別ができるだけで、頭のすっきり度が全然変わってくるからです。
繰り返しますが、最初に暗記を詰め込む必要はありません。
この記事を読んでくれたひとの「ふーん...??」が、いつか「あー...あれか...!?」になってくれればいいと思っています。
-
10 年以上前に「Java をインストールしろと言われたが、JDK とか JRE とか 8 とか 1.8 とか何が何だか全然わからん」なんて混乱したものです。 ↩︎
Discussion