Skip to main content

Deploy Hibernate In OSGi using a features.xml file!!!

Posted by fossesi on September 16, 2010 at 5:06 PM PDT

Hibernate and OSGI Implementation Made Simple

Last April I kicked off FossESI to discuss how to take existing Java applications built using older technologies and implement them using new technologies like OSGi, Spring, Camel and NOSQL databases.  At the time of the kickoff, we intended to begin comparing and contrasting 3 NOSQL databases.  And just after that started, I got a real-life opportunity to help convert an existing application over to OSGi.  What I thought would be a breeze turned out to be quite an effort!  What I'll be doing over the next few months is talking about some of the lessons I learned, some of the quirks of Karaf and OSGi, and some of the tips and tricks I learned.  This week, I'll talk about how to implement Hibernate 3.3.2.GA inside of Karaf 1.6.0 without creating any new bundles!

One of the major contributors to the OSGi movement is Peter Kriens who created an excellent tool called BND.  The good folks at apache-felix then created a maven-plugin that makes quick work of bundling apps, but I'll go over that in a later blog.  The reason I bring this up here is that a while ago Peter wrote www.aqute.biz/Code/BndHibernate which discusses how to create a stand-alone bundle with all of Hibernate 3's goodness wrapped up inside of it.  This is an excellent approach, but it has a few drawbacks:

  • It requires the creation of a new .jar file which may confuse new developers,
  • It is pretty complex, and
  • The BND tool, while most excellent and wonderful, takes some time to figure out.

What I'm going to do is show you how to leverage Karaf and SpringSource bundles to do something similar, but without having to bundle Hibernate.  As Peter says "Hibernate is one of the more complicated open source projects to wrap".  To do this, I'll:

  • Talk about an excellent source for bundles, Spring Source,
  • Describe what a features.xml file is,
  • Show you a working features.xml file for Hibernate 3, and finally
  • Show to modify one of Karaf's configuration files to automagically start up Hibernate when you start Karaf.

First, I 'd like to talk about Spring Source. These folks are doing an outstanding job of creating bundles out of commonly used java apps, like Hibernate.  I would be remiss if I didn't mention the fact that, without their hard work, simply deploying Hibernate using a features.xml file would not be possible.  The link points to thier bundle repository, you should bookmark it, its a great resource.

Karaf has a few core concepts that this blog will illustrate to you:

  • OSGi bundles,
  • Karaf Features,
  • Features.xml documents, and
  • the org.apache.felix.karaf.feature.cfg file.

When you have an application like Hibernate that has dependencies on other libraries, one way to deploy them is to turn them into OSGi bundles and then create a features.xml file. An OSGi bundle is simply a .jar file with a MANIFEST.MF file containing OSGi goodness.  There are a lot of great resources already available on the internet that go into detail about what an OSGi bundle is composed of, so I won't go further into it here. 

Deploying a large application composed of bundles using a features.xml file is much less time intensive than deploying them manually.  Most of the large bundled open-source programs have created features.xml files for you, Camel being the first one that comes to mind.  Unfortunately, at the time of this writing, I was unable to find one for Hibernate, so I made my own using a list of dependencies created by the good folks at Spring Source.

First, start Karaf.  Then, to deploy a single OSGi bundle into Karaf, you simply need to invoke the following command (for the uninitiated "karaf>> " is the prompt, dont' type that.)

karaf>> osgi:install <uri of the file>

In practice, the uri can be anything that can be resolved: a maven URI, a url, or even some file on your local file-system! Once you've typed that, Karaf will print out the name of the bundle you installed on the command-line.  Alternatively, you could find out the bundle number of the bundle you installed by typing:

karaf>> osgi:list | grep <bundle symbolic name>

That will give you the number of the bundle as it is installed in Karaf. Finally, you start the bundle by typing: 

karaf>> osgi:start <karaf's number for the bundle>

A bundle can have a number of states, it can be Installed, Active, or Active and Failed.  What you want is for your bundles to be Active. Usually, anything else is a problem. This is what you'd type to install and start an OSGi bundle from a maven repository:

karaf>> osgi:install mvn:org.dom4j/com.springsource.org.dom4j/1.6.1
 89
karaf>> osgi:start 89

Now, imagine if you have 90 bundles in your application, including all of the dependencies.  That's a lot of typing!  A features.xml does all that heavy lifting for you. The features.xml file is simply an xml file where you identify a given feature, and then define the OSGi bundles and other features necessary for that feature to work inside of Karaf. 

Karaf will read in the features.xml file, and when you install a feature, it will automatically download each bundle listed from its associated URI, install it as an OSGi bundle, and start it.  It will do this for each bundle unless it finds a problem. If it finds a problem, it will then stop and uninstall each bundle it started.  If a bundle was already installed, the Karaf will "refresh" it, and if there's a problem, it will leave it active. This is the features.xml file I wrote for Hibernate, the file is called hibernate-features-3.3.2-GA.xml.

<?xml version="1.0" encoding="UTF-8" ?>
<features>
   <feature name="hibernate" version="3.3.2.GA">
     <bundle>mvn:org.dom4j/com.springsource.org.dom4j/1.6.1</bundle>
     <bundle>mvn:org.apache.commons/com.springsource.org.apache.commons.collections/3.2.1</bundle>
     <bundle>mvn:org.jboss.javassist/com.springsource.javassist/3.9.0.GA</bundle>
     <bundle>mvn:javax.persistence/com.springsource.javax.persistence/1.0.0</bundle>
     <bundle>mvn:org.antlr/com.springsource.antlr/2.7.7</bundle>
     <bundle>mvn:net.sourceforge.cglib/com.springsource.net.sf.cglib/2.2.0</bundle>
     <bundle>mvn:org.apache.commons/com/springsource.org.apache.commons.logging/1.1.1</bundle>
     <bundle>mvn:javax.xml.stream/com.springsource.javax.xml.stream/1.0.1</bundle>
     <bundle>mvn:org.objectweb.asm/com.springsource.org.objectweb.asm/1.5.3</bundle>
     <bundle>mvn:org.objectweb.asm/com.springsource.org.objectweb.asm.attrs/1.5.3</bundle>
     <bundle>mvn:org.hibernate/com.springsource.org.hibernate/3.3.2.GA</bundle>
     <bundle>mvn:org.hibernate/com.springsource.org.hibernate.annotations/3.3.1.ga</bundle>
     <bundle>mvn:org.hibernate/com.springsource.org.hibernate.annotations.common/3.3.0.ga</bundle>
     <bundle>mvn:org.hibernate/com.springsource.org.hibernate.ejb/3.3.2.GA</bundle
  </feature>
</features>

Now, copy that bad-boy into an editor, and save it in your /etc directory.  Once that's done, you'll be ready for the next step!

We can make Karaf aware of this features.xml file manually by typing:

karaf>> features:installUrl file:///home/myname/apache-felix-karaf-1.6.0/etc/hibernate-features-3.3.2-GA.xml

To verify your new features.xml file is installed, type

karaf>> features:listUrl

If you see your feature listed there, you can start your feature by typing:

karaf>> features:install hibernate

Give it a few seconds, and when you get the prompt, if you haven't gotten any errors, you can verify that hibernate is installed by typing:

karaf>> features:list | grep hibernate

Installing your features.xml and starting your feature this way is fun, but what if you've got a ton of features to install?  Manually is fun; but lets face it, it's not very sexy... If only there was a way to make Karaf aware of the features.xml on start-up?  Well, there is! We just add it to our /etc/org.apache.felix.karaf.features.cfg file!  This is what it will look like when you download and install karaf:

################################################################################
#
#    Licensed to the Apache Software Foundation (ASF) under one or more
#    contributor license agreements.  See the NOTICE file distributed with
#    this work for additional information regarding copyright ownership.
#    The ASF licenses this file to You under the Apache License, Version 2.0
#    (the "License"); you may not use this file except in compliance with
#    the License.  You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS,
#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#    See the License for the specific language governing permissions and
#    limitations under the License.
#
################################################################################

#
# Comma separated list of features repositories to register by default
#
featuresRepositories=mvn:org.apache.felix.karaf/apache-felix-karaf/1.6.0/xml/features

#
# Comma separated list of features to install at startup
#
featuresBoot=ssh,management

This file is composed of two very important items for us, a list of features repositories, and also a list of the features to start up when we start Karaf.  Including our features.xml file is pretty straight-forward, we simply add the uri to the end of the featuresRepositories line so that it looks like this:

featuresRepositories=mvn:org.apache.felix.karaf/apache-felix-karaf/1.6.0/xml/features,file:///home/myname/apache-felix-karaf-1.6.0/etc/hibernate-features-3.3.2-GA.xml

When I first did this I tried to put a \ character after the first comman and start each features file on its own line, but that created issues, so now I put all of my features on the same line.

When we start up Karaf, we can verify that the features file is installed by typing:

karaf>> features:listUrl

This produces a list of each features.xml file Karaf was able to successfully read.  If you don't see your features.xml file there, go look at it, there's probably an issue.  Also, check out the /data/log/karaf.log file and see if any errors or exceptions were reported.

Ok, what if Hibernate is part of a larger set of applications, and you want them all to start up when you start up karaf?  Well, that's not too difficult.  Simply add your new feature to the featuresBoot line so it looks like this:

featuresBoot=ssh,management,hibernate

If everything works properly, when you start up Karaf, your happy new hibernate feature should be up and running and ready for some abuse!

That's all for tonight.  If you find an issue with this blog, have questions, or just like the cut of my jib, feel free to comment below!  Happy developing!

Comments

Hello, I am looking for a way to run hibernate apps in ...

Hello,

I am looking for a way to run hibernate apps in Karaf and stumbled upon this blog. Since Hibernate is now at revision 4.1.2 I want to try this latest edition. What is the recipe for creating a list of bundles for a Hibernate feature? I guess Maven can help me, or did you create the bundle list somehow different?

My wish is also to run Hibernate Search in the OSGi container. Did you by any chance tried this?

Thanks!

Borut