All Libraries Should Follow a Zero-Dependency Policy

This hilarious article with a click-bait title caught my attention, recently:

View at Medium.com

A hilarious (although not so true or serious) rant about the current state of JavaScript development in the node ecosystem.

Dependency hell isn’t new

Dependency hell is a term that made it into wikipedia. It defines it as such:

Dependency hell is a colloquial term for the frustration of some software users who have installed software packages which have dependencies on specific versions of other software packages.

The big problem in dependency hell is the fact that small libraries pull in additional depedencies on which they rely in order to avoid too much code duplication. For instance, check out who is using Guava 18.0:
https://mvnrepository.com/artifact/com.google.guava/guava/18.0/usages

You’ll find libraries like:

  • com.fasterxml.jackson.core » jackson-databind
  • org.springframework » spring-context-support
  • org.reflections » reflections
  • org.joda » joda-convert
  • … 2000 more

Now, let’s assume you’re still using Guava 15.0 in your application. You want to upgrade Spring. Will your application still work? Is that upgrade binary compatible? Will Spring guarantee this to you, or are you on your own? Now what if Spring also uses Joda Time, which in turn also uses Guava? Does this even work? Conversely, can Guava ever depend on Joda Time or will a circular Maven Central dependency cause all singularities to collapse into one huge black hole?

Truth is: You don’t need the dependency

… and by you, I don’t mean the end user who writes complex enterprise applications with Guava (or whatever). You need it. But YOU, dear library developer. You certainly don’t need any dependency.

An example from jOOQ. Being a SQL string manipulation library, we pulled in a dependency on Apache Commons Lang because:

  • They have some nice StringUtils, which we like to use
  • Their license is also ASL 2.0, which is compatible to jOOQ’s license

But instead of hard wiring a jOOQ 3.x to commons-lang 2.x dependency, we opted for internalising one of their classes and only parts of it, repackaging it as org.jooq.tools.StringUtils. Essentially, we needed things like:

  • abbreviate()
  • isEmpty()
  • isBlank()
  • leftPad() (hello node developers)

… and some more. That certainly doesn’t justify pulling in the entire dependency, does it? Because while it wouldn’t matter to us, it would matter to our thousands of users, who might prefer to use an older or newer version of commons-lang. And that’s just the beginning. What if commons-lang had transitive dependencies? Etc.

Please, library developers, avoid dependencies

So, please, dear library developers. Please avoid adding dependencies to your libraries. The only things you should depend on are:

  • The JDK
  • Some API governed by a JSR (e.g. JPA)

That’s it. We can all start writing better software and stop downloading the whole internet if YOU the library developers start being reasonable and stop being lazy.

Exceptions to the above rules:

  • Framework and platform vendors (e.g. Spring, Java EE) are excluded. They define the whole platform, i.e. they impose a set of well-documented dependencies. If you’re using a framework / platform in your application, then you have to abide to the platform’s rules

That’s all. Small libraries like jOOQ must not have any dependency.

When to Use a Framework

I’ve come across this interesting article titled “Don’t Reinvent the Wheel! Use a Framework!” They All Say. The essence of the article lies in this little fact:

[When should “they” use a framework?”] When they understand the basics of the language and would be able to code what the framework/library does anyway

Frameworks and libraries are great because someone out there had spent a lot of time thinking about a very specific problem domain. Chances that they have gotten it right are very high BUT if you had enough time and money, you could build at least the useful parts of that framework yourself. Nonetheless, it’s cheaper to use/buy their code and have them maintain that part for you.

This is very true with JPA / Hibernate, for instance. If you know SQL and you know SQL well, then JPA does a great deal of helping you getting all that repetitive and often complex CRUD right, and you’ll even know how to tweak and tune JPA or the generated SQL where needed. Gavin King himself has said time and again:

Just because you’re using Hibernate, doesn’t mean you have to use it for everything. A point I’ve been making for about ten years now.

Hibernate helps you write some of your SQL, it doesn’t replace SQL. If you’re new to programming, you shouldn’t use Hibernate right away. You should first learn to write SQL and get a good understanding of your RDBMS. From my experience at conferences and JUG talks, this doesn’t only apply to junior programmers, though. It is very interesting to see how few seniors and architects know about window functions, for instance.

So, if you’re using an RDBMS and Hibernate/JPA, have your team be trained on all the layers of your technology. SQL, HQL/JPQL, and Java.