NoSuchMethodError: com.google.common.util.concurrent.MoreExecutors.directExecutor conflits on Elastic Search jar

NoSuchMethodError: com.google.common.util.concurrent.MoreExecutors.directExecutor conflits on Elastic Search jar

在创建 Elasticsearch 客户端时,我遇到异常 java.lang.NoSuchMethodError:com.google.common.util.concurrent.MoreExecutors.directExecutor()Ljava/util/concurrent/Executor; 经过一番查找后,像 Guava-18 这样的接缝在运行时被旧版本覆盖,而 Guava-18 仅在编译任务期间有效。

我的 Maven 配置如下:

    <build>
    <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.0</version>
            <configuration>
                <source>1.7</source>
                <target>1.7</target>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>2.4.1</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <transformers>
                            <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
                        </transformers>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

如何在执行时强制使用 Guava-18 版本?

您应该尝试找到 "old" 版本的 guava 的来源,并一劳永逸地排除它。

找到依赖关系:

mvn dependency:tree | grep guava

排除它:

<dependency>
  <groupId>org.whatever</groupId>
  <artifactId>the_lib_that_includes_guava</artifactId>
  <version>0.97</version>
  <exclusions>
    <exclusion>
      <artifactId>com.google</artifactId>
      <groupId>guava</groupId>
    </exclusion>
  </exclusions>
</dependency>

有关依赖项排除的详细信息,请参阅 https://maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html

添加一个dependencyManagement块解决了这个问题:

<dependencyManagement>
    <!-- enforce dependency guava version 20.0 -->
    <dependencies>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>20.0</version>
        </dependency>
    </dependencies>
</dependencyManagement>

参考:

http://techidiocy.com/maven-dependency-version-conflict-problem-and-resolution/

我添加正确的elasticsearch依赖解决问题

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>18.0</version>
</dependency>

我遇到了类似的问题。我创建了一个 .jar 文件(Java 源),然后我想将该文件加载到 Spark Shell .事实证明,Spark Shell 从类似于此的东西中加载罐子 spark-[版本]-bin-hadoop[版本]/jars/"

那个目录有导致错误的旧版本的番石榴。我的 pom.xml 中有正确的版本。我什至添加了排除项和所有建议的回复。综上所述,确实是guava版本错误。我复制了 匹配 我的 pom.xml 文件的版本。希望这可以帮助。问候。

已解决:我将 Guava 依赖更新到最新版本并解决了

 <!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>latest</version>
</dependency>

我在创建 Elasticsearch Client 实例时也看到了 OP 提到的错误消息。在我的例子中,它发生在应用程序启动时的 Spring 启动应用程序中。 Spring Boot 试图通过 spring-boot-starter-data-elasticsearch 引入的依赖项自动配置 Elasticsearch 客户端。引入的基础番石榴版本是:

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>18.0</version>
</dependency>

一切正常,直到我引入以下 google-api-client 依赖项...

<dependency>
    <groupId>com.google.api-client</groupId>
    <artifactId>google-api-client</artifactId>
    <version>1.23.0</version>
</dependency>

...depends on 以下番石榴依赖项:

<dependency>
      <groupId>com.google.guava</groupId>
      <artifactId>guava-jdk5</artifactId>
      <version>17.0</version>
</dependency>

这导致了 class 路径冲突,解决方法是从 google-api-client 中排除较旧的 guava 版本,如下所示:

<dependency>
    <groupId>com.google.api-client</groupId>
    <artifactId>google-api-client</artifactId>
    <version>1.23.0</version>
    <exclusions>
        <exclusion>
            <groupId>com.google.guava</groupId>
            <artifactId>guava-jdk5</artifactId>
        </exclusion>
    </exclusions>
</dependency>

过去 2 个月我一直在为这个问题苦苦挣扎,终于找到了解决方案。

我在项目结构中添加了太多外部 jar,实际上在 Library Root 中创建了一些 jar,导致在 pom.xml.[=11 中添加内容时发生冲突=]

所以需要做的是从项目中删除所有外部 jar 文件,只保留来自 Maven 的文件,例如 Maven:org...

我的项目结构:

对于 SBT 解决方案:

在build.sbt

中使用着色库
// Shading com.google.**
// We need com.google.guava above 18 version but spark uses version 14 and in that we don't have directExecutor() method
// as spark give preference to spark used libraries, our code was failing

assemblyShadeRules in assembly := Seq(
    ShadeRule.rename("com.google.**" -> "shadeio.@1").inAll
)

最好的解决方案是使用 maven 的 shade 插件。将此添加到您的 pom.xml 应该可以解决问题:

            <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>3.2.1</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <relocations>
                            <relocation>
                                <pattern>com.google.common</pattern>
                                <shadedPattern>shaded.com.google.common</shadedPattern>
                            </relocation>
                        </relocations>
                        <artifactSet>
                            <includes>
                                <include>com.google.guava:guava</include>
                            </includes>
                        </artifactSet>
                    </configuration>
                </execution>
            </executions>
        </plugin>

这将创建一个同名的上层罐子,其中仅包含一个阴影番石榴。