|
Olof, if you need the native ServiceReference, cast the one managed by Spring-DM to ServiceReferenceProxy and then call getTargetServiceReference.
The idea behind the proxy service reference is that it's managed by Spring-DM automatically. you cannot reuse it with the platform but if the importer binds to a different service, this is automatically reflected to the service reference as well (notice that Spring-DM can inject a managed service or a managed service reference depending on your type). As for not being able to use the service reference - I don't recall reading in the OSGi spec /javadoc about any restriction on ServiceReferences to be reusable by the framework. I would argue that the framework could potentially double check the references passed in and use *only* the interface contract w/o any casting. These being said, the reference documentation should contain more information about this topic. I'll open another issue for it. As a separate comment you are right about the equality impact. Since it's defined by an implementation, it might break between two different implementation of the same interface.
The contract holds true though for the same type of implementations. I'll do some more thinking on this topic - from the top of my head, I think one improvement would be for the OSGI spec to specify also the equality/hashcode algorithm otherwise any implementation of the ServiceReference would break this contract. Hi Costin,
I run also in ClassCastExceptions when casting an exposed bundle Service to its exposed interface using Spring DM 1.1.0 Regarding your first comment i tried the following to cast the ServiceReference to ServiceReferenceProxy : protected Object getService(Class clazz) { ServiceReference ref = bundleContext.getServiceReference(clazz.getName()); //return bundleContext.getService(ref); // See Spring OSGi issue ServiceReferenceProxy proxy = (ServiceReferenceProxy) ref; return bundleContext.getService(proxy.getTargetServiceReference()); } But i still got a ClassCastException: java.lang.ClassCastException: org.eclipse.osgi.framework.internal.core.ServiceReferenceImpl Could you give a hint ? This issue regards the managed service-reference instances injected by Spring from osgi:reference elements. See http://is.gd/3jLO for more information. You have basic usage of OSGi which doesn't apply here (though you can improve it by using Spring DM to handle the references for you).
Indeed, thanks for the pointer.
The cast to the native service reference can be used as a workaround.
If I already have a hard dependency on OSGi, which I must have to be using ServiceReferences, I should be aware of the dynamicity issues and handle them properly myself. I don't really see the value-add of getting a hard dependency on Spring-OSGi as well just to be able to use getService/ungetService (the ONLY use case for ServiceReferences). In that case I don't really see the need of exposing the OSGi ServiceReference at all...
/ Olof Olof, one of the features of Spring DM is to track and manage the OSGi service for you. In both cases (service reference injection or service listening), the service reference needs to reflect the service used. Since the service itself can change, the reference can become stale - hence the decision to add a tracking reference.
This is especially relevant in the first case when the service can change after its reference has been injected. While the reference can be used for getting/ungetting the service, in case of Spring DM, since everything is managed already, there is no need to do this - maybe this is not clear from the docs, I'll try to improve them. Access to the service reference is given so that one can access the OSGi specific properties of the service. You can accept a map but also might be interested in who's using the service and so on. > I must have to be using ServiceReferences, I should be aware of the dynamicity issues and handle them properly myself One can use ServiceReference, as I said above, to get access to more information about the environment while leaving Spring DM to do service management. Note that both the listener and injection are done through Spring DM which implies management. If that's not your case, then you can just inject the bundle context and start dealing with the services yourself. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
The patch also modifies the org.springframework.osgi.service.importer.ServiceReferenceProxy interface so it doesn't extend ServiceReference, something that amounts to most of the changes in the patch. This isn't strictly necessary, but it makes sense that it doesn't since it won't (and shouldn't) be used as a ServiceReference.