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: