Thursday, 28 May 2009

OSGi ClassCastException with Equinox 3.4

Edit - problem solved thanks to Stuart McCulloch. I need to refresh the framework as well. So stopping both bundles, updating them and then calling refresh before starting them fixed the problem.


OK, I'm hoping this isn't going to make me sound like too much of a noob but I've been experiencing ClassCastExceptions with some bundles I've been playing around with.

This is using Equinox 3.4 on Mac.

Essentially this is the situation:

Bundle A exports an interface and is designed to load and create instances of classes from other bundles that have a certain manifest header and implement this interface.

Bundle B has a class which implements the interface and the classname specified in the required manifest header.

Bundle A creates an instance of Bundle B's class - using Bundle B's loadClass method to get the class. No problems thus far.

However, OSGi is a dynamic environment so maybe Bundle A needs to go away or be updated for some reason:

Update Bundle A and a ClassCastException is now thrown when loading Bundle B's class. That seems reasonable because I haven't updated Bundle B though I am surprised it is still in the STARTED state. Since it had a dependency on the now updated Bundle A I kind of expected it to be in the RESOLVED state.

So I take more severe action:

Stop Bundle A (now in STOPPED state).

Stop Bundle B (now in STOPPED state).

Update Bundle A (now in INSTALLED state).

Update Bundle B (now in INSTALLED state).

Start Bundle A (Bundle B now in RESOLVED state).

Start Bundle B and I still get a ClassCastException while trying to create an instance of Bundle B's classes even though both bundles have been updated.

Same thing happens even if I completely uninstall Bundle A and/or B.

What I'm asking is should I get the ClassCastException after both bundles have been updated?

It is as though Bundle B is still using the class definition of the interface in Bundle A that was loaded right at the beginning of this exercise.

After an update of both bundles (and certainly a reinstall) I would have expected Bundle B to be using the interface definition from the recently updated Bundle A.

Any thoughts?

Thanks in advance.

The obvious answer is to create a third bundle that contains the interface in question, but then I have two bundles for my functionality and I only want one, especially since this is such a lightweight activity. Also, if I then update the bundle containing the interfaces I suspect that will mess things up for even more bundles.

Also, I really should try this on a different OSGi container such as Felix or Knoplerfish.

No comments: