Java9のモジュール機構
サービスプロバイダーを作ってみよう Java8以前ではJavaのサービスプロバイダーを作った。このときはjarの中にMETA-INF/services/ファイルを配置したけど、Java9以降ではこの辺に新しいやり方が導入されている。
まずはJava8以前と同様にサービス、サービスプロバイダー、アプリケーションを作っていこう。
※.java自体はJava8以前と同じ。
サービス
まずはサービスのインターフェースを定義する。local/api/MyService.java
package local.api; public interface MyService { void show(); }Java8と違うところは、MyServiceをjarの外部に公開するためにmodule-info.javaを用意するところ。
META-INF/servicesと違いコンパイル時に必要となる。
module-info.java
module local.api { exports local.api; uses local.api.MyService; }これによってlocal.apiパッケージのMyServiceがjarの外部に公開される。
これをコンパイルしてjarにする。
$ javac -d bin src/*.java src/local/api/*.java $ jar --create --file local-api.jar -C bin .
サービスプロバイダー
次にサービスプロバイダー。試しに2つ作ってみる。local/provider/MyServiceProvider1.java
package local.provider; import local.api.MyService; public class MyServiceProvider1 implements MyService { @Override public void show() { System.out.println("MyService1"); }; }local/provider/MyServiceProvider2.java
package local.provider; import local.api.MyService; public class MyServiceProvider2 implements MyService { @Override public void show() { System.out.println("MyService2"); }; }これもMETA-INF/servicesではなく、module-info.javaを作成する。
今度はrequiresで外部から取り込むパッケージを指定して、providesでサービスを実装するサービスプロバイダーを指定する。
module-info.java
module local.provider { requires local.api; provides local.api.MyService with local.provider.MyServiceProvider1, local.provider.MyServiceProvider2; }これをコンパイルしてjarにする。
$ javac -d bin --module-path ../api src/*.java src/local/provider/*.java $ jar --create --file local-provider.jar -C bin .
アプリケーション
最後にサービスプロバイダーを実行するアプリケーションを作成する。local/app/Main.java
package local.app; import java.util.ServiceLoader; import local.api.MyService; public class Main { public static void main(String ... args) { for (MyService service : ServiceLoader.load(MyService.class)) { System.out.println(service.getClass().getName()); service.show(); } } }module-info.java
module local.app { requires local.api; uses local.api.MyService; }
$ javac -d bin --module-path ../api src/*.java src/local/app/*.java $ jar --create --file local-app.jar -C bin .
実行
すべてのjarができたので、実行してみよう。jarをlibに集めておく。$ ls lib local-api.jar local-app.jar local-provider.jar $ java --module-path lib --module local.app/local.app.Main local.provider.MyServiceProvider1 MyService1 local.provider.MyServiceProvider2 MyService2
全体のディレクトリイメージ
$ tree . ├── api │ ├── bin │ │ ├── module-info.class │ │ └── local │ │ └── api │ │ └── MyService.class │ ├── local-api.jar │ └── src │ ├── module-info.java │ └── local │ └── api │ └── MyService.java ├── app │ ├── bin │ │ ├── module-info.class │ │ └── local │ │ └── app │ │ └── Main.class │ ├── local-app.jar │ └── src │ ├── module-info.java │ └── local │ └── app │ └── Main.java ├── lib │ ├── local-api.jar │ ├── local-app.jar │ └── local-provider.jar └── provider ├── bin │ ├── module-info.class │ └── local │ └── provider │ ├── MyServiceProvider1.class │ └── MyServiceProvider2.class ├── local-provider.jar └── src ├── module-info.java └── local └── provider ├── MyServiceProvider1.java └── MyServiceProvider2.java
0 件のコメント:
コメントを投稿