CodeZine(コードジン)

特集ページ一覧

Vert.xのモジュールの構造と仕組み

Javaプログラマーのための実践「Vert.x」 第2回

  • LINEで送る
  • このエントリーをはてなブックマークに追加

目次

モジュールとVerticle ~ モジュールクラスローダー

 実際にモジュールを作成する前に、Vert.xモジュールが起動される仕組みはどういうものなのか。また、モジュールのmainとなる実行インターフェースのVerticleについて簡単に説明したいと思います。

 まず、起動時にはVert.x自身をロードするプラットフォームクラスローダーと呼ばれるクラスローダーを持ちます。そして各モジュールをロードする際に、指定されているモジュール配置ディレクトリ(VERTEX_MODS)配下より、プラットフォームクラスローダーを親とし、各々のモジュール個別にモジュールクラスローダーという独立したクラスローダーを作成してロードします。

 プラットフォームクラスローダーは環境変数CLASSPATHで指定されたパスと${VERTX_HOME}/conf、${VERTX_HOME}/lib/*を対象とします。モジュールクラスローダーは、そのモジュールディレクトリ配下のクラス、およびlibディレクトリ配下のjarファイルを対象としてロードします。

 下図のcom.bloidonia~mod-jdbc-persistor~2.1.3 、およびその下位のlibディレクトリ配下のjarファイルがモジュールクラスローダーの対象となります。

 対象のモジュールが${VERTX_MODS}に存在しない場合、クラスパス内のrepos.txtに指定されているリポジトリから自動的にダウンロードし、${VERTX_MODS}に展開されます。

 複数のモジュールを起動する場合は、mod.jsonの"includes" : "…" にモジュール名を記述することで同時起動が可能です。また、各モジュール内で複数のVerticleや別のモジュールを起動(デプロイ)することもできます。

container.deployVerticle("verticleClassName"); // Verticleクラスを起動
container.deployModule("moduleName"); // モジュールを起動
モジュールデプロイイメージ
モジュールデプロイイメージ

 この場合、注意すべきはモジュール内からロードした別モジュール、Verticleはそれぞれ別のモジュールクラスローダーが作成され、プラットフォームクラスローダーとの親子関係ができる点です。

 これの意味するところは、モジュールのクラスパス内にのみ存在するクラスでは、同じモジュール内だとしても異なるVerticle間でstaticフィールドの変数値を共有することができないということになります。これは通常のJavaのイメージで開発していると思わぬ挙動を呼ぶことになるため、意識しておく必要があるでしょう。

モジュール参照

 モジュールの関係としてモジュール参照があります。これはマニュアルにも明確には書いていませんが、モジュールクラスローダー間で参照関係を持つ機能です。

 これは、モジュールの親子関係が発生する場合に自動的に子のモジュールクラスローダーから親のモジュールクラスローダーへの参照が付与されます。

 マニュアルでは、これも親子関係のように書いてありますが、通常のクラスローダーの親子関係とは異なるため、ここではモジュール参照という別の言葉で表現します(実際にこの関係を実現するためのクラス名がModuleReferenceになっています)。

 通常のクラスローダーの親子関係は、まず親に移譲して検索し、親のクラスパスに存在しなかったら子のクラスローダーが検索するという、親から子への順番でクラスを検索します。プラットフォームクラスローダーとモジュールクラスローダーの関係は、この親子関係にあたります。

 モジュール参照の場合は逆に子が優先されます。まず自分自身(子モジュール)のクラスパスを検索し、参照先(親モジュール)のモジュールクラスローダーへ移譲します。mod.jsonの"includes"でロードされたモジュールのモジュールクラスローダーは、参照先(親モジュール)として扱われます。

 親をランタイムモジュールとし、子をアプリケーションモジュールとするイメージと考えたら捉えやすいでしょうか。

通常の親子関係クラスロードの流れ
通常の親子関係クラスロードの流れ
モジュール参照時のクラスロードの流れ
モジュール参照時のクラスロードの流れ

共有データ

 staticフィールドで値を共有できず、またメッセージパッシングだけでは効率が悪い場合に、異なるVerticle間でデータを共有するための方法として、SharedMapとSharedSetが用意されています。任意の名前で作成したMapやSetに共有したい値を登録することができます。

ConcurrentMap<String, Integer> map = vertx.sharedData().getMap("demo.mymap");
map.put("some-key", 123);

Set<String> set = vertx.sharedData().getSet("demo.myset");
set.add("some-value");

 ただし、登録できる型にはキー、バリューとも制限があるので注意が必要です(String、Integer、Long、Boolean、Double、Float、Short、Byte、Character、byte[]、Buffer、Shareableの12種類)。基本的に不変なデータのみ共有できることになります。

 不変なデータという約束はありますがShareableでラップすることで、いろいろな型も対応可能となります。


  • LINEで送る
  • このエントリーをはてなブックマークに追加

バックナンバー

連載:Javaプログラマーのための実践「Vert.x」

著者プロフィール

  • リョウジ(株式会社DMM.comラボ)(リョウジ)

    DMM.comのプラットフォームにおける主要アーキテクチャに関しての技術研究開発を担当。 非同期のメッセージ&キューの導入、Vert.xフレームワークを採用し社内の基盤を整備等、 高負荷対策・可用性の高いアーキテクチャの開発・設計など幅広く活躍。

あなたにオススメ

All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5