ダウンロード サンプルファイル (380.8 KB)
前回は、Java 9のモジュール機能「Project Jigsaw」の基本的な使い方を紹介しました。今回はJava 9以前に作られた既存のライブラリとモジュール機能を併せて使う場合の利用方法と、「ServiceLoader」を使う際の変更点を紹介します。
対象読者
- Java関連に携わる開発者
- これからJavaを学ぼうと思っている方
既存のライブラリ資産を利用する場合
Javaにはこれまで蓄積されたライブラリも多く、特にオープンソースライブラリを使わない選択をするのは、多くのプロジェクトで難しいと言わざるを得ません。そしてJava 9へのバージョンアップ後も、それらのライブラリをそのまま使う必要があるケースが多々あります。
しかし、Java 9がモジュールに対応したことに合わせて、既存の全ての資産をモジュール対応させてリリースし直すのは、現時点では難しいことでしょう。
Java 9のモジュール機能とモジュール対応されていないライブラリを同時に利用することは可能です。しかし、そのためにはいくつかの注意点があり、Java 9がモジュールをどのように扱っているのか、理解する必要があります。
Java 9におけるモジュールの扱い
Java 9のモジュールは、以下の3種類に分類できます。
[1]Named Module(Platform Module/Application Module)
Java 9のモジュール機能形式に沿ったモジュールです。このモジュールにはJDKで提供されているPlatform Moduleとそれ以外のApplication Moduleが存在しますが、基本的な制限事項は同じです。
ただし、Platform Moduleのjava.baseは全てのコードに依存してしまうため、このモジュールのみ例外としてどのモジュールからも自由にアクセス可能です。また、Application Moduleはモジュールパス(実行時に--module-pathで指定されたパス)に配置する必要があります。
[2]Automatic Module
この形式は、Java 9以前の形式(module-info.classファイルがない)でパッケージングされたjarファイルがモジュールパスに配置された際、自動的にモジュール扱いになるものです。
モジュール名は「ファイル名から自動的に命名」されるか、「manifestファイル内のAutomatic-Module-Name属性で指定」します。
ファイル名から自動的に命名される場合
ファイル名から命名される場合には、ルールに従います。具体的には以下の通りです。
- 最後の.jarの拡張子を削除します。
- ファイル名にハイフンが含まれて、そのハイフン以降が数値もしくはドットの場合(正規表現で「-(\d+(\.|$))」に一致する場合)、最初のハイフン以前の部分を利用します。
- 英数字でない文字(ハイフンなどの記号)は、全てドットに置き換えます。
つまり、「sample-foo.jar」という名前のjarファイルは「sample.foo」というモジュール名になり、「sample-foo-2.0.1.jar」というファイル名の場合も「sample.foo」というモジュール名になるということです。
manifestファイル内のAutomatic-Module-Name属性で指定する場合
manifestファイル内でモジュール名をsample.fooと指定する場合には、リスト1の通りにします。
Automatic-Module-Name: sample.foo
どちらの方法で命名されたとしても、このjarファイル内で定義されたパッケージは自動的に全てexportsされたものとして扱われます。これは、その他のモジュールに依存していることも多く、そこで定義が必要になってしまわないためにも必要な扱いといえます。
[3]Unnamed Module
このモジュールはクラスパスに指定された場合のモジュールです。また、Unnamedとあるようにモジュール名はありません。通常ここに配置されるのはAutomatic Moduleが依存しているライブラリです。
Application Moduleがコンパイルされる際に、Automatic ModuleとUnnamed Moduleにどのような制限があるかを示したのが図1です。
この通り、Unnamed Moduleは参照できません。つまり、コンパイル時にパッケージやクラスが見つからないことになります。したがって、コード内で既存のjarファイル内のクラスにアクセスする場合には、そのjarファイルをモジュールパス内に移動し、Automatic Moduleとして扱う必要があります。
ただし実行時はコンパイル時と異なり、リフレクションを使ったクラスへのアクセスが可能なため、コンパイル時に問題が生じなくても、実行時にはエラーが発生するケースがあります。
また、Java 9に以前に作られたライブラリは、Platform Moduleのjava.base以外も全て、何も制限なく参照可能でした。つまり、Java 9以前に作られたライブラリの場合は、ライブラリの中身を何も変更せずにそのまま利用したい事が多いと思います。そのためには、Javaの実行時にコマンドオプションに以下の指定し、モジュールへの参照権限の指定が必要になります。
--add-modules module(,module, ...)
実行時にモジュールの追加が可能です。
--add-exports module/package=target-module(,target-module, ...)
実行時に、<module>/<package>を<target-module>からアクセス(exports)できるようにします。
--add-opens module/package=target-module(,target-module, ...)
実行時に、<module>/<package>を<target-module>からアクセス(opens)できるようにします。
これらの関係を示したのが図2です。
この記事は参考になりましたか?
- Java 9で「変わること」と、Javaのこれまで連載記事一覧
- この記事の著者
-
WINGSプロジェクト 小林 昌弘(コバヤシ マサヒロ)
< WINGSプロジェクト について> 有限会社 WINGSプロジェクト が運営する、テクニカル執筆コミュニティ(代表 ...
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
-
山田 祥寛(ヤマダ ヨシヒロ)
静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数。
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
この記事は参考になりましたか?
この記事をシェア
