META-INF / JAR中与摇篮服务(META-INF/services in JAR with

2019-07-03 14:35发布

我想建立一个可以装载一个插件模块ServiceLoader 。 这需要将文件添加到META-INF/services目录,即服务接口命名,并包含合格的路径,以实现它的类。 然后,你可以通过调用加载这些服务ServiceLoader.load()

下面是一个例子:

说,我们要提供一个叫做插件接口org.example.plugins.PluginService 。 然后,我们提供了类此服务的实现org.example.plugins.impl.ExamplePlugin

如果我们希望有某种插件机制,我们可以创建一个JAR文件,包含实现。 这个JAR文件还必须包含文件META-INF/services/org.example.plugins.PluginService 。 此文件必须包含一行

org.example.plugins.impl.ExamplePlugin

启用ServiceLoader找到执行。 如果该JAR文件在构建路径,你可以通过调用加载插件

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

这个迭代会给你访问过由找到的所有插件ServiceLoader

出于某种原因,摇篮不包括文件到META-INF默认目录。 有没有办法让产生的JAR包含这样的文件?

我已经找到了方法metaInfJar 。 但我不知道常规不够好找到我自己的解决方案。

Answer 1:

你把META-INF/services/org.example.plugins.PluginServicesrc/main/java ,但它不是一个来源,它是一个资源文件,因此应根据Maven的目录布局约定放在资源文件夹,也就是

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

在这种情况下,一切都应该工作开箱。



Answer 2:

同时,我发现在(有点)解决我的问题类似的问题 。

添加以下到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


Answer 3:

希望他们能在jar任务就像蚂蚁确实实现这一点。 有人已经工作就可以了: http://fgaliegue.blogspot.fr/2013/06/gradle-serviceloader-support.html



Answer 4:

如果你碰巧继承不遵循Maven的约定一些基于蚂蚁遗留代码,下面可能会有帮助。

定义你的源组,以满足传统的结构,包括像这样的一行:

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' }
    }
}


Answer 5:

嗨可以试试这个: https://plugins.gradle.org/plugin/com.github.harbby.gradle.serviceloader

用法

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


文章来源: META-INF/services in JAR with Gradle