web-dev-qa-db-ja.com

Gradleを使用したJARのMETA-INF / services

ServiceLoader を使用してロードできるプラグインモジュールを構築したいと思いました。これには、_META-INF/services_ディレクトリにファイルを追加する必要があります。これは、サービスインターフェイスにちなんで名付けられ、ファイルを実装するクラスへの修飾パスを含んでいます。次に、ServiceLoader.load()を呼び出してこれらのサービスをロードできます。

次に例を示します。

_org.example.plugins.PluginService_というプラグインインターフェースを提供したいとします。次に、このサービスの実装をクラス_org.example.plugins.impl.ExamplePlugin_で提供します。

何らかのプラグインメカニズムが必要な場合は、実装を含むJARファイルを作成できます。このJARファイルには、ファイル_META-INF/services/org.example.plugins.PluginService_も含まれている必要があります。このファイルには1行が含まれている必要があります

_org.example.plugins.impl.ExamplePlugin
_

ServiceLoaderが実装を見つけられるようにします。そのJARファイルがビルドパスにある場合は、次を呼び出してプラグインをロードできます。

_Iterator<PluginService> it = ServiceLoader.load(PluginService.class).iterator();
_

そのイテレータは、ServiceLoaderによって検出されたすべてのプラグインにもアクセスできるようにします。

何らかの理由で、Gradleはデフォルトで_META-INF_ディレクトリにファイルを含めません。結果のJARにそのようなファイルを含める方法はありますか?

私はすでにクラスmetaInfにメソッド Jar を見つけました。しかし、私は自分で解決策を見つけるのに十分なグルーヴィーさを知りません。

23
pvorb

あなたが配置するMETA-INF/services/org.example.plugins.PluginService in src/main/Java、しかしそれはソースではなく、それはリソースファイルなので、Mavenディレクトリのレイアウト規則に従ってリソースフォルダーに配置する必要があります。

src/main/resources/META-INF/services/org.example.plugins.PluginService

この場合、すべてがそのまま動作します。

37
axtavt

その間、私は問題の解決策を(やや) 同様の質問 で見つけました。

以下をgradle.buildファイルに追加すると、問題が解決します

jar {
  from ('./src/main/Java') {
    include 'META-INF/services/org.example.plugins.PluginService'
  }
}

これでJARファイルは期待どおりに見えます

.
|- org
|  `- example
|     `- plugins
|        `- impl
|           `- ExamplePlugin.class
`- META-INF
   |- MANIFEST.MF
   `- services
      `- org.example.plugins.PluginService
6
pvorb

うまくいけば、antと同じようにjarタスクでこれを実装します。誰かがすでにそれに取り組んでいます: http://fgaliegue.blogspot.fr/2013/06/gradle-serviceloader-support.html

0
gyorgyabraham

Mavenの規則に従わないantベースのレガシーコードを継承する場合は、次の方法が役立ちます。

レガシー構造と一致するようにソースセットを定義し、次のような行を含めます。

include 'META-INF/services/**'

ソースセット。このパターンは一般的であり、すべてのmeta infサービスを取得します。

以下の完全な例。

sourceSets {
    main {
        Java {
            srcDir 'src'
            exclude '**/Test*.Java'
        }
        resources {
            srcDir 'src'
            include '**/*.xml'
            include 'META-INF/services/**'
        }
    }
    test {
        Java {
            srcDir 'src'
            include '**/Test*.Java'

        }
        resources { srcDir 'resources' }
    }
}
0
Jeremy Bunn

こんにちはこれを試すことができます: https://plugins.gradle.org/plugin/com.github.harbby.gradle.serviceloader

使用法

serviceLoader {
    serviceInterface 'org.example.plugins.PluginService'
    serviceInterface 'org.example.plugins.PluginService2'
}
0
ideal