17

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?

André Alves
  • 245
  • 1
  • 2
  • 12

9 Answers9

21

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.

devlearn
  • 1,725
  • 2
  • 17
  • 30
  • 2
    Thank you for answering, but i cant remove the older guava version, doesn't belong to my code. – André Alves Feb 02 '16 at 17:33
  • Actually i solve it with that solution, so thank you! – André Alves Feb 02 '16 at 18:25
  • When I remove the old version, it still throw exception, because the old lib can not use guava.18, how can I fix this. – Jack Apr 22 '16 at 17:31
  • Just one comment about this solution: `mvn dependency:tree` does not always work, especially when working with fat-jars (because maven does not see these included dependencies). I found this out the hard way. To get a clue about these "classpath-problems", I'm using `org.basepom.maven:duplicate-finder-maven-plugin` for detection. – FibreFoX Jun 07 '16 at 09:42
  • 3
    Please note that the given exclusion sample does not have correct group and artifact id. (groupId should be _com.google.guava_ and sample artifactId _guava-jdk5_) Copy-paste incident :D – Sergiu Indrie Oct 11 '16 at 09:26
  • find the dependency with `mvn dependency:tree -Dincludes=com.google.guava` – electrobabe Feb 04 '17 at 18:36
4

I add the correct dependency of elasticsearch resolve the problem

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>18.0</version>
</dependency>
Robin Wang
  • 779
  • 1
  • 8
  • 16
1

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/

Gary Gauh
  • 4,984
  • 5
  • 30
  • 43
1

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>
mjj1409
  • 3,075
  • 6
  • 28
  • 28
1

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.

tariq abughofa
  • 101
  • 1
  • 1
  • 8
0

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.

  • I see there is a *pom.xml* file in my project that is dynamically created using Guava version `24.0-jre`. Therefore I have added that version in my Gradle dependency however I am still seeing the error above. – AdamHurwitz Oct 17 '18 at 23:01
0

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>
Himadri
  • 150
  • 2
  • 11
  • This did not solve the issue for me @Himadri. As I can see from running the `gradle dependencies` command there are multiple versions of Guava being used in other libraries which seems related to this issue. – AdamHurwitz Oct 17 '18 at 23:02
0

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:

image

itsmysterybox
  • 2,748
  • 3
  • 21
  • 26
0

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
)
Rajiv Singh
  • 958
  • 1
  • 9
  • 14