Sylvain proposed [1] to base blocks on the OSGi service platform [2][3]. After having studied it in more detail I'm completely convinced that it is the way to go.

OSGi
====

The OSGi service platform is a "standarized, component oriented, computing environment for networked services". It handled bundles, which from a deplyment perspective can be any jar with some extra meta info in the manifest. Each bundle declare its dependencies on other bundles and what packages it exposes. The framework takes care about classloader isolation and there are also support for hot deployment, (which require more work in writing the bundles).

There is lifecycle support for dynamical: installation, start, stop, update and uninstallation of bundles. There is a service layer with registration and lookup of services. A number of APIs for standard services has also be defined [1] e.g. log, configuration, user admin and http services.

OSGi specification is currently at its 3rd release. It is used as kernel for Eclipse (since 3.0), each plugin is a bundle. It is used for embeded applications e.g. BMWs 5 series, mobile phones etc.

There are 12 compliant implementations and at least 3 with "friendly" licenses: the Eclipse kernel [4] (release 3+), Knoplerfish [5] (release 3), Oscar [6] (release 3-). There is also a bundle repository [7]. The Eclipse OSGi contain some extra functionallity that probably will be part of OSGi release 4. Knoplerfish is more lightweight and has a minimal framework distribution at only 200kB.

Alternatives
============

So what would be the alternatives to using OSGi? We have Pier's kernel, Metro [8] and Geronimos GBeans [9]. For Pier's kernel is solves AFACS a subset of what OSGi does and IMO we shouldn't base something as important as the Cocoon kernel on a one man show if we can avoid it. Using Metro will just not happen due to community reasons.

So GBeans seem like the only serious alternative. I don't know enough about GBeans to be able to evaluate it. But its much earlier in its development, it is not a standard and there is only one implementation, so it should IMO have a considerable technical advantage to OSGi to be used instead. Also I would assume that the fact that Eclipse is based on OSGi will mean that it would be much easier to write various Cocoon tools if we base Cocoon on OSGi. We allready have people in the community (Sylvain, maybe other Eclipse developers?) with previous experience in using it.

Getting it done
===============

As about any component framework ever concieved, allready has been proposed to solve the real blocks problem but we still doesn't have them, I would like to be a little bit more specific about how we could actually get there with OSGi. My main design criteria (except for solving the problem ;) ) is that we should have an incremental, evolutionary aporach. No "next generation", no new SVN branches, no major rewrites.

The rest will by nececity be more technical.

Cocoon bundles
--------------

The first step is to make Cocoon OSGi compliant by packaging the core and the blocks as (passive library) bundles. It just means that we add some meta info to the manifest files of the jars for core and blocks. Most of the info is allready available in the gump.xml and can be automatically added to the mainfests by the build system. For each block and core we need to decide what it exposes, which initially could be everything, and its dependecy on other block and libraries. It would also be and advantage to package all the jars that are used by more than one block as a bundle.

This step doesn't affect Cocoon as we know it at all. We just make it possible to load core and blocks into the OSGi environment (or Eclipse). OTH nothing will happen when we use OSGi this far.

The main sitemap
----------------

It should be as simple as possible for a user to add a webapp, so I think that a basic webapp bundle should be as simple as a directory with a sitemap in it and a WEB-INF with the basic configuration files. In the bundle scenario we don't need to put the core and block jars in WEB-INF as these are managed within the OSGi framework. What is needed is some meta info that says that the bundle contains the main sitemap, so that the (soon to be described) Cocoon service can search for the bundle and a list of what blocks (bundles) it depends on so that the Cocoon service can dynamically load all its dependencies.

The Cocoon service
------------------

The Cocoon service is the first bundle that is active, in the sense that it implements BundleActivator and is started by the frameworks lifecycle management. The Cocoon service publish an implemention of o.a.c.Processor as a service. It does this by looking up the main sitemap bundle above, dynamically installing all the blocks that the main sitemap bundles declare that it depends on and create an o.a.c.Cocoon based on this bundle and that uses the classloader that contains all the blocks it depends on.

When we have finished the sitemap aspect of blocks, the Cocoon service can alternatively look up a block manager service that contains the wiring info and manage all the blocks.

The Cocoon servlet bundle
-------------------------

At last we need to have a Cocoon servlet bundle it looks up the Cocoon service and a HTTP service [10] (both Tomcat and Jetty implementations are available), embeds the Cocoon service in the Cocoon servlet and register it in the HTTP service. That is all.

For some uses it would probably be good to be able to package everything including the OSGi framework as a WAR that can be deplyoyed into a Servlet container. I haven't thought about how to acomplish that.

A CLI bundle would also be useful.

Conclusion
==========

Following the above architecture, or some better ;) we can start experimenting with classloader isolation, deplyment from remote repositories and so on without introducing any back incompabilities or having to do any major rewritings.

It should also make those who want to be able to have both sitemap services and components in the same block (bundle) happy as well as those who want them architecturally independent.

The work on using OSGi can start as soon as we agree about that it is a good idea and somebody feel like doing it.

Whats next?
===========

When (and if) we have a basic micro kernel based Cocoon as described above, we can continue by breaking up the Cocoon core in smaller and more specialized bundles. We can break out flow, sitemap components, environments etc to own bundles, so that we get a core that is "lean and mean".

Common policies for package naming and bundle naming would also be a good idea. Also both core and blocks could be made more restictive about what they expose.

We could also, if it we gain anything from it, migrate to use the various services that are available in the framework.

But a main point is that we don't need to know that now. Even the basic scenario gives as a lot of advantages in that we get automatic dependency resolution an classloader isolation. We can decide how to move on from what we learn.

                                                 --- o0o ---

IMO, OSGi seem to be the best choice for kernel for Cocoon's block architecture and there is (if I haven't missed something important) a low risk, incremental and evolutionary way to get there.

WDYT?

/Daniel

[1] http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=111495131622669&w=2, http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=111497924701549&w=2
[2] http://www.osgi.org/osgi_technology/index.asp?section=2
[3] http://en.wikipedia.org/wiki/OSGi
[4] http://eclipse.org/osgi/
[5] http://www.knopflerfish.org/
[6] http://oscar.objectweb.org/
[7] http://oscar-osgi.sourceforge.net/
[8] http://dpml.net/
[9] http://wiki.apache.org/geronimo/GBeansArticle1, http://www-128.ibm.com/developerworks/java/library/j-geron1/?ca=dgr-lnxw01GeronimoEngine
[10] http://www.knopflerfish.org/releases/1.3.3/javadoc/org/osgi/service/http/package-summary.html

Reply via email to