← Spring コース
22. この設計の代償と、後の言語がしたこと
この不便さは が持ち込んだものではなく、1996年の最初の Java に既にある決め方から来ています。逆さにしたドメイン名を名の先頭に付ける慣習と、その名前をディレクトリに写す置き方です。後者は仕様が「ごく単純な例」として示し、 のコンパイラと標準の読み込みがそのとおりに実装しました。ドメイン名を使う理由は、仕様によれば「既にある一意な名前の登録簿に相乗りし、別の登録簿を作らない」ためです。
得たのは、名前だけでクラスを簡単に見つけられることと、登録簿を作らずに済むことです。払ったものは3つです。名前の長さがフォルダの深さになります。実行時は全部が1本の(クラスを探す場所の一覧)に並ぶので、足りない部品は使う瞬間まで分からず、同じパッケージのクラスが別の から読まれえます。Java 9 の( のものとは別で、JAR どうしの依存を宣言する仕組み)が扱うのは後の2つで、深さは変わりません。
他の言語は別の方式です。Node は呼び出し元から上へ node_modules を探し、Rust は公開するライブラリ名を crates.io が先着順で割り当てます。Go は Java と同じく既存の名前(URL)を借りますが、長い名前はディレクトリに現れません。既存の Java プロジェクトでは、jp/co/example をフォルダではなく、1つの長い名前の一部として読めば足ります。IDE では途中を1行に畳んで表示できます。
点線の付いた語はタップすると説明が出ます。用語集を開く →
Java 言語仕様 第1版(1996年)逆ドメインの名前は「慣習」、名前をディレクトリに写す置き方は「ごく単純な例」として書かれている
Spring が決めたものではない得たもの
名前だけで見つかる単純な実装でも、名前の . を / に替えた場所を探せばよい
登録簿が要らないドメイン名の登録簿に相乗り
払ったもの
名前の長さがフォルダの深さになるjp/co/example/shop/...
欠落は使う瞬間まで分からない部品どうしの依存を表せない
同じパッケージのクラスが別の部品から読まれうる全部が1本のクラスパスに並ぶ
後から足されたもの
Java 9 のモジュール(2017年)JAR どうしの依存を宣言する仕組み。Maven のモジュールとは別物。宣言は任意で、パスの深さは変えない
右2つへの対処IDE の表示IntelliJ IDEA と VS Code は、途中の階層を1行に畳んで表示できる
左への対処は表示だけ- 確認できた最古の資料が1996年8月の第1版です。仕様もJVMの仕様もディレクトリ対応を義務にはしておらず、データベースに置く実装も認めています。実際に決めているのは JDK の javac と標準のクラスローダの実装です。
- 「払ったもの」の右2つは、モジュールの仕様の申請文(JSR 376)が brittle, error-prone class-path mechanism(もろく、間違いやすいクラスパスの仕組み)として挙げた2点です。俗に JAR hell と呼ばれますが、これは通称で、仕様の文書には出てきません。
- JDK 9 の一般提供は 2017-09-21 です。モジュールの設計文書は、Java 8 でコンパイルして動くクラスパスのアプリは、非推奨でない標準の API だけを使う限り Java 9 でも同じに動く、と書いています。
- Spring Boot 4.1.1 の Web アプリ(雛形1つ)が同梱する JAR 34本のうち、モジュール宣言(module-info.class)を持つのは16本でした。Spring 自身の16本と Micrometer の2本は、マニフェストにモジュール名を1行書いているだけです。
- Kotlin は同じ JVM で動きますが、Kotlin だけのプロジェクトではソースの置き場所から共通の接頭辞を省くことを公式の規約が勧めています。コンパイル結果の .class は Java と同じ深さのディレクトリに出ます。
- 他の言語が Java のこの規則を見て方式を決めた、と述べた資料は見つかっていません。言えるのは「違う方式である」までです。
▶ サンプルコードを実行してみよう(自由に書き換えてOK)
Java
図やコードに出てくる用語(タップで説明)
サンプルコードで身につける(5本) →
学んだ概念を、素朴な例から実務寄りの例まで5つの具体例で確認します。
公式ドキュメントで詳しく ↗