Java – Use multiple versions of Guava in the same Maven project

Use multiple versions of Guava in the same Maven project… here is a solution to the problem.

Use multiple versions of Guava in the same Maven project

I have the following two dependencies in my project:

<dependency>
  <groupId>com.google.javascript</groupId>
  <artifactId>closure-compiler</artifactId>
  <version>v20141215</version>
  <exclusions>
      <exclusion>
          <groupId>com.google.protobuf</groupId>
          <artifactId>protobuf-java</artifactId>
      </exclusion>
  </exclusions>
</dependency>

<dependency>
  <groupId>org.apache.hadoop</groupId>
  <artifactId>hadoop-common</artifactId>
  <version>2.4.0</version>
</dependency>

As you can see in the dependency tree, they all contain different versions of Guava:

[INFO] --- maven-dependency-plugin:2.1:tree (default-cli) @ extraction ---

[INFO] +- com.google.javascript:closure-compiler:jar:v20141215:compile
[INFO] |  +- com.google.javascript:closure-compiler-externs:jar:v20141215:compile
[INFO] |  +- args4j:args4j:jar:2.0.26:compile
[INFO] |  +- com.google.guava:guava:jar:18.0:compile
[INFO] |  +- com.google.code.gson:gson:jar:2.2.4:compile
[INFO] |  \- com.google.code.findbugs:jsr305:jar:1.3.9:compile
[INFO] +- org.apache.hadoop:hadoop-common:jar:2.4.0:compile
[INFO] |  +- org.apache.hadoop:hadoop-annotations:jar:2.4.0:compile
[INFO] |  |  \- jdk.tools:jdk.tools:jar:1.7:system
[INFO] |  +- (com.google.guava:guava:jar:11.0.2:compile - omitted for conflict with 18.0)
[INFO] |  +- ...

The well-known problem is that Guava is not backwards compatible. So I need two jars.

The error I get is as follows:

Error:  tried to access method com.google.common.base.Stopwatch.<init>()V from class org.apache.hadoop.mapreduce.lib.input.FileInputFormat

It has been reported here: https://issues.apache.org/jira/browse/HADOOP-10961

Also, they recommend using the shading Maven plugin to handle it:
https://groups.google.com/a/cloudera.org/forum/#!topic/cdh-user/d5_HqUSvVl4

I tried it here :

<build>
<plugins>
   <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.1</version>
        <configuration>
            <source>1.6</source> <!-- If you want to use Java 8, change this to "1.8" -->
            <target>1.6</target> <!-- If you want to use Java 8, change this to "1.8" -->
        </configuration>
    </plugin>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>2.3</version>
        <executions>
            <execution>
                <phase>package</phase>
                <goals>
                    <goal>shade</goal>
                </goals>
                <configuration>
                    <relocations>
                        <relocation>
                            <pattern>com.google</pattern>
                            <shadedPattern>project.shaded.com.google</shadedPattern>
                        </relocation>
                    </relocations>
                </configuration>
            </execution>
        </executions>
    </plugin>
</plugins>
</build>

But I still get the same error.

Can anyone help me with this Maven issue?

Thank you
Felix

Solution

I recommend finding the latest version of Guava running with Hadoop 2.4 and including it as an explicit dependency. Guava is then excluded from instantaneous fetching from closure compilers and Hadoop deps.

I recommend v16 because it still has a zero-argument constructor on the StopWatch class: see Guava 16

Of course, this solution depends on Guava 16 using the closure compiler.

Related Problems and Solutions