30

でロードできるプラグインモジュールを作成したかったの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

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

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

4

5 に答える 5

49

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

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

この場合、すべてが箱から出して動作するはずです。

于 2012-11-06T19:23:07.057 に答える
7

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

以下をファイルに追加すると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
于 2012-11-06T19:10:44.530 に答える
1

Mavenの規則に従わないantベースのレガシーコードをたまたま継承する場合は、次のことが役立つ場合があります。

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

include 'META-INF/services/**'

ソースセット内。このパターンは一般的であり、すべてのメタ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' }
    }
}
于 2016-04-26T14:24:39.257 に答える
0

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

于 2013-07-16T07:29:46.990 に答える
0

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

使用法

serviceLoader {
    serviceInterface 'org.example.plugins.PluginService'
    serviceInterface 'org.example.plugins.PluginService2'
}
于 2018-08-21T03:15:21.037 に答える