Module packaging

So say I’ve got a simple project with 3 modules A, B and C. C depends on B. B depends on A. So I presume its OK to bundle up the class files and release it as the ABC library. Now say I decide it would be helpful for some purpose to package up and release A on its own. Am I right in saying its now a complete no-no to continue releasing ABC? From now on I must release BC, with A as a dependency?

Hmm. AFAIK, there’s nothing preventing you from doing it, and I don’t think there’s any clear community standard on the subject.

It seems like the real issue is whether it worsens the risk of potential transitive version skews for your users, and I’m honestly unsure about this one. That is, what are the odds that:

  • Third-party library D depends on version A1
  • An application picks up D and ABC2
  • Boom! at runtime, because D expects A1, but it’s been evicted in favor of A2.

This sort of complexity is where things get complicated. It seems like the question is whether allowing A and ABC to release in parallel makes this sort of problem more likely. I’m actually not sure offhand whether it does or not.

At my company, we’ve developed a fairly hard-and-fast rule of shading our libraries, so that A1 and A2 can co-exist in the same application, which reduces this particular danger. That might be helpful here, but like I said, I don’t find it immediately obvious one way or another…

Actually build tools (or more precisely: their dependency resolution mechanisms) will always treat ABC<whatever version> and A<whatever version> as different libraries because they have different names. So in the end you’ll end up with both ABC2 and A1 libraries on classpath and depending on which library is first on the classpath you’ll get classes from A2 or A1. This can cause even more confusion as e.g. build tool used for e.g. running tests in CI/ CD pipeline could use different classpath order than IDE in which you’re developing an application.