Friday, February 12, 2010

Try out WebSphere's OSGi Application Feature

The open Beta version of the WebSphere OSGi Application and JPA Feature Pack hits the streets today. This brings together the JPA and OSGi Application Alpha programs and makes them installable features within a managed install. This post focuses on the OSGi Application feature of the Beta which and adds many new and good things beyond the Alpha including a completely re-factored version of the original Blog Sample application. In this post I will step through instructions for running and and modifying the Blog Sample application. Detailed instructions on how to run the Blog Sample are supplied in the Readme.txt that comes with the sample, so I will go over some of the steps quite briefly.

I will refer to your WebSphere home directory as WAS_HOME throughout this post. I ran through this using the free-for-developers version of WebSphere running on Ubuntu, so there may be a slightly Linux-y flavour; I'll document the 'assume nothing' Ubuntu install here. Everything should, of course, work on any supported WAS platform.

The Blog sample



The Blog sample is an OSGi Application that demonstrates the main concepts and many of the benefits of assembling and deploying an enterprise application as an OSGi Application. It comprises four main bundles and an optional fifth bundle, the relationship between the bundles is shown below:

The blog sample demonstrates the use of blueprint management, bean injection, using and publishing services from and to the osgi service registry, using optional services and the use of java persistence. In the main application, supplied as an EBA (enterprise bundle archive), the four bundles are:

  1. The API bundle - describes all of the interfaces in the application
  2. The Web bundle - contains all of the front end (servlet) code and the 'lipstick' (css, images)
  3. The Blog bundle - the main application logic. This bundle publishes a 'blogging service' that the Web bundles uses.
  4. The persistence bundle - the codes that deals with persisting objects (authors, blog posts ..) to a database (Derby in this case). The persistence bundle supplies a service for this which is used by the Blog bundle; the persistence service in this implementation uses JPA, with OpenJPA as the JPA provider.
  5. The final bundle is an upgrade to the persistence service, it contains an additional service that will deal with persisting comments as well as authors and blog posts.




Running the Blog Sample


The first steps in running the sample are to set up some data sources and create the database that the sample will use. There are instructions on how to do both in the Readme.txt file which can be found in WAS_HOME/feature_packs/aries/samples/blog; when you run the blogSampleInstall.py script use the 'setupOnly' option which will just create data sources. I'm going to step through the rest of the installation using the WebSphere Admin Console.

Start up WebSphere and point your web browser at the Admin Console, if you are running on a local machine and have not set up administrative security you will find the console at http://localhost:9060/ibm/console. Before going any further check that the data sources were set up properly by navigating to Resources->JDBC->Data sources, you should see something like this:



In the next sections I will work through installing the sample, starting with the bundles that it depends on.


Deploying bundles by reference


The Blog sample uses a common JSON library; while it could be deployed as part of the application the Blog sample illustrates how common libraries can be installed to the new WebSphere OSGi bundle repository and provisioned as part of the installation of an application that requires it. So the first thing we do is add the common JSON library to the WebSphere bundle respository. Navigate to Environment->OSGi Bundle Repositories->Internal bundle repository, the repository will be empty if you are using a new installation.

Click on 'New' to add a new bundle, on the next screen add the asset WAS_HOME/feature_packs/aries/InstallableApps/com.ibm.json.java_1.0.0.jar. Click 'OK' and then save the configuration, you should see this screen:




Creating the Blog Asset


Installing an OSGi Application through the Admin console is accomplished in two steps, described in this section. The blogSampleInstall.py script mentioned above illustrates the underlying wsadmin commands for a scripted install. The first step is to add an EBA (enterprise bundle archive) archive as an administrative asset, the .eba extension just indicates that this is an OSGi Application. Navigate to Applications->Application Types->Assets. Click 'Import' and add WAS_HOME/feature_packs/aries/InstallableApps/com.ibm.ws.eba.example.blog.eba. After saving you should see this:





Creating the Blog Sample Business Level Application



The second step is to to create an application which uses the EBA asset. Navigate to Applications->Business Level Applications, add a new application called Blog Sample:





After you have added the application you must associate it with the Blog sample asset, click on the sample and add com.ibm.ws.eba.examples.blog.eba under Deployed Assets.



As usual, save the configuration.

Start and run the Blog Sample application



At this point everything is in place and ready to run the application. From the Business Level Application screen, select the radio button beside the Blog sample and click start. If the sample starts as expected then point your web browser to
http://localhost:9080/blog, and you will see this:



With the blog sample running you will be able to add authors and posts and see that they are persisted to the database. Here is my first post to the Blog sample:



There isn't a great deal of functional code in this 1.0.0 version of the sample but a 1.1.0 version of the blog.persistence bundle is provided which adds a functional service to enable you to add comments to blog posts. We'll now illustrate how to update an application to add a new service by moving from version 1.0.0 of the blog persistence bundle to version 1.1.0 which contains the new service.

Changing the bundles that the Blog Sample application uses


First you will need to add the blog.persistence_1.1.0 jar to the internal bundle repository. This means repeating the same steps as for adding the JSON jar above. The path to the archive is WAS_HOME/feature_packs/aries/InstallableApps/com.ibm.ws.eba.example.blog.persistence_1.1.0.jar. Add it to the internal bundle repository and save the configuration.

Now you need to allow the application to use the new bundle. To do this, select the blog sample asset by navigating to Applications->Application types->Assets and clicking on com.ibm.ws.eba.examples.blog.eba. Scroll down to close to the end of the next screen where you will find this link:



Clicking on the 'Update bundle versions...' link will take you to this page:



Click on the the drop down arrow to the right of the line for the persistence bundle, you will be offered a choice of using the 1.0.0. or the 1.1.0 bundle. Choose 1.1.0 and follow through the preview and commit screens. You will need to restart the Blog application (from the Business Level Application screen) to make it use the new bundle, after that, navigating to http://localhost:9080/blog should show you the blog application with a new link to add comments. Unfortunately, it doesn't. This is what you will see:



This turns out to be entirely my mistake. In the last minute scramble to get the sample into the Beta delivery I didn't notice that some changes had been made to the JPA support had been made at the same time. The consequence of those changes is that my MANIFEST.MF requires an additional line. This is an easy fix and in the next section I'll describe how to make it.

How to modify the Blog Sample



All of the sample source code and Ant build files can be found under WAS_HOME/feature_packs/aries/samples/blog. Before making any other changes you should modify the build.properties file in this directory so that the first line refers to your WAS_HOME, you will need this file to build code with later on.

The best way to fix the problem with the MANIFEST.MF is to create another version of the persistence bundle, it should be a 1.1.1 version since the fix is very small. To start with, create a new directory under WAS_HOME/feature_packs/aries/samples/blog called com.ibm.ws.eba.example.blog.persistence_1.1.1, then copy the entire contents of com.ibm.ws.eba.example.blog.persistece_1.1.0 into it. Two files need to be modified, the META_INF/MANIFEST.MF needs to be changed to add the pink highlights shown below:




be very careful with the Meta-Persistence: line, it must have a space after the colon and the code will not compile if it doesn't. The second file that needs a small modification is the build.xml file, the project name needs to end 1.1.1, not 1.1.0.

After making the changes, run the build.xml file in your new 1.1.1 directory, like this:

ant -propertyfile ../build.properties -buildfile build.xml


This will create the archive target/lib/com.ibm.ws.eba/blog.persistence_1.1.1.jar. To install the new archive, go back to the WAS console and repeat the steps for adding it to the internal bundle repository and making the Blog Asset use it. Finally, restart the Blog application, point the web browser to the Blog and hit refresh. Et voila! A new link has appeared so that comments can be added to the post. Here is a screen shot with a comment added:




How does it work?



This Blog sample is designed to demonstrate how easy it is to change bundles and how to use optional services. To make this work we had to think about how to design the sample to be able to use the additional comment service from the start. This isn't really unrealistic, how often have you had a complete design in mind but not had time to implement the whole thing before delivering it? In this case we stopped short of delivering the service in the first version but we were able to supply it as an upgrade with an almost undetectable interruption to the service.

The sample is designed so that the bundles can be maintained completely independently of each other - I want the ability to upgrade one bit at a time. This might be overkill for an application of this size but the principle applies to applications of any complexity.

The other thing I have rather glossed over is that I didn't change the database, again the database had to have the right structure for the comment service from the start. However, this follows fairly naturally from designing the application to expect to be able to use commenting.

The best way to understand what is happening when the application is running is to look at the META-INF.MANIFEST.MF and OSGI-INF/blueprint/blueprint.xml files for each bundle. As the code is fairly simple, it's easy to follow through to the Java code and see where properties are injected by the container as specified in the application blueprint.

In the next revision of the Beta release I will fix the mistake in the MANIFEST.MF and will also correct a horrible anti-pattern that I introduced in trying to keep the persistence blog layers separate. In fact, I'll buy a beer for anyone that can see it and send me a good fix for it!

9 comments:

Anonymous said...

Hey it is a great article, but I have one question, I could not found the menu "Environment->OSGi Bundle Repositories->Internal bundle repository" mentioned on Deploying bundles by reference, do you know other way to do this ?

zoe said...

Hi there - I've made a very short video, it's easier than trying to describe the selection process. You can find it here:
http://zapt.info/WSSelectEnvt.mp4.

Let me know if this helps.

Anonymous said...

Hello again, I saw your video, the problem is the menu on my administrative console does not have the sub-menu OSGI Bundle Repositories.

I think a different Websphere version.

Do you know any other option to do this ? I really appreciate your help Thanks

Zoe Slattery said...

Hi again - So, the non-appearance of that menu item does seem to indicate some issue with your WebSphere installation. There are command line ways to do the same thing - they are described in scripts referenced in the Readme.txt file that is mentioned under 'Running the blog sample'. However, they will not work either if there is a problem with the WAS installation.

I wonder if you could help me with some information? What version of the WebSphere Application Server are you using? What OS are you running on?


Zoe

Anonymous said...

I have been investigating about it and seems that I need a feature pack to work with bundles as you mentioned on your article, am I right ?

Was version
6.1.0.2
OS
Windows xp sp 2

thanks

Zoe Slattery said...

Hi - yes, you are indeed :-) You will also need WAS V7.

Ralf Zahn said...

Hi,

thanks for your great articles. I'm currently evaluating the OSGi feature of WAS >7, and it's really nice.

The OSGi implementation that WAS provides is Equinox. But is it possible to use the Extension Point mechanism of Equinox in WAS? I need this because I want to install some bundles that are available in Eclipse (non-UI of course) and that use the Extension Registry. (e.g. the Equinox Servlet registry)

Another question: Is it only the org.eclipse.osgi bundle that is available before installing any custom bundle?

Alasdair Nottingham said...

Ralf,

I have not tried this, but I took a look and it looks to be possible. You need to put the org.eclipse.equinox.registry and org.eclipse.equinox.common bundles into the IBR and reference them from your Application-Content. Then it should process extension points in your application.

Alasdair

Ralf Zahn said...

Alasdair,

thanks for your answer. The org.eclipse.equinox.registry and org.eclipse.equinox.common bundles can be installed into the IBR and started.
But when importing the org.eclipse.core.runtime package (to read the IExtensionRegistry), I cannot deploy my EBA because of an error. (The logs tell me to look into FFDC, but there aren't any files created.) I guess it has something to do with the package, which is exported by multiple plugins.
And I cannot install and refer to the org.eclipse.core.runtime bundle, it brings also errors. I would need this bundle because other bundles require this.
In general, it is really disturbing for me that the Use-Bundle header is not allowed for custom bundles as part of the EBA, but can be processed for bundles in the IBR.

> reference them from your Application-Content.
Which header do you mean exactly? I only used the package import within my bundle's manifest.

Regards,
Ralf