You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/11/07 10:20:33 UTC
[sling-org-apache-sling-testing-osgi-mock] 05/07: SLING-6372 OSGi
Mocks - Correctly handle static, greedy references
This is an automated email from the ASF dual-hosted git repository.
rombert pushed a commit to annotated tag org.apache.sling.testing.osgi-mock-1.9.2
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-osgi-mock.git
commit 3253df9cd1fa8e6641aad78b78bd706c3fb3511c
Author: Stefan Seifert <ss...@apache.org>
AuthorDate: Fri Dec 9 22:30:56 2016 +0000
SLING-6372 OSGi Mocks - Correctly handle static, greedy references
git-svn-id: https://svn.apache.org/repos/asf/sling/branches/testing/mocks/osgi-mock-1.x@1773480 13f79535-47bb-0310-9956-ffa450edef68
---
.../sling/testing/mock/osgi/MockBundleContext.java | 76 ++++++++-
.../sling/testing/mock/osgi/OsgiServiceUtil.java | 31 +++-
...ockBundleContextStaticGreedyReferencesTest.java | 186 +++++++++++++++++++++
.../testing/mock/osgi/OsgiServiceUtilTest.java | 103 ++++++++++++
...sling.testing.mock.osgi.OsgiServiceUtilTest.xml | 8 +
5 files changed, 398 insertions(+), 6 deletions(-)
diff --git a/src/main/java/org/apache/sling/testing/mock/osgi/MockBundleContext.java b/src/main/java/org/apache/sling/testing/mock/osgi/MockBundleContext.java
index ce94c04..ea0808a 100644
--- a/src/main/java/org/apache/sling/testing/mock/osgi/MockBundleContext.java
+++ b/src/main/java/org/apache/sling/testing/mock/osgi/MockBundleContext.java
@@ -111,8 +111,8 @@ class MockBundleContext implements BundleContext {
public ServiceRegistration registerService(final String[] clazzes, final Object service, final Dictionary properties) {
Dictionary<String, Object> mergedPropertes = MapMergeUtil.propertiesMergeWithOsgiMetadata(service, configAdmin, properties);
MockServiceRegistration registration = new MockServiceRegistration(this.bundle, clazzes, service, mergedPropertes, this);
- handleRefsUpdateOnRegister(registration);
this.registeredServices.add(registration);
+ handleRefsUpdateOnRegister(registration);
notifyServiceListeners(ServiceEvent.REGISTERED, registration.getReference());
return registration;
}
@@ -123,8 +123,10 @@ class MockBundleContext implements BundleContext {
* @param registration
*/
private void handleRefsUpdateOnRegister(MockServiceRegistration registration) {
- List<ReferenceInfo> affectedReferences = OsgiServiceUtil.getMatchingDynamicReferences(registeredServices, registration);
- for (ReferenceInfo referenceInfo : affectedReferences) {
+
+ // handle DYNAMIC references to this registration
+ List<ReferenceInfo> affectedDynamicReferences = OsgiServiceUtil.getMatchingDynamicReferences(registeredServices, registration);
+ for (ReferenceInfo referenceInfo : affectedDynamicReferences) {
Reference reference = referenceInfo.getReference();
switch (reference.getCardinality()) {
case MANDATORY_UNARY:
@@ -140,6 +142,24 @@ class MockBundleContext implements BundleContext {
throw new RuntimeException("Unepxected cardinality: " + reference.getCardinality());
}
}
+
+ // handle STATIC+GREEDY references to this registration
+ List<ReferenceInfo> affectedStaticGreedyReferences = OsgiServiceUtil.getMatchingStaticGreedyReferences(registeredServices, registration);
+ for (ReferenceInfo referenceInfo : affectedStaticGreedyReferences) {
+ Reference reference = referenceInfo.getReference();
+ switch (reference.getCardinality()) {
+ case MANDATORY_UNARY:
+ throw new ReferenceViolationException("Mandatory unary reference of type " + reference.getInterfaceType() + " already fulfilled "
+ + "for service " + reference.getServiceClass().getName() + ", registration of new service with this interface failed.");
+ case MANDATORY_MULTIPLE:
+ case OPTIONAL_MULTIPLE:
+ case OPTIONAL_UNARY:
+ restartService(referenceInfo.getServiceRegistration());
+ break;
+ default:
+ throw new RuntimeException("Unepxected cardinality: " + reference.getCardinality());
+ }
+ }
}
void unregisterService(MockServiceRegistration registration) {
@@ -147,6 +167,31 @@ class MockBundleContext implements BundleContext {
handleRefsUpdateOnUnregister(registration);
notifyServiceListeners(ServiceEvent.UNREGISTERING, registration.getReference());
}
+
+ void restartService(MockServiceRegistration registration) {
+ // get current service properties
+ Class<?> serviceClass = registration.getService().getClass();
+ Map<String,Object> properties = MapUtil.toMap(registration.getProperties());
+
+ // deactivate & unregister service
+ MockOsgi.deactivate(registration.getService(), this);
+ unregisterService(registration);
+
+ // newly create and register service
+ Object newService;
+ try {
+ newService = serviceClass.newInstance();
+ }
+ catch (InstantiationException e) {
+ throw new RuntimeException("Unable to instantiate service: " + serviceClass);
+ }
+ catch (IllegalAccessException e) {
+ throw new RuntimeException("Unable to access service class: " + serviceClass);
+ }
+ MockOsgi.injectServices(newService, this);
+ MockOsgi.activate(newService, this, properties);
+ registerService(serviceClass.getName(), newService, MapUtil.toDictionary(properties));
+ }
/**
* Check for already registered services that may be affected by the service unregistration - either
@@ -154,8 +199,10 @@ class MockBundleContext implements BundleContext {
* @param registration
*/
private void handleRefsUpdateOnUnregister(MockServiceRegistration registration) {
- List<ReferenceInfo> affectedReferences = OsgiServiceUtil.getMatchingDynamicReferences(registeredServices, registration);
- for (ReferenceInfo referenceInfo : affectedReferences) {
+
+ // handle DYNAMIC references to this registration
+ List<ReferenceInfo> affectedDynamicReferences = OsgiServiceUtil.getMatchingDynamicReferences(registeredServices, registration);
+ for (ReferenceInfo referenceInfo : affectedDynamicReferences) {
Reference reference = referenceInfo.getReference();
switch (reference.getCardinality()) {
case MANDATORY_UNARY:
@@ -173,6 +220,25 @@ class MockBundleContext implements BundleContext {
throw new RuntimeException("Unepxected cardinality: " + reference.getCardinality());
}
}
+
+ // handle STATIC+GREEDY references to this registration
+ List<ReferenceInfo> affectedStaticGreedyReferences = OsgiServiceUtil.getMatchingStaticGreedyReferences(registeredServices, registration);
+ for (ReferenceInfo referenceInfo : affectedStaticGreedyReferences) {
+ Reference reference = referenceInfo.getReference();
+ switch (reference.getCardinality()) {
+ case MANDATORY_UNARY:
+ throw new ReferenceViolationException("Reference of type " + reference.getInterfaceType() + " "
+ + "for service " + reference.getServiceClass().getName() + " is mandatory unary, "
+ + "unregistration of service with this interface failed.");
+ case MANDATORY_MULTIPLE:
+ case OPTIONAL_MULTIPLE:
+ case OPTIONAL_UNARY:
+ restartService(referenceInfo.getServiceRegistration());
+ break;
+ default:
+ throw new RuntimeException("Unepxected cardinality: " + reference.getCardinality());
+ }
+ }
}
@Override
diff --git a/src/main/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtil.java b/src/main/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtil.java
index 05a26bc..15340d4 100644
--- a/src/main/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtil.java
+++ b/src/main/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtil.java
@@ -33,6 +33,7 @@ import org.apache.sling.testing.mock.osgi.OsgiMetadataUtil.OsgiMetadata;
import org.apache.sling.testing.mock.osgi.OsgiMetadataUtil.Reference;
import org.apache.sling.testing.mock.osgi.OsgiMetadataUtil.ReferenceCardinality;
import org.apache.sling.testing.mock.osgi.OsgiMetadataUtil.ReferencePolicy;
+import org.apache.sling.testing.mock.osgi.OsgiMetadataUtil.ReferencePolicyOption;
import org.osgi.framework.BundleContext;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
@@ -407,7 +408,8 @@ final class OsgiServiceUtil {
}
/**
- * Collects all references of any registered service that match with any of the exported interfaces of the given service registration.
+ * Collects all references of any registered service that match with any of the exported interfaces of the given service registration
+ * and are defined as DYNAMIC.
* @param registeredServices Registered Services
* @param registration Service registration
* @return List of references
@@ -432,6 +434,33 @@ final class OsgiServiceUtil {
return references;
}
+ /**
+ * Collects all references of any registered service that match with any of the exported interfaces of the given service registration
+ * and are defined as STATIC + GREEDY.
+ * @param registeredServices Registered Services
+ * @param registration Service registration
+ * @return List of references
+ */
+ public static List<ReferenceInfo> getMatchingStaticGreedyReferences(SortedSet<MockServiceRegistration> registeredServices,
+ MockServiceRegistration registration) {
+ List<ReferenceInfo> references = new ArrayList<ReferenceInfo>();
+ for (MockServiceRegistration existingRegistration : registeredServices) {
+ OsgiMetadata metadata = OsgiMetadataUtil.getMetadata(existingRegistration.getService().getClass());
+ if (metadata != null) {
+ for (Reference reference : metadata.getReferences()) {
+ if (reference.getPolicy() == ReferencePolicy.STATIC && reference.getPolicyOption() == ReferencePolicyOption.GREEDY) {
+ for (String serviceInterface : registration.getClasses()) {
+ if (StringUtils.equals(serviceInterface, reference.getInterfaceType())) {
+ references.add(new ReferenceInfo(existingRegistration, reference));
+ }
+ }
+ }
+ }
+ }
+ }
+ return references;
+ }
+
static class ServiceInfo {
private final Object serviceInstance;
diff --git a/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextStaticGreedyReferencesTest.java b/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextStaticGreedyReferencesTest.java
new file mode 100644
index 0000000..98d31c3
--- /dev/null
+++ b/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextStaticGreedyReferencesTest.java
@@ -0,0 +1,186 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.testing.mock.osgi;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+
+import org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest.Service3StaticGreedy;
+import org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest.ServiceInterface1;
+import org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest.ServiceInterface1Optional;
+import org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest.ServiceInterface2;
+import org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest.ServiceInterface3;
+import org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest.ServiceSuperInterface3;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+
+import com.google.common.collect.ImmutableSet;
+
+@RunWith(MockitoJUnitRunner.class)
+public class MockBundleContextStaticGreedyReferencesTest {
+
+ private BundleContext bundleContext;
+ private ServiceRegistration reg1a;
+ private ServiceRegistration reg2a;
+
+ @Mock
+ private ServiceInterface1 dependency1a;
+ @Mock
+ private ServiceInterface1 dependency1b;
+ @Mock
+ private ServiceInterface1Optional dependency1aOptional;
+ @Mock
+ private ServiceInterface1Optional dependency1bOptional;
+ @Mock
+ private ServiceInterface2 dependency2a;
+ @Mock
+ private ServiceInterface2 dependency2b;
+ @Mock
+ private ServiceSuperInterface3 dependency3a;
+ @Mock
+ private ServiceSuperInterface3 dependency3b;
+
+ @Before
+ public void setUp() {
+ bundleContext = MockOsgi.newBundleContext();
+
+ // setup service instance with only minimum mandatory references
+ reg1a = bundleContext.registerService(ServiceInterface1.class.getName(), dependency1a, null);
+ reg2a = bundleContext.registerService(ServiceInterface2.class.getName(), dependency2a, null);
+
+ Service3StaticGreedy service = new Service3StaticGreedy();
+ MockOsgi.injectServices(service, bundleContext);
+ MockOsgi.activate(service, bundleContext);
+ bundleContext.registerService(Service3StaticGreedy.class.getName(), service, null);
+
+ assertDependency1(dependency1a);
+ assertDependency1Optional(null);
+ assertDependencies2(dependency2a);
+ assertDependencies3();
+ }
+
+ @Test
+ public void testAddRemoveOptionalUnaryService() {
+ ServiceRegistration reg1aOptional = bundleContext.registerService(ServiceInterface1Optional.class.getName(), dependency1aOptional, null);
+ assertDependency1Optional(dependency1aOptional);
+
+ reg1aOptional.unregister();
+ assertDependency1Optional(null);
+ }
+
+ public void testAddOptionalUnaryService_TooMany() {
+ bundleContext.registerService(ServiceInterface1Optional.class.getName(), dependency1aOptional, null);
+ assertDependency1Optional(dependency1aOptional);
+
+ // in real OSGi this should fail - but this is not covered by the current implementation. so test the real implementation here.
+ bundleContext.registerService(ServiceInterface1Optional.class.getName(), dependency1bOptional, null);
+ assertDependency1Optional(dependency1bOptional);
+ }
+
+ @Test(expected = ReferenceViolationException.class)
+ public void testAddMandatoryUnaryService_TooMany() {
+ bundleContext.registerService(ServiceInterface1.class.getName(), dependency1b, null);
+ }
+
+ @Test(expected = ReferenceViolationException.class)
+ public void testRemoveMandatoryUnaryService_TooMany() {
+ reg1a.unregister();
+ }
+
+ @Test
+ public void testAddRemoveOptionalMultipleService() {
+ ServiceRegistration reg3a = bundleContext.registerService(ServiceInterface3.class.getName(), dependency3a, null);
+ assertDependencies3(dependency3a);
+
+ ServiceRegistration reg3b = bundleContext.registerService(ServiceInterface3.class.getName(), dependency3b, null);
+ assertDependencies3(dependency3a, dependency3b);
+
+ reg3a.unregister();
+ assertDependencies3(dependency3b);
+
+ reg3b.unregister();
+ assertDependencies3();
+ }
+
+ @Test
+ public void testAddRemoveMandatoryMultipleService() {
+ ServiceRegistration reg2b = bundleContext.registerService(ServiceInterface2.class.getName(), dependency2b, null);
+ assertDependencies2(dependency2a, dependency2b);
+
+ reg2b.unregister();
+ assertDependencies2(dependency2a);
+ }
+
+ @Test(expected = ReferenceViolationException.class)
+ public void testAddRemoveMandatoryMultipleService_FailReg2aUnregister() {
+ ServiceRegistration reg2b = bundleContext.registerService(ServiceInterface2.class.getName(), dependency2b, null);
+ assertDependencies2(dependency2a, dependency2b);
+
+ reg2b.unregister();
+ assertDependencies2(dependency2a);
+
+ // this should fail
+ reg2a.unregister();
+ }
+
+ private void assertDependency1(ServiceInterface1 instance) {
+ Service3StaticGreedy service =getService();
+ if (instance == null) {
+ assertNull(service.getReference1());
+ }
+ else {
+ assertSame(instance, service.getReference1());
+ }
+ }
+
+ private void assertDependency1Optional(ServiceInterface1Optional instance) {
+ Service3StaticGreedy service =getService();
+ if (instance == null) {
+ assertNull(service.getReference1Optional());
+ }
+ else {
+ assertSame(instance, service.getReference1Optional());
+ }
+ }
+
+ private void assertDependencies2(ServiceInterface2... instances) {
+ Service3StaticGreedy service =getService();
+ assertEquals(ImmutableSet.<ServiceInterface2>copyOf(instances),
+ ImmutableSet.<ServiceInterface2>copyOf(service.getReferences2()));
+ }
+
+ private void assertDependencies3(ServiceSuperInterface3... instances) {
+ Service3StaticGreedy service =getService();
+ assertEquals(ImmutableSet.<ServiceSuperInterface3>copyOf(instances),
+ ImmutableSet.<ServiceSuperInterface3>copyOf(service.getReferences3()));
+ }
+
+ private Service3StaticGreedy getService() {
+ ServiceReference serviceRef = bundleContext.getServiceReference(Service3StaticGreedy.class.getName());
+ return (Service3StaticGreedy)bundleContext.getService(serviceRef);
+ }
+
+}
diff --git a/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtilTest.java b/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtilTest.java
index 253b401..988cf26 100644
--- a/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtilTest.java
+++ b/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtilTest.java
@@ -340,6 +340,109 @@ public class OsgiServiceUtilTest {
}
@Component
+ @References({ @Reference(name = "reference2", referenceInterface = ServiceInterface2.class, cardinality = ReferenceCardinality.MANDATORY_MULTIPLE) })
+ public static class Service3StaticGreedy {
+
+ @Reference
+ private ServiceInterface1 reference1;
+ @Reference(cardinality = ReferenceCardinality.OPTIONAL_UNARY)
+ private ServiceInterface1Optional reference1Optional;
+
+ private List<ServiceReference> references2 = new ArrayList<ServiceReference>();
+
+ @Reference(name = "reference3", referenceInterface = ServiceInterface3.class, cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE)
+ private List<ServiceSuperInterface3> references3 = new ArrayList<ServiceSuperInterface3>();
+ private List<Map<String, Object>> reference3Configs = new ArrayList<Map<String, Object>>();
+
+ private ComponentContext componentContext;
+ private Map<String, Object> config;
+
+ @SuppressWarnings("unchecked")
+ @Activate
+ private void activate(ComponentContext ctx) {
+ this.componentContext = ctx;
+ this.config = MapUtil.toMap(ctx.getProperties());
+ }
+
+ @Deactivate
+ private void deactivate(ComponentContext ctx) {
+ this.componentContext = null;
+ }
+
+ @Modified
+ private void modified(Map<String,Object> newConfig) {
+ this.config = newConfig;
+ }
+
+ public ServiceInterface1 getReference1() {
+ return this.reference1;
+ }
+
+ public ServiceInterface1Optional getReference1Optional() {
+ return this.reference1Optional;
+ }
+
+ public List<ServiceInterface2> getReferences2() {
+ List<ServiceInterface2> services = new ArrayList<ServiceInterface2>();
+ for (ServiceReference serviceReference : references2) {
+ services.add((ServiceInterface2)componentContext.getBundleContext().getService(serviceReference));
+ }
+ return services;
+ }
+
+ public List<ServiceSuperInterface3> getReferences3() {
+ return this.references3;
+ }
+
+ public List<Map<String, Object>> getReference3Configs() {
+ return this.reference3Configs;
+ }
+
+ public ComponentContext getComponentContext() {
+ return this.componentContext;
+ }
+
+ public Map<String, Object> getConfig() {
+ return config;
+ }
+
+ protected void bindReference1Optional(ServiceInterface1Optional service) {
+ reference1Optional = service;
+ }
+
+ protected void unbindReference1Optional(ServiceInterface1Optional service) {
+ reference1Optional = null;
+ }
+
+ protected void bindReference1(ServiceInterface1 service) {
+ reference1 = service;
+ }
+
+ protected void unbindReference1(ServiceInterface1 service) {
+ reference1 = null;
+ }
+
+ protected void bindReference2(ServiceReference serviceReference) {
+ references2.add(serviceReference);
+ }
+
+ protected void unbindReference2(ServiceReference serviceReference) {
+ references2.remove(serviceReference);
+ }
+
+ protected void bindReference3(ServiceSuperInterface3 service, Map<String, Object> serviceConfig) {
+ references3.add(service);
+ reference3Configs.add(serviceConfig);
+ }
+
+ protected void unbindReference3(ServiceSuperInterface3 service, Map<String, Object> serviceConfig) {
+ references3.remove(service);
+ reference3Configs.remove(serviceConfig);
+ }
+
+ }
+
+ @Component
@Reference(referenceInterface = ServiceInterface1.class, name = "customName", bind = "customBind", unbind = "customUnbind")
public static class Service4 {
diff --git a/src/test/resources/OSGI-INF/org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest.xml b/src/test/resources/OSGI-INF/org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest.xml
index a9d3623..bf88df7 100644
--- a/src/test/resources/OSGI-INF/org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest.xml
+++ b/src/test/resources/OSGI-INF/org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest.xml
@@ -43,6 +43,14 @@
<reference name="reference2" interface="org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest$ServiceInterface2" cardinality="1..n" policy="dynamic" bind="bindReference2" unbind="unbindReference2"/>
<reference name="reference3" interface="org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest$ServiceInterface3" cardinality="0..n" policy="dynamic" bind="bindReference3" unbind="unbindReference3"/>
</scr:component>
+ <scr:component name="org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest$Service3StaticGreedy" activate="activate" deactivate="deactivate" modified="modified">
+ <implementation class="org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest$Service3StaticGreedy"/>
+ <property name="service.pid" value="org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest$Service3StaticGreedy"/>
+ <reference name="reference1" interface="org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest$ServiceInterface1" cardinality="1..1" policy="static" policy-option="greedy" bind="bindReference1" unbind="unbindReference1"/>
+ <reference name="reference1Optional" interface="org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest$ServiceInterface1Optional" cardinality="0..1" policy="dynamic" policy-option="greedy" bind="bindReference1Optional" unbind="unbindReference1Optional"/>
+ <reference name="reference2" interface="org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest$ServiceInterface2" cardinality="1..n" policy="static" policy-option="greedy" bind="bindReference2" unbind="unbindReference2"/>
+ <reference name="reference3" interface="org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest$ServiceInterface3" cardinality="0..n" policy="static" policy-option="greedy" bind="bindReference3" unbind="unbindReference3"/>
+ </scr:component>
<scr:component name="org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest$Service4_other_name">
<implementation class="org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest$Service4"/>
<property name="service.pid" value="org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest$Service4"/>
--
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.