Kyle Giovannetti created SLING-11668:
----------------------------------------

             Summary: [osgi-mocks] Dynamic service references not updated on 
osgi Components
                 Key: SLING-11668
                 URL: https://issues.apache.org/jira/browse/SLING-11668
             Project: Sling
          Issue Type: Bug
          Components: Testing
    Affects Versions: Testing OSGi Mock 3.3.2
            Reporter: Kyle Giovannetti


In osgi-mocks, when a OSGI Component (*without* a service interface) is 
registered via `registerInjectActivateService`, and that component has dynamic 
non-mandatory service references that are not fulfilled at the time of the 
component initialization, those services references are never bound later when 
they become available.

 

Having stepped through the debugger, I believe that this condition is the cause:
[https://github.com/apache/sling-org-apache-sling-testing-osgi-mock/blob/5ce257bd07c5087f0340d7b7ab426971128eb69f/core/src/main/java/org/apache/sling/testing/mock/osgi/MockOsgi.java#L274-L278]

 
{code:java}
 public static final @NotNull <T> T registerInjectActivateService(@NotNull 
Class<T> dsComponentClass, @NotNull BundleContext bundleContext, @Nullable 
final Map<String, Object> properties) {
    Map<String, Object> mergedProperties = 
propertiesMergeWithOsgiMetadata(dsComponentClass, 
getConfigAdmin(bundleContext), properties);
    ComponentContext componentContext = newComponentContext(bundleContext, 
mergedProperties);
    T component = OsgiServiceUtil.activateInjectServices(dsComponentClass, 
(MockComponentContext)componentContext);
    OsgiMetadata metadata = OsgiMetadataUtil.getMetadata(dsComponentClass);
    if (!metadata.getServiceInterfaces().isEmpty()) {
        // convert component properties to service properties 
(http://docs.osgi.org/specification/osgi.cmpn/7.0.0/service.component.html#service.component-service.properties)
        Dictionary<String, Object> serviceProperties = 
mergedProperties.entrySet().stream().filter(e -> e.getKey() != null && 
!e.getKey().startsWith(".")).collect(new DictionaryCollector<String, 
Object>(Entry::getKey, Entry::getValue));
        
bundleContext.registerService(metadata.getServiceInterfaces().toArray(new 
String[0]), component, serviceProperties);
    }
    return component;
}{code}
 

 

Here we see that if the service doesn't implement any interfaces, then it's 
completely forgotten about after being activated.

This appears to be by-design as per 
[SLING-10922|https://issues.apache.org/jira/browse/SLING-10922]. However, in 
non-mock environments, components that do not implement a service interface 
still have references bound/unbound dynamically.

As a consequence of this, in tests, the ordering of service activation becomes 
critically important - any component that does not implement and service an 
interface must be activated last, or else the references will not be updated. 

Even implementing/servicing a trivial empty interface resolves the issue.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to