DISCLAIMER : This is in no way a reflection on OSGI as suitable/unsuitable framework, just my personal opinion as I found it having a steep learning curve which cannot be done in hurry
We were evaluating technologies for one of our recent project which has a quite strict deadline (as usual ;)). One of the requirement was to push updates without any down time. OSGI was suggested, which allows bundles to be pushed without any restart of server. A little research helped us to understand it’s basic philosophy of bundles, restricted import and export, “forced” modularity -All seemed too good theoretically to be excited about using it and add to it that one of the most popular IDE eclipse uses OSGI.
We started with the development, but as we expanded and added dependencies -its started turning out a nightmare. Most of the problem lied in one root cause -OSGI complaint jar for most of popular apps is not available out of box (example hibernate).
Every module is a jar file – and for it to be OSGI complaint, it’s manifest should have enough information so that any OSGI container (like felix) can understand what packages does it import/export, what are run time dependencies and all. There are tool like BND which help convert non OSGI jars to OSGI jars, there are some repositories which have a collection of many standard libs like ebr.springsource.com -but it was lacking for one or other reason.
If one searches at ebr.springsource.com, most of the libraries are older version. Although BND can add necessary information to metadata, we have to convert the whole dependency tree to an OSGI complaint.
If any of the jars uses class.forname to load any class, for example JDBC jars, life becomes even miserable -There are a lot of class loader issues as soon as dynamic loading kicks in.
Some of the issues which we encountered and which left a real sour taste:
- Sling Scheduler Integration with Felix: Lack of proper documentation.
We did not found proper documentation on installing sling. We felt, Felix website is NOT a “uptodate” source of documentation and only after looking out on community we were able to find exact steps.
Solution: Getting exact steps helped and we were able to deploy it.
- Quartz scheduler Job Store Integartion: Class loading issues.
If Quartz is configured to use the Data store, it uses class.ForName to load the Data base driver dynamically. While attempting this it was throwing class not found exception.
We used bnd tool to convert non OSGI complaint jars to OSGI complaint Jar.
Added Dynamic-ImportPackage: * tag to look for classes through all bundles at run time.
- Spring Web template for SOAP services: Class loading issues.
We used Spring template for Java standalone project and it worked just fine. We tried to take same approach in OSGI environment i.e. Felix it failed. We picked up appropriate versions from spring source repository, but it did not helped. Following is a stack trace
org.springframework.beans.factory.BeanInitializationException: Could not find default strategy class for interface [org.springframework.ws.transport.WebServiceMessageSender]; nested exception is java.lang. at org.springframework.ws.support.DefaultStrategiesHelper.getDefaultStrategies(DefaultStrategiesHelper.java:126) at org.springframework.ws.support.DefaultStrategiesHelper.getDefaultStrategies(DefaultStrategiesHelper.java:90) at org.springframework.ws.client.core.WebServiceTemplate.initMessageSenders(WebServiceTemplate.java:320) at org.springframework.ws.client.core.WebServiceTemplate.initDefaultStrategies(WebServiceTemplate.java:306) at org.springframework.ws.client.core.WebServiceTemplate.<init>(WebServiceTemplate.java:143) at test.soapservice.service.SOAPServiceImpl.<init>(SOAPServiceImpl.java:41) at test.soapservice.service.SOAPServiceActivator.start(SOAPServiceActivator.java:17) at org.apache.felix.framework.util.SecureAction.startActivator(SecureAction.java:641) at org.apache.felix.framework.Felix.activateBundle(Felix.java:1977) at org.apache.felix.framework.Felix.startBundle(Felix.java:1895) at org.apache.felix.framework.Felix.setActiveStartLevel(Felix.java:1191) at org.apache.felix.framework.FrameworkStartLevelImpl.run(FrameworkStartLevelImpl.java:295) at java.lang.Thread.run(Thread.java:595) Caused by: java.lang.ClassNotFoundException: org.springframework.ws.transport.http.HttpUrlConnectionMessageSender at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
- Connect standalone Felix instance with CRX repository using Jack Rabbit API.
We tried accessing remote CRX repository using Jack Rabbit client for JCR complaint repository (in this case CRX) .
Following are the problems we faced:
To access the JCR repository we need “JCRUtils” with version 2.0 or above that is not available bundled in jar that is OSGi compliance. We have used tools BND(http://www.aqute.biz/Code/Bnd) and magen(http://felix.apache.org/site/apache-felix-manifest-generator-mangen.html) to make external non OSGi jars to OSGi jars (but this approach is not working due to incompatible version or cyclic dependency between two jars)
To overcome this we have created a bundle in which we have bundled all the jars required to run above code with that bundle –using BundleClassPath meta tag. But the bundle deployed on Felix had problems like:
incompatible version problem
if jars bundled inside parent bundle have dependency on each other then we are getting NoClassDefFound error.
We were able to access JCR repository by creating a simple java project contains following code using following libraries.
So for sure its an OSGI specific issue.
After so much of hiccups and already spend an week of our development sprint, we decided to move on with custom approach and abandoned OSGI.
May will take a detailed look in some free time, learn it properly and then try out the things. Mean while I am posting this experience so that it might help in planning for the bootstrap time line for a new team 🙂