在我的build.gradle文件中,我需要添加以下行:
shadowJar {
mergeServiceFiles()
}
否则jar无法正常运行。我想知道这条线到底是做什么的? 我在Eclipse Luna中使用Gradle插件。我在一个Java项目上创建了jar,这个项目依赖于另一个项目。
答案 0 :(得分:8)
为什么不自己在代码中进行调查? mergeServiceFiles
被正确声明为here,其实现如下:
/**
* Syntactic sugar for merging service files in JARs
* @return
*/
public ShadowJar mergeServiceFiles() {
try {
transform(ServiceFileTransformer.class);
} catch (IllegalAccessException e) {
} catch (InstantiationException e) {
}
return this;
}
如您所见,它使用ServiceFileTransfomer
定义here。来自其文档:
从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。
答案 1 :(得分:0)
TL;DR - 合并 META-INF/services 文件夹中的服务文件。
长答案
某些库(例如 Micronaut)在 META-INF/services
文件夹中创建了一些服务文件。这些文件可以包含任何在运行时有用的信息。在 Micronaut 框架的情况下,它会创建一个文件,在 io.micronaut.inject.BeanDefinitionReference
下名为 META-INF/services
的文件中列出 Bean 引用(或实例化的 Bean)。
通常,如果您只有一个应用程序,即使没有 mergeServiceFiles()
也能正常工作。但是,如果您将两个 micronaut 项目捆绑到一个 jar 中(例如,带有一些实用程序的 micronaut lib
项目和带有核心业务逻辑的 micronaut app
项目),您将有两个 {{1 }}。每个都将包含它自己项目的 bean。
如果您不使用 io.micronaut.inject.BeanDefinitionReference
,mergeServiceFiles()
文件之一将被另一个覆盖。在这种情况下,您将收到一个运行时异常,表示 BeanDefinitionReference
或类似的内容。
使用 BeanNotInstantiated
合并(或在这种情况下连接)两个项目的 mergeServiceFiles()
文件,以便在运行时获得定义的所有 bean。
可在 gradle 论坛主题 here 中找到更多详细信息。