felix-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Mark Richards <mark.alan.richa...@gmail.com>
Subject Re: Object versions in services
Date Fri, 14 Jun 2013 00:55:34 GMT
I thought I'd implement an example of this and I get ClassCastExceptions in
the Consumer.
Please feel free to checkout:
https://bitbucket.org/markalanrichards/discussion-points/overview
It's not that big (each bundle has only one Java class in it).

When these start (in order) everything is fine: service-api, model10,
model15, model20, model-provider10, model-provider15, model-provider20.
However, when I start modelConsumer10, model 1.0 and model 1.5 are fine for
the consumer, but model 2.0 hits the ClassCastException.

What did I miss?

Many Thanks
Mark

PS: If you don't wish to checkout/run this, but are interested in what
happens, the output when I start model-consumer10 is:
finding refs
objectClass: [Ljava.lang.String;@df54977
provides: com.example.markoffline.model.Model
service.id: 226
TO STRING: Date: 1371160741853
Description: null
THE LONG: 1371160741853
objectClass: [Ljava.lang.String;@11df24ba
provides: com.example.markoffline.model.Model
service.id: 227
TO STRING: Date: 1371160741856
Description: The time now
THE LONG: 1371160741856
objectClass: [Ljava.lang.String;@373984fd
provides: com.example.markoffline.model.Model
service.id: 228
---
--- Here the bundle hits an exception trace, probably not too useful except
for:
---
Caused by: java.lang.ClassCastException:
com.example.markoffline.model.Model cannot be cast to
com.example.markoffline.model.Model
    at
com.example.markoffline.consumer.ModelConsumer.start(ModelConsumer.java:27)






On 13 June 2013 11:27, Felix Meschberger <fmeschbe@adobe.com> wrote:

> Hi
>
> Am 13.06.2013 um 12:18 schrieb Mark Richards:
>
> > Thanks...
> > "In addition the service registry makes sure, that D only gets V1 Model
> > service instances and E only gets V2 Model service instances."
> > I assumed the registry would only care about the versions of Producer and
> > Consumer, as the Models aren't bound directly to the service.
>
> The service registry does not care for versions at all. It cares to make
> sure a consumer (retrieving the service) can use the service by making
> sure, the consumer and the service object see the same service object class
> objects and thus are compatible.
>
> Regards
> Felix
>
> >
> >
> > On 13 June 2013 09:56, Felix Meschberger <fmeschbe@adobe.com> wrote:
> >
> >> Hi
> >>
> >> OSGi wires API by import and export package version.
> >>
> >> In you example of two incompatible model classes, you might have bundle
> B
> >> export the Model API at version 1.0 and bundle C export the Model API at
> >> version 2.0.
> >>
> >> Your consumer bundles D and E would then import the appropriate Model
> API
> >> versions such as [1,2) and [2,3).
> >>
> >> The actual Model class objects are then different for D and E (even
> though
> >> the fully qualified class name is the same). In addition the service
> >> registry makes sure, that D only gets V1 Model service instances and E
> only
> >> gets V2 Model service instances.
> >>
> >> Hope this helps.
> >>
> >> Regards
> >> Felix
> >>
> >> Am 12.06.2013 um 17:56 schrieb Mark Richards:
> >>
> >>> Hi,
> >>>
> >>> I'm new to this list and hopefully this question isn't too long...
> please
> >>> let me know if you'd like further details.
> >>>
> >>> Context: I'd like to create a service architecture that represents
> EIPs,
> >> a
> >>> bit like Camel but more OSGi friendly, however the safe wiring of
> objects
> >>> must ensure the producers are wired to consumers that provide and
> >> consumer
> >>> compatible versions of the objects.
> >>>
> >>> Problem: How do you handle the versions dependencies of objects used a
> >>> layer beneath the services provided?
> >>>
> >>> I believe this issue also affects the listener model, if you wanted to
> >> use
> >>> a generic listener model like so I'm hoping somebody has already solved
> >> it:
> >>>
> >>> interface Listener<T> { //Listener class is handled by bundle
> resolution
> >>>   void Notify(T event); //but what about this T?
> >>> }
> >>>
> >>>
> >>> When you create an implementation you usually know T, so it's quite
> easy
> >> to
> >>> call "bundleContext.register(Listener.class, this, props)" where props
> >>> includes {"listenerOf":"t.class}" and to then filter the class.
> However,
> >>> I'm not sure where to get the version for T from (it may be an imported
> >>> class) and versions are ranges with different rules for import and
> >> export.
> >>>
> >>> Any help advice or also, an idea of whether I'm the only one trying to
> do
> >>> this would be useful.
> >>>
> >>> Thanks,
> >>> Mark
> >>>
> >>>
> >>> Ps: if it helps here is an example of the style of problem in
> semi-pseudo
> >>> code.
> >>> If you cannot filter the version of the Model through the services
> layer
> >>> ModelProvider will provide a Date object and ModelConsumer will try to
> >> read
> >>> a Long. The two shouldn't be allowed to bind to each other.
> >>>
> >>>
> >>> bundle A: wiring-api
> >>>   interface Provider<T> {
> >>>       T giveMeAnObject();
> >>>   }
> >>>   interface Consumer<T> {
> >>>       void hereIsAnObject(T object);
> >>>   }
> >>>
> >>> bundle B: model version 1:
> >>>   class Model {
> >>>       long getDate();{ return (long) 99 }
> >>>   }
> >>>
> >>> bundle C: model version 2:
> >>>   class Model {
> >>>       Date getDate() { return new Date(); }
> >>>   }
> >>>
> >>> bundle D: model-provder version 2: import-packages wiring-api 1 and
> >> model 2
> >>>   class ModelProvider implements Provider <Model>  implements
> >>> BundleActivator { {
> >>>       void start(BundleContext context) {
> >>>           context.register(Provider.class, this, ???? )* // here you'd
> >>> need to specify it is model 2, but how do you get this*
> >>>      }
> >>>       Model giveMeAnObject() {
> >>>           return new Model();
> >>>       }
> >>>   }
> >>> bundle E: consumer imports wiring-api and model 1:
> >>>   class ModelConsumer implements Consumer<Model>, BundleActivator
{
> >>>       void start(BundleContext context) {
> >>>           context.register(Consumer.class, this, ???? )* // here you'd
> >>> need to specify it is model 1, but how do you get this**
> >>> *        }*
> >>> *
> >>>
> >>>       void hereIsAnObject(Model object) {
> >>>           System.out.println(Long.valueOf(model.getDate())); // if no
> >>> object version filtering this will fail as bundle D should not be
> >> connected
> >>> to bundle E
> >>>       }
> >>>   }
> >>>
> >>> // here I envisage there should be a Provider Manager perhaps along the
> >>> lines of that could be exposed to have wiring done through a UI,
> >> interface
> >>> or config settings like WireAdmin
> >>> // this isn't too important at this point, except it would need some
> way
> >> to
> >>> manage this *version filtering/matching*!
> >>> bundle F: provider-service imports wiring-api
> >>>   class ProviderManager {
> >>>       Map<ClassVersion, Provider> providers;
> >>>       Map<ClassVersion, Consumer, consumers
> >>>       void registerProvider(ClassVersion<T> provided, Provider<T>
> >>> provider);
> >>>       void registerConsumer(ClassVersion<T> consumed, Consumer<T>
> >>> provider);
> >>>
> >>>      // methods to lookup and match providers with consumers
> >>>   }
> >>
> >>
> >> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> >> For additional commands, e-mail: users-help@felix.apache.org
> >>
> >>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message