I've seen a few build tools in my career, and they've all had their quirks. I'm just now looking into Maven, and came across the idea of "dependency exclusions" for the first time. I honestly don't understand which legitimate problem this mechanism is trying to solve.
Let's take the POM of Apache Pig, for example:
<project xmlns="http://maven.apache.org/POM/4.0.0"> <modelVersion>4.0.0</modelVersion> <groupId>org.apache.pig</groupId> <artifactId>pig</artifactId> <packaging>jar</packaging> <version>0.16.0.2.5.0.0-1245</version> <dependencies> <!-- ... --> <dependency> <groupId>org.apache.avro</groupId> <artifactId>avro</artifactId> <version>1.7.4</version> <exclusions> <exclusion> <!-- Don't pull in Avro's (later) version of Jetty. --> <groupId>org.mortbay.jetty</groupId> <artifactId>jetty</artifactId> </exclusion> <exclusion> <!-- Exclude Avro's version of ant since it conflicts with Jetty's. --> <groupId>org.apache.ant</groupId> <artifactId>ant</artifactId> </exclusion> </exclusions> </dependency> <!-- ... --> </dependencies> <!-- ... --> </project>
This particular project depends on the
avro artifact from the
org.apache.avro group, but removes two dependencies from that dependency (namely
ant) because they "conflict". Apparently, it's perfectly fine to remove these dependencies from
avro, as the ones included by
pig will do.
To me, this sounds like asking for trouble, and I'd think that any other resolution of dependency conflicts would be preferred over it.
By meddling with the dependencies of a dependency, the Pig project is effectively patching the Avro project, and quite blindly too, as the version constraint on Avro does not strictly identify one release of the project.
Wouldn't it make more sense to either reject the build altogether, or build in two separate versions of both
jetty into the project (assuming they can be kept segregated in Java's class loader system)?