In this post I will show how to create a modular rich internet application that will run on any browser using Java, Vaadin and OSGi. I'll make all sources and binaries available for download at the end of the post.
I've been working with Flex and combining it with OSGi (on the server) at Arum for the last couple of years and while Flash, especially using Flex as a development tool, is a fantastic platform with great penetration, I have found that I still yearn for solutions which require no plugins. In the last few weeks this has become even more important to me with the announcement of the (Flashless) iPad and embarking on a personal project that needs to run on every browser, not just a browser with a Flash Player plugin installed.
Having spent a great deal more effort looking for a solution to this problem (how to create a plugin free, cross browser RIA using Java and OSGi) I finally discovered Vaadin.
Vaadin is a suite of HTML UI components that have already been built using GWT, then are composed in to a running application using Java... at runtime.
A "Hello World" Vaadin application looks like this:
Vaadin and OSGi
I was particularly interested to learn that someone had considered using Vaadin with OSGi, though I personally do not like the concept of wrapping it in a J2EE style web application (WAR), nesting the OSGi container inside:
It is understandable that people would assume that if a developer that wants to create an RIA with Java they will want to deploy it as a WAR. However, I generally don't use application servers anymore. They tend to be bloated and have a large footprint soaking up much of a VM's heap space just to get started, and as a result tend to have a fairly long startup cycle (from several seconds to over a minute in some cases). Using an OSGi container *as* an application server gives you a much more lightweight application that doesn't require as much memory and starts up almost instantly and out of everything in the J2EE spec, the only thing I regularly come back to is servlets. Everything else seems to be an exercise in telling developers how to build applications with the view of scaling up hardware - obviously a winning approach for Sun in the old days, but not so useful for people wishing to get away with minimum footprint these days (for example by creating a cloud architecture which uses the minimum resources required and scaling up as demand dictates, not the software architecture).
Right out of the box (from at least version 6.2.2 onwards anyway) the Vaadin jar file is already configured as an OSGi bundle which means I can write other bundles which use those APIs.
My next activity was to make Vaadin not just OSGi friendly, but OSGi's "best friend forever". To do this I wanted to achieve the follow things:
- Allow bundles to register Vaadin Applications (whiteboard pattern - it's easier to register services than look them up) and automatically create a http resource for them.
- Allow bundles to register static resources (themes, widgetsets, etc)
- Make no changes to the core Vaadin jar file that you can download from their site
The result is three classes which are built in to a separate bundle that I currently call com.vaadin.osgi.
- StaticResources runs as an OSGi component and serves the themes and widgetsets directly from the core Vaadin bundle.
To add your own theme or widget set create a fragment which contains your theme/widgetset files and export those as packages. The Fragment-Host should be set to the Vaadin core bundle. The fragment containing your theme/widgetset resources will be added to the core Vaadin bundle dynamically.
Of course static resources should really be deployed separately to a web server that proxies servlet requests on to the container, so I wouldn't recommend this for use in a production environment.
- VaadinOSGiApplicationManager also runs as an OSGi component and looks for OSGi component factories with their component.factory property set to vaadin.app.
The component factory name (specified as component.name) is used as the alias to register an instance of VaadinOSGiServlet which then uses the component factory to create an instance of Application. For example, if component.name was set to myapp, the servlet would be registered at http://localhost:8080/myapp
- VaadinOSGiServlet creates instances of applications that have been registered with the container via a component factory.
This is what is registered by the VaadinOSGiApplicationManager.
Creating an OSGi Vaadin Hello World Application
To get the hello world application shown near the beginning of this post up and running we need to create a bundle which registers the application as a component factory. There is no additional Java code required for this step and by far the easiest way to do this is by describing the bundle with a bnd file.
To create the bundle simply run bnd. I used the following command on my system:
java -jar ~/Downloads/bnd-0.0.384.jar helloworld.bnd
More about bnd and how to get it can be found here:
The result is a bundle that uses declarative services to register your application as a component factory. This is the cool part - if you want to access other OSGi services just create binding methods for them in your application and update the bnd file. Declarative services then injects your application with the services automatically when an instance of the application is created.
Vaadin has this great concept of 'production mode'. When an application is not in production mode, you can append ?debug to your application's URL in order to see a debug console that shows you all kind of useful information such as the traffic between the browser and server, how long requests take, the JSON that has been passed backwards and forward and also gives you a useful 'restart application' button which forces the creation of a new application instance. Obviously, you will want your application to be in production mode at some point so to do this you need to pass "productionMode=true" as a property to the VaadinOSGiApplicationManager and because it is running as a component you can do this using configuration admin. With Apache Felix Fileinstall this is as easy as creating a file called com.vaadin.osgi.VaadinOSGiApplicationManager.cfg and specifying productionMode=true as a line in the file.
Every application will no doubt want it's own theme, right? To do that, again we're going to use bnd to create a bundle which simply adds our theme to the resources in the core Vaadin bundle, a using a useful and under-used feature of OSGi known as Fragments.
Create a folder called etc/theme under which create your theme assets. For example, etc/theme/VAADIN/themes/helloworld/styles.css. The following bnd file would then create a fragment.
Install the fragment and update the core Vaadin bundle and your theme is now available (delivered via the StaticResources component). With the theme installed the hello world application now looks like this:
Again, using bnd to create my bundle:
java -jar ~/Downloads/bnd-0.0.384.jar helloworld.theme.bnd
And that is that; a themed hello world application that is primed for dynamic modularity.
[Edit 10th September 2010]
Since writing this I've published an add-on to the Vaadin Directory that contains the bundles you need to run your apps as OSGi apps and a simple example. You can find that here:
Lastly, I have to thank Neil Bartlett for mentoring me through some of the OSGi concepts I've used here. Thanks Neil! You can find Neil's website full of useful OSGi information here: