Apache Ivy: Elegant Dependency Management (and not much else)


I decided to give Apache Ivy a try. I was looking at an old Ant build, and I was toying around with the idea of just “adapting” it to a repository manager. I fooled around with Ivy a bit. Had it retrieve some artifacts from an “ibiblio” repository type. Ivy, for some reason, calls the Maven repository format an ibiblio format. This would make sense five years ago, but now it is just an odd anachronism.

After getting a basic build working with an existing Ant build.xml file, I was able to craft a classpath with identifiers and connect the build to a repository manager. There is some confusing documentation out there wrt connecting Ivy to a repository manager. Maybe I was just confused by the fact that, while 95% of Ivy users connect to the Central Maven repository and they have a different set of identifiers (“organization” isn’t a direct match for “groupId”). You have to configure “resolvers”, and here’s where I just start to lose track of what these people are trying to do. They’ve gone and given you, the consumer the responsibility of defining the pattern used in a repository. Here’s an example (try to ignore the fact that organization is really a groupId):

    
        
	
    

Apache Ivy appears to solve a sliver of the larger problem Maven solves: dependency management. Dependency conflicts are the boogey man in the closet for Ivy users, it is one of the prime motivators for adopting Ivy. I guess someone, somewhere was once overwhelmed by a difficult to debug Maven dependency conflict so they decided to abandon the tool and create Ivy. One of the other reasons for Ivy is that it will allow you to have different classpaths in the same project. This is something that is important if your project is one of those “we put everything in the same source tree” approaches to coding. Ivy (obstensibly) does all of this with greater elegance and control, but I can’t for the life of me understand why using a tool like Ivy is somehow preferable to learning how to use exclusions in a Maven POM. Unless, of course, Apache Ivy is just an excuse for people to avoid having to use Maven.

I’m about an hour into the effort, and I’m already doubting success. This shouldn’t be a big surprise…. I’m a Maven partisan. I believe it to be the best solution, I’ll gladly recommend it, but I’m always open to alternatives. I do continue to believe that the important differentiator for most people is the use of a repository manager. So, that’s what I was trying to figure out…. Could I use Ivy to publish artifacts to a repository manager? Artifacts that could be consumed by other projects.

Verdict: Yes and no. Ivy will read artifacts from traditional Maven repositories. The Ivy project maintains code to parse a Maven POM, so it can read from Maven Central and it can resolve dependencies properly. Once you’ve created a classpath, it is fairly straightforward to turn this into a classpath that you can pass to the javac task. I was able to successfully publish to a repository manager, but that’s where my problems started. Ivy doesn’t publish a POM by default, it publishes some ivy.xml file (which is useless for the majority of users). You have to specifically call out to a makepom task and upload it as a separate artifact.

In other words: this is a hell of a lot of work just to get Ivy to publish to the repository format it read from. Really the only way you are going to start using Ivy and publishing artifacts to repositories is if you bypass this makepom task and start crafting your own POMs. If you are crafting your own POMs it sort of begs the question: why not just use Maven?

Documentation… I wish this thing was as well documented as Maven

The documentation! To think that people complain about the Maven documentatiion. Unbelievably, it makes some snarky reference to the Maven documentation as being bad. Going out on a limb here…. that’s no longer true. Maven’s got great documentation. If you don’t believe me, I’ll send you an encyclopedia of well written books.

Ivy’s documentation suffers from the same problem Maven’s documentation had in 2005. Little editorial control, and a large number people collaborating without an outline. Add to that the fact that most open source projects tend to span a few continents and you have many pages on the Ivy site with odd word choice problems and idioms translated from one language to another (and back).

Publish Task: A simple example? No luck.

No one publishes artifacts with Ivy, and if they do, they are a very small minority of Ivy users. The Ant tasks for publishing artifacts are inscrutable. Here take this fun Ivy Ant task as an example:

   
   

This snippet has a note below it: “Publishes the last resolved module in the local resolver with revision 1.0, looking for artifacts in directories 1 and 2.” Right. What are these “1” and “2” directories? Oh wait, there is no standard directory layout for these projects because this is Ant, and everyone is free to just do *whatever*.

If you are going to publish? you need to deliver your descriptors (for publishing). (huh?)

Here’s just a sampling of the fun that awaits those you want to publish JARs from an Ivy project.

“During the module development time, between publications, the descriptor helps in managing all the possibly changing dependencies of the module. For that purpose, development time ivy files can declare dynamic dependencies to allow for a greater flexibility of use.”

Right, so then you go further down the rabbit hole and realize that you need to maintain a “Resolved descriptor for publishing” which can be automatically generated using the “deliver” Ant task which evidently: “Deliver(s) a resolved descriptor of the current module, and possibly perform(s) a recursive delivery of dependencies.”

Cater to the Control Freaks

People who are attracted to Ivy are holding on to the idea that they *really* want to write Ant scripts. They don’t just want to have control over (read responsibility for) the build logic, they want to be able to control the format of the repository. Not only do these people want to create an inscrutable, customized build system, they want to create inscrutably awful chains of resolvers (repositories) and mix and match repository formats.

Conclusion

So, after investing a couple of hours in this insanity, how is any of this simpler or more straightforward than declaring some identifiers in a Maven pom.xml? Answer: It totally isn’t. People clinging on to Ivy, are doing so because they have some other axe to grind. Maybe they feel threatened because they’ve invested heavily in obtuse Ant scripts?

Really the only contender at the moment is Gradle, and I am keen to take a quick look at Gradle. I really am, and not just so I can predictably whine about the parts I dislike. I’m keeping an open mind, and I want to see what attracted Ebersole to the tool.