java - 当库使用 gradle 使用 SPI 时,如何正确输出 META-INF?

标签 java hadoop gradle lucene build.gradle

我正在尝试使用 Gradle 和 Java 制作一个测试应用程序,该应用程序使用多个使用 Java 服务提供程序接口(interface)的库。我认为这意味着我需要修改 META-INF 但我不确定该怎么做。

我得到的错误是 An SPI class of type org.apache.lucene.codecs.codec with nameLucene50does not exist。您需要将支持此 SPI 的相应 JAR 文件添加到您的类路径中。当前类路径支持以下名称[SimpleText]

我认为我需要将 SPI 信息放入 META-INF,但我不确定如何使用 Gradle 执行此操作。

具体来说,我正在尝试在以下构建文件中使用 Lucene 和 Hadoop jar:

apply plugin: 'java'

sourceCompatibility = 1.8
version = '1.0'

repositories {
    mavenCentral()
}

dependencies {
    compile group:'org.apache.lucene', name:'lucene-core', version:'5.0.0'
    compile group:'org.apache.lucene', name:'lucene-queryparser', version:'5.0.0'
    compile group:'org.apache.lucene', name:'lucene-analyzers-common', version:'5.0.0'
    compile group:'org.apache.lucene', name:'lucene-facet', version:'5.0.0'
    compile group:'org.apache.lucene', name:'lucene-codecs', version:'5.0.0'

    compile group:'org.apache.hadoop', name:'hadoop-hdfs', version:'2.6.0'
    compile group:'org.apache.hadoop', name:'hadoop-core', version:'1.2.1'
    compile group:'org.apache.hadoop', name:'hadoop-common', version:'2.6.0'

}

jar
        {

                from {configurations.compile.collect {it.isDirectory() ?it:zipTree(it) }}
                manifest
                        {
                            attributes 'Main-Class': 'LuceneTest'
                        }
        }

最佳答案

lucene-corelucene-codecs 库都提供了 org.apache.lucene.codecs.Codec 实现,所以它们都有META-INF/services/org.apache.lucene.codecs.Codec 服务文件。当您合并所有依赖项时,两个文件都会添加到 jar 文件中,但 Lucene 只会看到 lucene-codecs 一个。您可以在 jar 任务中手动合并服务文件,如 this post ,它基本上找到所有服务文件并将它们组合起来。更简单的解决方案可能是使用类似 Gradle Shadow plugin 的东西.

如果您将此添加到 build.gradle,使用 shadowJar 任务而不是 jar 任务应该可以完成您想要的操作。

buildscript {
  repositories { jcenter() }
  dependencies {
    classpath 'com.github.jengelman.gradle.plugins:shadow:1.2.1'
  }
}
apply plugin: 'com.github.johnrengelman.shadow'
shadowJar {
  mergeServiceFiles()
}

关于java - 当库使用 gradle 使用 SPI 时,如何正确输出 META-INF?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29614796/

相关文章:

android - Sceneform 的 Gradle 问题 - 程序类型已存在 : com. google.ar.schemas.lull

java - 从 Android Studio 项目中删除 Android(app 或 lib)模块需要在每次项目启动时将项目与 gradle 文件同步

gradle - Eclipse JDT LS 和 Gradle - 资源异常 "Invalid project description"

java - Spring Boot PropertyPlaceholderConfigurer 无法从环境中获得

java - 验证 Java 中反射方法的返回类型和参数

java - URL 的 PATH 段中是否允许使用 "&"符号?

java - 关于java的5个问题

java - 错误 : cannot access org. apache.hadoop.mapred.MapReduceBase

hadoop - 具有广泛开放权限的目录如何抛出 EPERM 错误(hadoop)?

hadoop - 如何将新数据附加到现有的配置单元表