Archive for the ‘osgi’ Category
Too much work is done around Eclipse (RCP, Equinox, BIRT, Monkey) that I can’t follow all the things which interests me.
However, by browsing the mailing list of the Equinox (Eclipse’s OSGi implementation), I discovered a cool new project in the Equinox incubator: Resources Monitoring.
Its mission statement?
To provide a framework for monitoring resources that are contributed by bundles installed on the host machine. The term ‘resources’ is used to
describe something as specific as a single object or something as abstract as an OSGI bundle.
It seems to use JMX to manage the resources and to provide both the server and the client code to manage the resources.
Definitively worth a look…
Following my last post on browser-based desktop applications, I prototyped a little application to play with these ideas.
I’m a big fan of the social bookmarks manager del.icio.us which enable you to bookmark urls and categorize them. However, all your bookmarks are available to everyone else (it manages social bookmarks after all).
But, from time to time, I also need to bookmark urls that I don’t want to share (e.g. private ones or professional ones which could give too much hints to competitors).
So I bookmark these URLs with my browser. But they can not be categorized like del.icio.us ones (folders don’t help). So when I want to check bookmarks for a given topic I’ve to look in two different places and interfaces (the web bookmarks toolbar and del.icio.us).
I prototyped a simple application with the following requirements:
- keep a private list of bookmarks
- categorize them like in del.icio.us
- aggregate private and del.icio.us bookmarks
- display them in the same interface
- search categories for both private and del.icio.us bookmarks
The prototype is a browser-based desktop application (i.e. a standalone application which runs its embedded HTTP server and is displayed in the browser).
The application keeps a list of private bookmarks and aggregates them with del.icio.us ones (retrieved with del.icio.us REST API thanks to the delicious-java library).
In fact, from the user interface, it is quite similar to del.icio.us interface.
The only differences is that private bookmarks are automatically categorized with a private tag. (As an aside, I first had two type of bookmarks: public and private ones. But as I coded, I realized that I could used the bookmark own tags to categorize them as public or private…).
Special urls (like for displaying bookmarks for a set of categories) redirect to the application which filters both del.icio.us and private bookmarks.
Here some screenshots (I haven’t care much for the layout but it is based on del.icio.us):

To save a bookmark, type its url, its description, its (optional) extended description and list of space-separated tags.
To save it in the application ( i.e. on your desktop), tag it as private. Otherwise, the bookmark will be saved on del.icio.us.

If I look for all the bookmarks with the osgi tags, I see that some of them are categorized as private. They’re stored on the application and not on del.icio.us (see my del.icio.us OSGi page to see the differences).
As you can see on the screenshots, the only differences is that private bookmarks are categorized with a private tag.
I haven’t reproduced all features provided by del.icio.us but this first prototype is functional enough to help me vizualize what browser-based desktop applications could be.
I see this prototype like the equivalent of Google Desktop Search but for bookmarks. Both application aggregates local and web data and displays them in a consistent way in the browser.
As for the technology I used, it’s based on the OSGi framework and its HTTP service (I used Knoplferfish implementation). The cool thing is that everything can be delivered as a standalone application that sits anywhere on your hard drive. You just start it and point your web browser to http://localhost:8080:<your del.icio.us name>. It’s also possible make it a Windows or Mac OS X service with a cute little icon in the tray.
And, being based on OSGI, you can also use it from your PocketPC!
One other cool feature of this application is that since it sits on your own machine, you can also bookmark local files and categorize them.
For example, I’ve a local version of the OSGi specification in PDF file. I bookmarked it with my application with the url file:///Users/jeff/doc/…../r3.book.pdf.
So when I want to see all my bookmarks related to OSGi (http://localhost:8080/jmesnil?tag=osgi), I’ve got both web url and local documentation (URLs starting with file:// are automatically tagged as private and local).

The only problem is that you can’t open the files from their URLs (I already blogged about it but I haven’t find a correct solution yet).
There is nothing rocket science in this prototype but there is some potential for such browser-based desktop applications to integrate in a consistent way desktop data with the whole web.
What I said in my last entry concerning OSGi and Component Versioning is not accurate (not to say completely wrong).
I wrote that:
With OSGi, you can state the version of the bundle you want to import. It also takes into account compatible versions. Since bundles have their own classloaders, you can have different bundles using different versions of the same library without conflict.
To check that, I wrote some bundles and it does not work that way.
As is stated in OSGi specification:
A bundle may offer to export all the classes and resources in a package by specifying the package names in the Export-Package header in its manifest. For each package offered for export, the Framework must choose one bundle that will be the provider of the classes and resources in that package to all bundles which import that package, or other bundles which offer to export the same package.
and
If more than one bundle declares the same package in its Export-Package manifest header, the Framework controls the selection of the exporting bundle. The Framework must select for export the bundle offering the highest version of the declared package.
If I read it correctly, that means that you can only have one version of a given exported package identified by the highest specification-version value.
So OSGi won’t help to solve runtime dependencies nightmare experienced by anyone using different projects, each one depending on different versions of Jakarta commons jars…
So next time, I’ll first RTBS, then write some code and finally blog about it instead of blogging first…
P.S.: OSGi versioning is based on Java Product Versioning Specification which is worth reading…
I saw this thread of Java.net community forums about missing features to administrate libraries in Java.
OSGi helps with two shortcomings of the Java platform (not Java language):
- Component Versioning
- Published Interfaces
Component Versioning
There is already a notion of versioning in Jar specification. But I’m not aware of simple tools to take advantage of it (a.k.a “write you own ClassLoader”).
With OSGi, you can state the version of the bundle you want to import. It also takes into account compatible versions. Since bundles have their own classloaders, you can have different bundles using different versions of the same library without conflict.
Published Interfaces
Another useful feature of OSGi bundles is the idea of published API (see Martin Fowler’s article “Public versus Published Interfaces” for a definition of published interface).
You have to state in the manifest of your bundle the packages of the other bundles you’re depending on. Your bundle can then only load classes from these packages and not from any other packages.
Eclipse plug-ins makes the distinction by putting their published interfaces in org.eclipse.foo package and the public API in org.eclipse.foo.internal.
It is not recommended to make your plug-in dependant of internal packages but you still have the freedom to do so at your own risk if you really need it (e.g. to circumvent a bug or to extend the plug-in if it does not expose a feature as an extension point).
I really like the idea to make an explicit distinction between the public interfaces of a component and the published ones.
These days, thanks to autocompletion in the IDEs you can inadvertantly import and use a part of a component which is not meant to be used by its clients.
With OSGi, you can’t use a package if it’s not explicitely stated in the import-package header of its manifest file. Of course, you can still import internal packages but it has to be done explicitely in the manifest file.
The advantage of OSGi is that with a quick look at the manifest file, you can see the boundaries of your bundle:
31d3b6d2b8c131716e3adaa3d91dcbf7
While with “standard” jars, it is more difficult to see all its dependencies in one look.
Since Eclipse 3.0, OSGi framework has been under my radar but I hadn’t had the opportunity to develop an application based on it. I’m not aware of Open Source applications based on top of OSGi (other than Eclipse) but I think there is a lot of potential to develop an application on top of it. Not only for the two features I described but for a lot of other reasons (hot deployment, remote administration).
Another cool example is that application help could be written in HTML and available as a Bundle taking advantage of OSGi embedded web container (e.g. like Eclipse Help).
That way, you have simple to write documentation without the need to keep all the versions of the documentation of the available versions of your application on your web site.
I’m currently playing with OSGi. There are two Open Source implementations (Oscar and Knoplerfish) you can use.
Another Open Source OSGi framework is provided by Eclipse since its 3.0 release.
To launch its OSGi framework without starting all Eclipse:
- put in your classpath all the jars in
$ECLIPSE_HOME/plugins/org.eclipse.osgi_3.1.0/
- start the framework with
java -classpath $CLASSPATH \
-Dosgi.framework="file://$ECLIPSE_HOME/plugins/org.eclipse.osgi_3.1.0" \
org.eclipse.osgi.framework.launcher.Launcher -console
You then have the framework started:
osgi> status
Framework is shutdown.
id Bundle Location
State Bundle File Name
0 System Bundle
STARTING org.eclipse.osgi.framework.adaptor.core.SystemBundleData@17f1ba3
Registered Services
{org.eclipse.osgi.framework.console.CommandProvider}=
{service.ranking=2147483647, service.id=1}
osgi> launch
osgi> ss
Framework is launched.
id Type State Bundle
0 ACTIVE System Bundle [0]
osgi>
It is then ready to install and start new bundles (e.g. available from Oscar Bundle Repository):
osgi> install http://oscar-osgi.sf.net/repo/log/log.jar
Bundle id is 2
osgi> start 2
osgi> status
Framework is launched.
id Bundle Location
State Bundle File Name
0 System Bundle
ACTIVE org.eclipse.osgi.framework.adaptor.core.SystemBundleData@17f1ba3
2 http://oscar-osgi.sf.net/repo/log/log.jar
ACTIVE http://oscar-osgi.sf.net/repo/log/log.jar
Registered Services
{org.eclipse.osgi.framework.console.CommandProvider}=
{service.ranking=2147483647, service.id=1}
{org.osgi.service.packageadmin.PackageAdmin}=
{service.ranking=2147483647, service.id=2, service.vendor=Eclipse.org,
service.pid=0.org.eclipse.osgi.framework.internal.core.PackageAdminImpl}
{org.osgi.service.startlevel.StartLevel}=
{service.ranking=2147483647, service.id=3, service.vendor=Eclipse.org,
service.pid=0.org.eclipse.osgi.framework.internal.core.StartLevelManager}
{org.osgi.service.log.LogService}=
{service.id=4}
{org.osgi.service.log.LogReaderService}=
{service.id=5}
osgi>