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
を見つけました。しかし、私は自分で解決策を見つけるのに十分なグルーヴィーさを知りません。
あなたが配置するMETA-INF/services/org.example.plugins.PluginService
in src/main/Java
、しかしそれはソースではなく、それはリソースファイルなので、Mavenディレクトリのレイアウト規則に従ってリソースフォルダーに配置する必要があります。
src/main/resources/META-INF/services/org.example.plugins.PluginService
この場合、すべてがそのまま動作します。
その間、私は問題の解決策を(やや) 同様の質問 で見つけました。
以下を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
うまくいけば、antと同じようにjarタスクでこれを実装します。誰かがすでにそれに取り組んでいます: http://fgaliegue.blogspot.fr/2013/06/gradle-serviceloader-support.html
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' }
}
}
こんにちはこれを試すことができます: https://plugins.gradle.org/plugin/com.github.harbby.gradle.serviceloader
使用法
serviceLoader {
serviceInterface 'org.example.plugins.PluginService'
serviceInterface 'org.example.plugins.PluginService2'
}