问题
While creating Elasticsearch Client, I'm getting the exception java.lang.NoSuchMethodError: com.google.common.util.concurrent.MoreExecutors.directExecutor()Ljava/util/concurrent/Executor; After some lookup, seams like the Guava-18 is being overwrite by an older version at runtime, and Guava-18 only works during compile task.
My Maven configuration is the follow:
<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>
How can i force the Guava-18 version at execution time?
回答1:
You should try to find where the "old" version of guava is taken from and to exclude it once for all.
Find the dependency :
mvn dependency:tree | grep guava
Exclude it :
<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>
See https://maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html for more info on the dependency exclusion.
回答2:
I add the correct dependency of elasticsearch resolve the problem
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
回答3:
I was also seeing the error message mentioned by the OP when creating an Elasticsearch Client instance. In my case it was occurring in a Spring Boot app at application startup. Spring Boot was attempting to auto-configure the Elasticsearch Client via dependencies brought in by spring-boot-starter-data-elasticsearch
. The underlying guava version being brought in was:
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
This was all working fine until I introduced the following google-api-client
dependency...
<dependency>
<groupId>com.google.api-client</groupId>
<artifactId>google-api-client</artifactId>
<version>1.23.0</version>
</dependency>
...which depends on following guava dependency:
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava-jdk5</artifactId>
<version>17.0</version>
</dependency>
This caused a class path collision and the fix was to exclude the older guava version from the google-api-client
like so:
<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>
回答4:
Add a dependencyManagement
block solves this problem:
<dependencyManagement>
<!-- enforce dependency guava version 20.0 -->
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>20.0</version>
</dependency>
</dependencies>
</dependencyManagement>
Reference:
http://techidiocy.com/maven-dependency-version-conflict-problem-and-resolution/
回答5:
I had a similar problem. I created a .jar file (Java source), then I wanted to load that file into the Spark Shell. It turns out that Spark Shell loads jars from something similar to this spark-[version]-bin-hadoop[version]/jars/".
That directory had an older version of the guava which causes the error. I had the correct version in my pom.xml. I even added exclusions and all suggested responses. In conclusion, it is indeed a wrong version of guava. I copied the version that matches my pom.xml file. Hope this helps. Regards.
回答6:
SOLVED: I updated the Guava dependency to latest version and it solved the
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>latest</version>
</dependency>
回答7:
I was struggling with this issue from past 2 months and finally found the solution.
I added too many external jars in my Project Structure which actually created some jars in Library Root resulting in conflicts whenever something is added in pom.xml.
So what needs to be done is delete all external jar files from your project and keep only the ones which are from maven like Maven:org...
My project structure:

回答8:
For SBT solution:
Use shading the library in 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
)
回答9:
The best soltion is to use the shade plugin for maven. Adding this to your pom.xml should fix it:
<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>
This will create an upper jar with the same name including only a shaded guava inside.
来源:https://stackoverflow.com/questions/35157642/nosuchmethoderror-com-google-common-util-concurrent-moreexecutors-directexecuto