It looks like binding multiple optional references in OSGi is flaky at least with Felix 1.2.0. Uhh what does that mean?
AFAICT, an annotation like
@Reference(name="virtualResourceType", cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE, referenceInterface = VirtualResourceType.class)
with
public void bindVirtualResourceType(VirtualResourceType virtualResourceType) { log.info("Bound "+virtualResourceType); store.put(virtualResourceType,virtualResourceType); } public void unbindVirtualResourceType(VirtualResourceType virtualResourceType) { log.info("UnBound "+virtualResourceType); store.remove(virtualResourceType); }
Only binds some of the time on reload, but unbind works every time.
I have a feeling that below will work, no idea why ?
protected void bindVirtualResourceType(ServiceReference reference) { VirtualResourceType virtualResourceType = (VirtualResourceType) this.componentContext.locateService( "VirtualResourceType", reference); if ( virtualResourceType != null ) { LOGGER.info("=====================BOUND VIRTUAL RESOURCE TYPE{}===============================",virtualResourceType.getResourceType()); virtualResourceTypes.put(virtualResourceType.getResourceType(), virtualResourceType); } else { LOGGER.info("=====================Faied to find BOUND VIRTUAL RESOURCE TYPE{}===============================",reference); } }
Update:
The annotation should have been
@Reference(name = “virtualResourceType”,
cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE,
referenceInterface = VirtualResourceType.class,
policy = ReferencePolicy.DYNAMIC)
and then the bind and unbind can be
protected void bindVirtualResourceType(VirtualResourceType virtualResourceType) { virtualResourceTypes.put(virtualResourceType.getResourceType(), virtualResourceType); } protected void unbindVirtualResourceType(VirtualResourceType virtualResourceType) { virtualResourceTypes.remove(virtualResourceType.getResourceType()); }
(I am an idiot!)
You are not an idiot. You ran into a fixed bug. In older releases of the Felix Declarative Services implementations static references were updated as soon as they became available by cycling the component. This is in fact wrong: static references are only bound at the time the component is activated. Unbinding is different of course because a reference must immediately be unbound and thus the component be cycled.