DEC
9
2004

Why versioning your interfaces is always a good idea

Today, a lot of people have voiced their opinion on wether or not it's a good idea to port the KDE plattform to Windows. In other news, I whitnessed another uncessary crash today, that was due to a stale library that had an old interface. On load, it crashed and teared the application down. Read on to learn how to avoid those problems.



"They should uninstall old libs!" some of you might say. Wrong approach. This doesn't cover the case where third party libs are shipped. the original program might not know about them and thus has no decent way to uninstall them



"But shouldn't happen, interfaces should stay binary compatible" you might say. No, because that particular one was private.



Now see people screaming "Gotcha!, private interfaces should have
no 3rd party plugins!



Yes, that's true... In theory. In practice this breaks with our beloved KDEDIRs approach. Imagine a case where $KDEDIRS=/opt/kde3:/opt/kde-cvs. This is a wonderful scenario I use myself quite frequently, because I only need to compile the relevant part of KDE CVS and don't have to run bleeding edge with all KDE components.



Now if an application tells KTrader [kde:KTrader] to look for plugins it will search for service desktop files in both directories. Now say there is a desktop file pointing to a plugin that is BIC from an oder KDE release, there is little we can do. KTrader will find it, KLibraryLoader will load it and Booom - all is void. So how can we avoid those things?



Enter: Versioning constraints. I will demonstrate that using Kontact Parts as an example. In our definition of the new servicetype kontactplugin.dektop looks something like this.

[[Desktop Entry]]
Type=ServiceType
X-KDE-ServiceType=Kontact/Plugin
Name=Kontact Plugin
...
[[PropertyDef::X-KDE-KontactPluginVersion]]
Type=int
...

As you can see, we introduced a custom field X-KDE-KontactPluginVersion. This one can now appear in every service desktop file describing a Kontact/Plugin.

[[Desktop Entry]]
Encoding=UTF-8
Type=Service
Icon=kontact_summary
ServiceTypes=Kontact/Plugin,KPluginInfo

X-KDE-Library=libkontact_summaryplugin
X-KDE-KontactPluginVersion=4
...

Now when loading the plugins, we add an extra constraint in the KTrader Language that compares the current version with the version of the plugin:

...
  KTrader::OfferList offers = KTrader::self()->query(
      QString::fromLatin1( "Kontact/Plugin" ),
      QString( "[[X-KDE-KontactPluginVersion]] == %1" ).arg( KONTACT_PLUGIN_VERSION ) );
...

Tadaaa! Now we only load parts that should be safe the load. Of course you a free to add several versions here if you are sure your interface is still binary compatible.



PS: as you probably noticed, the parser for kdevelopers.org sucks. If someone tells me how to stop it from interpreting quare brackets as a link, I promise to fix things.



So, there are todays mantras. If you can't sleep tonight, try repeating them until you can sleep :)

  1. Always introduce versioning to your interfaces
  2. Always check versions
  3. Carefully evaluate which versions of your interfaces might still be compatible to the current version.

Comments

[Like this] is one way (unicode entity).

ps. Very nice article!


By Richard Moore at Thu, 12/09/2004 - 23:17

Doesn't work in pre and code areas as much as I wish it would :(


By Daniel Molkentin at Thu, 12/09/2004 - 23:42

I'll try to think of another way then! ;-)


By Richard Moore at Thu, 12/09/2004 - 23:43

[[the drupal site says to do it like this]

Edit: If anyone wants to moderate this unintenional post away, I'd appreciate it!


By Richard Moore at Thu, 12/09/2004 - 23:46

[the drupal site says to do it like this]

and it seems to be right. Now, the question is how do I put it in so that it comes out without being expanded! [


By Richard Moore at Thu, 12/09/2004 - 23:49