I'm sure I am presently asking a really simple question that have been seen
a thousand times. But since I don't know where to start with OSGI, I'll ask
the question here in hope that one person would help me.
We need to build a plugin management for a web application running wicket.
It is already running and I would want to include OSGI bundle
extendability. I want bundles that are added to register as services in
order to give access to some methods. The bundle is installed in felix
using the FileInstall activator. I will not paste all the code since I
think the interface and implementation is irrelevant here. (Even if they are
really simple). The problem come with the fact that I cannot cast the
service received into the interface implemented. I get a ClassCastException
when trying to use it.
Here is the code at initialization of the web application :
//Make the felix startup here.
Properties felixProps = new Properties();
try {
felixProps.load(this.getClass().getResourceAsStream("/felix.properties"));
} catch(Exception e) {
logger.warn("Could not load felix properties", e);
}
List<BundleActivator> list = new ArrayList<BundleActivator>();
FileInstall activator = new FileInstall();
list.add(activator);
this.panelProvider = new PanelServiceProvider();
list.add(this.panelProvider);
felixProps.put(FelixConstants.SYSTEMBUNDLE_ACTIVATORS_PROP, list);
try {
this.felix = new Felix(felixProps);
this.felix.start();
logger.info("Felix started.");
} catch(Exception ex) {
logger.error("Could not load felix", ex);
}
Here is the code for the PanelServiceProvider class :
public class PanelServiceProvider implements BundleActivator {
private ServiceTracker serviceTracker;
public void start(BundleContext context) throws Exception {
this.serviceTracker = new ServiceTracker(context,
PanelDescriptor.class.getName(), null);
this.serviceTracker.open();
}
public void stop(BundleContext arg0) throws Exception {
this.serviceTracker.close();
}
public List<PanelDescriptor> getAllPanelDescriptor(){
if(this.serviceTracker != null){
Object[] services = this.serviceTracker.getServices();
if(services != null){
List<PanelDescriptor> panels = new
ArrayList<PanelDescriptor>(services.length);
for(Object service : services){
if(service instanceof PanelDescriptor){
panels.add((PanelDescriptor)service);
}else{
System.out.println("Unknown service : " +
service.getClass().getName());
for(Type type :
service.getClass().getGenericInterfaces()){
System.out.println("Implementing : " +
type.toString());
}
}
}
return panels;
}
}
return null;
}
}
And here is the result that I get for invoking this method when I call the
page in the web app :
Installed
c:\java\project\demo-wicket-felix\target\felix\fileinstall\panel1-0.0.1-SNAPSHOT.jar
2009-06-18 10:18:34.544::INFO: Started [email protected]:8080
[INFO] Started Jetty Server
Unknown service : com.mycompany.panel.PanelDescriptorImpl
Implementing : interface com.mycompany.panel.PanelDescriptor
What that mean is that the serive is loaded, it can be reached, but the
classes does not come from the same classloader. Now, I'm a little lost as
to what I'm supposed to do in this case.Does anybody have an idea on what I
could do to solve this problem?
If more details is needed (Like the manifest files or the other classes),
let met know and I'll provide them.
Thanks in advance.
Marc-Andre