Platinum Partner
java,osgi,spring dm,server-side,opinions,enterprise libs,class not found exception

Enterprise Libraries and OSGI

I will try here to explain why some enterprise libraries don't work with the OSGi concept. For this reason, I will create a simple Java library and client bundle to use it.

We start with the library, responsible for loading properties files. It contains one abstract class named ALoader with one static final method getResourceBundle that returns a ResourceBundle.
package com.jtunisie.osgi.load;

import java.util.ResourceBundle;

public abstract class ALoader {
public static final ResourceBundle getResourceBundle(String ressource){
return java.util.ResourceBundle.getBundle(ressource);
}
}

This class should work fine with a simple Java application.
Starting our client, we create one class named LibCustomer with three methods :

package com.jtunisie.osgi.loader.client.impl;

import com.jtunisie.osgi.loader.client.ILoader;
import com.jtunisie.osgi.loader.lib.ALoader;

public class LibCustomer extends ALoader implements ILoader {

@Override
public String getNameFromLib() {
return getResourceBundle("loader").getString("contry");
}
@Override
public String getNameFromLocale() {
return java.util.ResourceBundle.getBundle("loader").getString("contry");
}



public void init(){
System.out.println("local contry name : "+ getNameFromLocale());
System.out.println("lib contry name : "+getNameFromLib());
}

}

 

The init method will be called by Spring DM as the default init method.

Note that we have to add loader.properties file to src root file that contains one property :

contry=tunisie

Using maven to generate the two bundles we will get the following nested exception:

java.util.MissingResourceException: Can't find bundle for base name loader, locale en_US.

This means that library can't load properties file because it isn't visible. Why ?

In fact, the class loader concept isn't the same as a simple Java application - the tree concept isn't available here. The client bundle must import the library package otherwise the library is independent of client and it can't see resource file.

Many libraries such as hibernate, JPA and JAXB use the same thing with the class forName concept to load class with reflection, and due to invisibility of client to such libraries, the ClassNotFound exception is thrown.


OSGi R 4.1 isn't clear about this point, and some workaround is given by the Eclipse Equinox implementation. Let us adding a second chance to find resource file :

We mention that our library is Eclipse-BuddyPolicy registered which helps to find resource on the registered bundle. Our client will register by adding Eclipse-RegisterBuddy: com.jtunisie.osgi.loader.lib property.

If the OSGi class loader cycle fails to find the resource, our library will try to delegate the class loader to registered bundle wich is our client. Now if we try our client both methods work fine.

Conclusion


This is a brief introduction about the recurrent problem found when using external jars, and we need to take care about class loader before working with OSGi concept. It isn't as easy as a simple Java application but with some practice we can detect the source of ClassNotFoundExceptions - the workaround isn't always evident.


Source is available here :

svn checkout http://osgienterpriselibs.googlecode.com/svn/trunk/ osgienterpriselibs-read-only 

 

{{ tag }}, {{tag}},

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}
{{ parent.authors[0].realName || parent.author}}

{{ parent.authors[0].tagline || parent.tagline }}

{{ parent.views }} ViewsClicks
Tweet

{{parent.nComments}}