Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use multiple Guava versions in 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 both contain a different version 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 backward compatible. Therefore I kind of need both jars.

The error - I get - is the following:

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

This has already reported here: https://issues.apache.org/jira/browse/HADOOP-10961

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

Which I tried 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

like image 786
Felix Avatar asked Feb 06 '15 14:02

Felix


People also ask

Which dependency lets maven distinguish between multiple artifacts that are generated from the same project?

Maven can automatically bring in these artifacts, also called transitive dependencies. Version collision happens when multiple dependencies link to the same artifact, but use different versions.

What will happen if the Maven version number of POM XML file does not match with the machine used to install?

Maven won't allow any other either. Build will fail if version is not found.

What does omitted for duplicate mean?

"Omitted for..." means that a dependency wasn't included, because it was either already included earlier, or because it conflicts with a dependency that was already included but has a different version. "Omitted for duplicate" is fine, and happens a lot.

What is the correct syntax for executing a Maven plugin?

Usage of a Maven Plugin xml you can use the shorthand notation to execute the plugin: mvn <prefix>:<goal> , commonly the “prefix” is the artifact ID minus the “-maven-plugin”. For example mvn example:version .


1 Answers

I would suggest finding the latest version of Guava that functions with Hadoop 2.4 and including that as an explicit dependency. Then exclude Guava from being fetched transiently from the closure compiler and Hadoop deps.

I'd suggest v16 as that still has the zero-args constructor on the StopWatch class: see Guava 16

Of course this solution depends on Guava 16 working with the closure compiler.

like image 108
Will Avatar answered Nov 15 '22 14:11

Will