Saturday, February 02, 2013

Dependency Hell

Like Dependency Lock-in, another big problem in modular software development is Dependency Hell. I have a very recent example.

 +- org.apache.httpcomponents:httpclient:jar:4.2.3:compile  
 | +- org.apache.httpcomponents:httpcore:jar:4.2.2:compile  

You may be familiar with both and ask why I don't have the same version of httpclient and httpcore. Because that's the ways they work together.

If you use httpclient and also declare httpcore in your pom.xml, congratulations, you're making Dependency Hell. But what if you don't declare httpcore but httpclient gets updated and removes the dependency to httpcore, or depends on something else that provides http core function? Good luck. Spring Framework 3.2.1 made such a mistake and broke one of my hobby projects. The hell has different impact on component provider and consumer, but most of time, we're both component provider and consumer.

You shouldn't care about a component that your dependency depends on, and you shouldn't let any user of your component care about any component that your component depends on. If you break this, you break the fundamental principle of software component design. But in practice, unless you use OSGi [update 18/6/2020 - or Java 9 Platform Module System (JPMS)], you don't have easy ways to control how not to expose your dependencies to those components that directly, or indirectly, depend on your component.

Versioned jar files are the root of Dependency Hell in Java development. Check your pom file to see how many dependencies are redundant, they should be taken care of by direct dependencies; And how many dependencies should be upgraded to latest but you can't. Consider replace these outdated jar files with XaaS services?