Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Enterprise Libraries and OSGI

DZone's Guide to

Enterprise Libraries and OSGI

· Java Zone ·
Free Resource

Verify, standardize, and correct the Big 4 + more– name, email, phone and global addresses – try our Data Quality APIs now at Melissa Developer Portal!

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 

 

Developers! Quickly and easily gain access to the tools and information you need! Explore, test and combine our data quality APIs at Melissa Developer Portal – home to tools that save time and boost revenue. Our APIs verify, standardize, and correct the Big 4 + more – name, email, phone and global addresses – to ensure accurate delivery, prevent blacklisting and identify risks in real-time.

Topics:

Opinions expressed by DZone contributors are their own.

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

{{ parent.tldr }}

{{ parent.urlSource.name }}