Shadow Plugin Gradle:mergeServiceFiles()有什么作用?

Rom*_*ain 14 java gradle build.gradle gradle-shadow-plugin

在我的build.gradle文件中,我需要添加以下行:

shadowJar {
    mergeServiceFiles()
}
Run Code Online (Sandbox Code Playgroud)

否则罐子不能正常运行.我想知道这条线到底是做什么的?我在Eclipse Luna中使用Gradle插件.我在一个Java项目上创建了jar,它取决于另一个Java项目.

Opa*_*pal 8

你为什么不自己在代码中调查呢?mergeServiceFiles正好在这里声明,其实现如下:

/**
 * Syntactic sugar for merging service files in JARs
 * @return
 */
public ShadowJar mergeServiceFiles() {
    try {
        transform(ServiceFileTransformer.class);
    } catch (IllegalAccessException e) {
    } catch (InstantiationException e) {
    }
    return this;
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,它使用了此处ServiceFileTransfomer定义的内容.从它的文档:

从org.apache.maven.plugins.shade.resource.ServiceResourceTransformer.java修改

将META-INF /服务资源中的条目附加到单个资源中的资源转换器.例如,如果有多个META-INF/services/org.apache.maven.project.ProjectBuilder资源分布在多个JAR中,则各个条目将连接成一个META-INF/services/org.apache.maven.project. .ProjectBuilder资源打包到由着色过程生成的结果JAR中.


Shr*_*ath 5

TL;DR - 它合并 META-INF/services 文件夹中的服务文件。

长答案

一些库(例如 Micronaut)会在文件夹中创建一些服务文件META-INF/services。这些文件可以包含运行时有用的任何信息。对于 Micronaut 框架,它会创建一个文件,其中列出了 Bean 引用(或实例化的 Bean io.micronaut.inject.BeanDefinitionReferenceMETA-INF/services

通常,如果您只有一个应用程序,即使没有mergeServiceFiles(). 但是,如果您将两个 micronaut 项目捆绑到一个 jar 中(例如,一个lib带有一些 utils 的 micronaut 项目和一个app带有核心业务逻辑的 micronaut 项目),那么您将拥有两个io.micronaut.inject.BeanDefinitionReference. 每一个都包含它自己项目的 bean。

如果不使用mergeServiceFiles(),其中一个BeanDefinitionReference文件将被另一个文件覆盖。在这种情况下,您将收到运行时异常BeanNotInstantiated或类似的信息。

使用mergeServiceFiles()合并(或在本例中连接)BeanDefinitionReference两个项目的文件,以便在运行时获得定义的所有 bean。

更多详细信息可以在此处的gradle 论坛主题中找到。