1. ホーム
  2. java

[解決済み] Mavenを使用してJARの "META-INF/services "フォルダに設定ファイルをインクルードする方法

2023-06-02 18:46:04

質問

私は Maven を使用して構築された Eclipse の Java プロジェクトで作業しています。古いプロジェクトからリサイクルされたコードを使用していますが、これらのクラスの 1 つが META-INF/services フォルダーにある特定の名前のファイルを探し、そのファイルのテキストを解析します。この特定の例では、Java インターフェイスの名前を持つファイルを探し、そのファイルの中から実装のクラス名を取得します。

つまり、基本的に私がやろうとしていることは JARの"META-INF/services"フォルダにファイル名(X)と1行のテキスト(Y)を持つファイルをインクルードすることです。 . 私はこれがMavenを使用して、多分POMファイルで属性を指定することによって行われるべきであると推測していますが、私の研究は何も発見していません。私はあなたがハードコードまたは手動でMETAファイルを入力することになっていないことを知っているので、私はここで何をすべきかわかりません。

どのように解決するのですか?

新しいソースフォルダを作成する を作成し、その場所を src/main/resources を作成し、次に META-INF/services フォルダを作成し、完全修飾クラス名 (FQCN) ファイルをドロップしてください。これで、自動的にjarファイルにコピーされるはずです。つまり、FQCNが com.acme.MyInterface の実装では、こうなります。

Project
| src
| | main
|   | java
|     | [your source code]
|   | resources
|     | META-INF
|       | services
|         | com.acme.MyInterface

なお com.acme.MyInterface はファイル名であり、Javaのパッケージのようなディレクトリ構造ではありません。ファイル名は実装するインターフェースのFQCNで、その中に、例えば、各実装のFQCNをそれぞれの行に記述することになります。

com.example.MyInterfaceImpl
com.example.AnotherMyInterfaceImpl

これは、デフォルトのソースセットを持つGradleプロジェクトにも適用されることは注目に値します。

一度これを行うと、インターフェイスのすべての実装をロードすることができます。 ServiceLoader :

ServiceLoader<MyInterface> loader = ServiceLoader.load(MyInterface.class);
for (MyInterface service : loader) {
    // Prints com.example.MyInterfaceImpl and com.example.AnotherMyInterfaceImpl
    System.out.println(service.class.getName());
}

いくつか注意することがあります。

  • すべての実装は、引数なしのコンストラクタを持たなければなりません。
  • モジュールやカスタムのクラスローダを使うアプリケーションは、 オーバーロードされた ServiceLoader.load

これらの条件でうまくいかない場合は、他のシステム、例えばSpringやEJBなどのCDIスタイルのフレームワークに切り替えるとよいでしょう。