Friday, February 23, 2007

The OSGi Extender Model

Installing and upgrading software is a complicated process that is very error prone in today’s operating system. In Windows, there is a whole industry for installers that take (some of) the pain out of installing a windows application. In Linux RPM package management is famous.

These installers are necessary because applications in operating systems touch many other subsystems. For example, to install an address book application in Linux, it is necessary to have at least the following things done:

  • Testing if the dependencies are fulfilled
  • Setup an SQL database and tables in MySQL
  • Place the executables and files in an appropriate place
  • Link the documentation and servlets to an Apache web server
  • Link to the commands from the application from the appropriate bin directory
  • Setup the permissions
  • Etc.

An RPM script for the GNU Indent program looks like:
Name: indent
Version: 2.2.6
Release: 1
Source0: %{name}-%{version}.tar.gz
License: GPL
Group: Development/Tools
%description
The GNU indent program reformats C code to any of a
variety of formatting standards, or you can define your
own.
%setup
-q
%build
./configure
make install
%defattr(-,root,root)
/usr/local/bin/indent
%doc /usr/local/info/indent.info
%doc
%attr(0444,root,root) /usr/local/man/man1/indent.1
%doc COPYING AUTHORS README NEWS

Notice how many hard coded details are specified in this script. Scripts like these are highly sensitive to small changes in the deployment environment.

The model is that the application developer/deployer has to know it all. There is a good reason why installation scripts so often fail: coupling. Installation scripts require deep knowledge of the structure and setup of the target system. The installation script writer is one of the few persons that has to understand all aspects of the application to configure and initialize the environment. Uninstallation is even harder because it is not easy to know what files are created by the applications that should be removed. It is the unfortunate truth that after a year or two, my Windows operating system needs to be reformatted to get rid of the applications that are no longer removable because their installation script fails, a simple missing file can already cause such a script/installer to fail.

Installation scripts are so hard, that one day a friend of mine promised to eat the installation floppy (yes this was a long time ago) if it failed one more time. Alas, we served the floppy with a fresh salad to make it easier to digest.

Now once there was an operating system that did not require installation scripts at all: The Macintosh. When I moved form the Mac to the PC I was utterly confused with installers. On a Mac, installation means dragging a file to any folder on the Mac. That’s it. All OS related installation is performed automatically when an executable is copied, renamed, or deleted. The reason that this can magically (for PC users) work is because a Mac executable contained a simple database with installation information (the so called resources). When the executable is copied, the MacOS is called with a handle to the executable. Associations, icons, help, and many more resources are stored in this flexible database. Moving the file to another location? No problem, this is handled by the OS. Uninstalling? Simple, just delete the file.

With hindsight, it was obvious that my first week on the PC would be a disaster. After installing a number of applications, I decided to rearrange the folder structure, something I often did on the Mac without thinking about. Yes I got this pesky warning but what is a registry??? … A reformat was the only solution in the end.

Let us inspect the differences between the Mac and PC/Unix a bit deeper. An example of information that needs to be installed on both the Mac and the PC are the file associations. When a text file is double clicked, an editor needs to be opened, when an html file is clicked, we want to see the browser. In the PC this association is made by the file extension of the file. For example: .html, .txt, .doc. The association extension-to-application is made in the Windows Registry (Yes, I am now thoroughly familiar with it). On the Mac, the association is stored in the desktop database and copied from the resources of the executable.

It is interesting to compare the two strategies to set this information:




The Mac model has many advantages and few drawbacks. The biggest drawback is maybe psychological, the programmers feel less in control because so little installation work is left and delegated to other subsystems (job security!). Subsystems they do not have direct control over. However, this lack of control is maybe one of its greatest assets in my opinion. Over the years, the Macintosh was able to get more and more functionality that was immediately applicable to old applications. For example, the desktop database could be totally restructured because normal applications had no knowledge whatsoever about this database. Restructuring the Windows registry … eh, well that would be a major undertaking because any useful application on Windows has intricate knowledge of large parts of the registry.

Nowadays, many Mac applications also have installers because they have become dependent on many other components that are installed on the system. E.g. many applications use MySQL, a web server, and other components. In today’s operating systems, MySQL needs to be configured and initialized for a new application that uses it.

Looking at the advantages of the declarative model that was used in the Mac for file associations, would it not be nice if the other subsystems could work similarly?

For example, if the MySQL component could see that a new application was installed, it could look in the application resources and see if there was installation information for this MySQL component. If so, it could use this information to setup the tables and permissions. If the file was standardized (lets say standard SQL), it might even be picked up by another database like Progress, DB2 or Oracle, without the application being aware of this. Updates and installation could work in similar vein if the subsystem (in this case the database subsystem) could get notifications of updates and uninstallations.

An interesting aspect of this extendeer model is the robustness. Quite often, applications are uninstalled because they have become unreliable; their state is messed up. Relying on scripts that run in the context of this messed up state is not good, often creating a larger mess by not finishing and leaving expensive resources lingering on the system. If a messed up application gets uninstalled, the chance that the subsystems can clean up for the application is much higher because they are more likely to be in a healthy state.

If life could only be so good … But it can! This is exactly that the OSGi Alliance enables and promotes. Meet the Synchronous Bundle Listener.

Synchronous Bundle Listener


The Life Cycle layer in the OSGi Framework allows bundles to listen to installations, updates and uninstallations of other bundles. A normal Bundle Listener will handle those events asynchronous. That is, when you get the event, the cause has moved on and has not waited for you to look at it. The Synchronous Bundle Listener works differently, it will handle the same event, you guessed it, synchronously. With the Synchronous Bundle Listener you get a chance to do your thing before the cause of the event has passed. This allows the subsystem to perform its initialization before the application gets control.

In the Synchronous Bundle Listener event call back, the subsystem can look at the resources of the bundle and check if there is anything of its liking. If it is, it can use this resource to perform the necessary initialization for the new bundles.

This is all rather abstract so let us work out a simple example.

A Servlet Helper


If you write a servlet for an OSGi service platform than you must get the Http Service and register your servlet with it. This is boilerplate code, not very interesting. An extender could simplify this model by removing all the cruft for the servlet programmer. Whenever a bundle gets started, the servlet extender would inspect a header in the bundle about to be started. If this header was set, it would load the servlet class from the bundle and register it with the Http Service.

This model is easily programmed, you can find an example on the snippets site. This snippet discusses some of the implementation issues around extenders.

Issues


No model is perfect and obviously the extender model is no exception. There are a number of issues that may impact the suitability.

No Access to private area of bundle


Extenders do not have access to the private area of a bundle. This area is reserved for the bundle itself and should not be touched by other bundles. Any party that could access this area makes it impossible for a bundle to reason about its private data area. For example, locking is not necessary in the private area to prevent access from other parties.
If a bundle needs its private data area initialized, it can do this lazily in the start method. If it is necessary to initialize this data after install, the extender method is not suitable.

Permissions


Extenders run with their own permissions. An extender should therefore be careful not to perform operations on behalf of the bundle that the bundle would have no authority for. For example, a malicious bundle should not be able to wreak havoc because the extenders did things on its behalf without checking.

Then again, there is an advantage that an extender could do more privileged operations than the bundle itself is allowed. For example, an extender could create a database for a bundle without the bundle having permission to create it (obviously it requires permission to use it).

Extenders could scope the operations they have by using Permission Admin to get the permissions of the bundle and using a doPrivileged call with those permissions on the stack. For example, an extender could get the permissions of the signer and scope all actions with these permissions.

This issue needs to be analyzed in detail for each type of extender. In most cases a solution can be found but in certain cases extenders are not suitable.

Hanging Bundle Listeners


Synchronous Bundle Listeners are, well, synchronous. They are called in the middle of an installation process. If they do not return, the installation cannot be finished. Good frameworks will handle hanging synchronous bundle listeners, but it is not good when it happens.

Extenders are likely to be system components and should therefore have extra quality requirements. For this reason, a synchronous bundle listener must have AdminPermission[bundle,LISTENER]. The model is therefore less suitable when the initialization is done by untrusted components.

Conclusions


The life cycle events of the OSGi Framework enable a much more friendly installation model in comparison to traditional scripts and installers. By delegating application setup and initialization to the subsystem applications will require less, highly volatile, knowledge of the deployment platform. Further, subsystems have more possibilities to clean up and adapt to changes in the applications.

The single most important drawback is that the model is less familiar to Windows and Unix (but not Mac) programmers. In these environments, the lack of life cycle events and heavy reliance on the file system structure makes the described model impossible. This lack of familiarity by the programmer makes the OSGi model look like there is no control, a feeling many programmers distinctly dislike.

However, the OSGi is a component model where it is impossible to know all the life cycle events. By delegating the installation task to the different subsystems, the overall system becomes significantly more robust, reliable, future proof, and simpler to maintain.

Peter Kriens

Tuesday, February 20, 2007

OSGi Activities in the next Month

First some housekeeping. Next week 1 and 2 March 2007 we will have a meeting Cologne about end-2-end solutions related to OSGi technologies. This includes remote management and anything else that is necessary to run large scale OSGi installations. This meeting is open to members and non-members because we see this as a requirements gathering meeting. More information can be found on the meeting page.

As if this was not enough, we also will run a Vehicle requirements gathering meeting in Eindhoven at Siemens VDO. This is a successor to the successful meeting in Troy at Delphi. You can read more about this at the meeting page.

You can contact Kai Hackbarth if you need an invitation.

And last, but absolutely not least ... You are coming to the OSGi Developer Conference (sometimes also called EclipseCon 2007)? The program is fantastic! Really hoping to see many of the readers there in two weeks. We have a BOF at 19.30 Tuesday in the theater, do not miss it! The OSGi Alliance will provide drinks. There is still time to register, and OSGi members still get a discount.

Peter Kriens

OSGi Extenders

Friday, February 2, 2007

Tidbits

I wanted to blog about the OSGi Enterprise Expert Group but Eric Newcomer (IONA), one from the chairs beat me. I do not think I can improve his report, so please check it out. I fully agree with Eric that it was an exciting and energetic day with a lot of hope for the future (and work). If you want to participate in this work, you will have to become an OSGi member, but believe me, it is definitely going to be worth it!

I just finished working on the final details OSGi DevCon/EclipseCon . It really is becoming an amazing conference. We had many more submissions than we could select, and almost all submissions were of very high quality. You still get an early bird discount for the next two weeks, so sign up quickly. I sure hope to meet many of my blog readers.

Ok, one thing technical. Jon Bostrom showed me the N800, which is an improved version of the N770. This is an OSGi dream come true machine. For some reason, it does not include a GSM chip, but that could make the N800 an interesting companion with the E70 that I have, which contains also an OSGi framework. The devices could communicate over wifi or bluetooth to exchange data and code. Jon promised me an N800 once the channels are filled, once I get one I will report about my experiences. So many interesting areas, so little time ...

Peter Kriens