In my project there is a class implementing an interface. The interface comes from a dependency. I have another dependency that itself has a dependency on a jar that also contains the same interface, except a version with more methods; the two jars containing the same package-interface DON’T have the same groupId or artifactId.
Compilation is failing because the compiler complains that the class in my project is not implementing all the methods. I realized it is because the compiler is taking the interface reference from the wrong jar. My question is, why is maven using the interface from the transitive dependency instead of the one from the jar that I explicitly mention in the project POM? I can see the jar that is used appears earlier in the definition (so i imagine in the classpath as well), but i thought in these cases maven resolved it by using the colliding class/interface from the dependency with the shortest path
Here is part of the dependency tree. Note that this is grepped but it can still be seen that javax.servlet:servlet-api (the one actually used) is deeper in the tree compared to tomcat:servlet (the one that should be used)
[builder@ca-rd-build11 proj]$ mvn dependency:tree | grep servlet
[INFO] | +- javax.servlet:servlet-api:jar:2.4:compile
[INFO] +- tomcat:servlet:jar:4.0.6:compile
I’m using maven 3.0.4
Because, to Maven, the two have nothing to do with each other. Maven doesn’t know about class or package names, Maven just knows about groupId and artifactId. Since those are not the same, maven doesn’t have any reason to omit the transitive dependency.
And if I am correct, Maven places the dependencies on the classpath in the order they are defined, i.e. the transitive dependencies of dependency
aappear before dependencyb.