Thursday, September 24, 2009

API compatibility matters

A few weeks ago, Palm has released an SDK called "Mojo" for their WebOS. They also offer Eclipse plug-ins that have been developed for and tested with Eclipse 3.4.2. I just read a short review of this Eclipse-based tooling and was happy to see the following:
The WebOS plug-in is supposed to officially work with Version 3.4.2 of Eclipse (code-named Ganymede). However, I was able to successfully run it on Version 3.5 of Eclipse (code-named Galileo) without any problems.
It makes me happy to see real-world reports like this. They confirm that you can run plug-ins developed for older versions of Eclipse on more current versions. In the Eclipse community, we almost take this for granted and sometimes tend forget the effort involved in pulling this off. Because when you think about it, compatibility is only achieved when both sides do a good job of enabling compatibility:
  • On the Eclipse SDK side, we tend to think that we are doing good job of ensuring API compatibility between Eclipse releases, so that you can run older plug-ins on newer versions of Eclipse. Since Eclipse 1.0 (2001), we've had excellent rules in places around API compatibility, and if you want to read more I'd recommend you start at our "API Central" wiki page. More recently, we've automated a lot of the necessary compatibility checking in form of API tooling that ships with the Eclipse SDK. I haven't seen anything like it for other languages or environment yet, but would like to hear if similar tooling exists elsewhere. C#? ActionScript? Let me know in the comments!
  • On the Palm Mojo side, the developers must have done a good job of only using documented APIs, and abiding by the contracts for those APIs. Because if you don't, all bets are off.
Here is a quote from the 2001 article "How to use the Eclipse API" by Jim des Rivieres, a recommended read for anyone developing Eclipse plug-ins:
As the Eclipse platform matures and evolves, it will be the API contracts that guide how this evolution happens. Outside of these contracts, everything is unsupported and subject to change, without notice, and at any time [...]. Client code that oversteps the above rules might fail on different versions and patch levels of the platform; or when run on different underlying OSes; or when run with a different mix of co-resident plug-ins; or when run with a different workbench perspective; and so on. [...] To those who choose to ignore the rules, don't say that you weren't warned. And don't expect much more than a sympathetic "Told you so."
Of course, in reality, life is never as easy and black-and-white as software developers would like it to be. Sometimes, the existing API doesn't work for your particular case, or there is no supported API at all. In these cases, however, you need to realize that by calling internals, you are assuming technical debt. The idea behind this metaphor, created by Ward Cunningham, is that you have taken a shortcut and need to pay up later, either in form of interest payments or paying back the principal. In concrete terms: Whenever a new version of the plug-ins you depend on comes out, you have the cost of testing that your code still works, and the cost of adapting to any change that may have broken your code. This is a recurring cost, hence the term "interest". If you want your code to run against both older and newer versions of your dependencies, the interest payments are much greater, because the problem is much harder. Often, you will need to use Java reflection to guard your calls to internals. Alternatively, you can pay back the "principal" at a later point in time, when the necessary API has been added, and get rid of your debt. You did file an enhancement request to get that API added, didn't you? Because if you don't, you'll be bound to pay interest forever!

Every now and then, I encounter people who are hoping to get away without paying either interest or principal. And that's after our collective experience with how schemes based on trading debts can take the whole economy down! :-)


David Green said...

Excellent article Boris.

I would even go so far as to say that compatibility matters at the classpath level too, not so much for Eclipse but for stand-alone apps. If consumers of your project must reconfigure their classpath in order to use a new version of your project, there should be a good reason why. Otherwise they're just presented with unnecessary obstacles.

Chris Aniszczyk (zx) said...

What, no mention of the awesome PDE API Tools ;)?