David,
What you're describing here:
To use your example above, some bundle (BundleS) will register a
Skateboard
as a Vehicle to the system, which is tracked by BundleA. BundleA
will then
manage the Skateboard just like it would any other Vehicle. BundleS
should
not need to do anything regarding management other than registering
the
Skateboard as an OSGi service implementing Vehicle with a property
"id=skateboard". BundleA, from its perspective, just receives a
Vehicle that
it then takes control of as a Vehicle (it doesn't need to know any
of the
details of a Skateboard).
Is *exactly* how OSGi services work. BundleS would instantiate a
Skateboard in the normal way and register it under the Vehicle
interface. BundleA would then track services registered under the
Vehicle interface. BundleA only needs to know the Vehicle interface,
not any specific implementations of it.
However you then say:
Since BundleS knows the specific type, I was wondering how I can
pass on
that type to BundleA at runtime so the service is already casted to
the
specific type.
Why do you need to do this? BundleA or BundleB will obtain the actual
skateboard object registered by BundleS. It does not need to cast, it
can call any of the methods of the Vehicle interface on that object.
On the other hand if BundleA or BundleB need to know that it's a
Skateboard, then they have a straightforward dependency on the
Skateboard class which can be modelled with static Import-Package.
There are many ways to do this in plain old java, but the
problem is classloading in OSGi, since Skateboard is not imported. I
am
trying to avoid forcing a convention like "must be of class
com.blah.foo.bar.*" so I can use dynamic imports. I want the choice
of class
to be free, which means there's no way of using the dynamic-import
in the
manifest.
If it can't be done, it can't be done, but it is a very nice-to-have
with
regards to what I'm trying to do:
// The lifecycle management system from BundleA
Service service = getVehicleService();
// Registering Skateboard from BundleS
Skateboard skateboard = new Skateboard();
bundleContext.registerService( ... ) //register Skateboard as Vehicle
// Use the registered service from BundleB
Skateboard skateboard = service.getVehicle( "skateboard" );
Sorry but this is not how Java works. If the return type of the
getVehicle() method is Skateboard then it will always return
Skateboard even when you call getVehicle("bus"). Naturally the
VehicleService must also have a straightforward static dependency on
Skateboard, along with every other kind of vehicle it supports.
Does BundleB really need to use the methods of Skateboard rather than
just treating the object as a Vehicle? What is BundleA's role here...
why doesn't BundleB just obtain the object directly from the OSGi
service registry and cast it to Skateboard?
Anyway, this is all somewhat pointless. If BundleB needs to be aware
of the precise type of the object it obtains, you might as well just
call "new Skateboard()" in BundleB. If you need to manage the number
of instances of Skateboard, then make it into a plain old GoF-style
Singleton. I don't see what value your framework provides.
Regards,
Neil
_______________________________________________
OSGi Developer Mail List
[email protected]
http://www2.osgi.org/mailman/listinfo/osgi-dev