You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2021/10/28 07:46:14 UTC

[sling-org-apache-sling-adapter] branch master updated: SLING-10885 : Improve adapter factory handling

This is an automated email from the ASF dual-hosted git repository.

cziegeler pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-adapter.git


The following commit(s) were added to refs/heads/master by this push:
     new aa2bf8c  SLING-10885 : Improve adapter factory handling
aa2bf8c is described below

commit aa2bf8c7c81371db6e0b62bad0ef32b86cfbc298
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Thu Oct 28 09:46:10 2021 +0200

    SLING-10885 : Improve adapter factory handling
---
 .gitignore                                         |   1 +
 pom.xml                                            |  95 ++----
 .../adapter/internal/AdapterFactoryDescriptor.java |  20 +-
 .../sling/adapter/internal/AdapterManagerImpl.java | 112 ++-----
 .../adapter/internal/AdapterWebConsolePlugin.java  | 110 ++++---
 .../sling/adapter/internal/AdapterManagerTest.java | 336 ++++++---------------
 6 files changed, 221 insertions(+), 453 deletions(-)

diff --git a/.gitignore b/.gitignore
index 5b783ed..38f5ca4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,4 +14,5 @@ maven-eclipse.xml
 .vlt
 .DS_Store
 jcr.log
+.vscode
 atlassian-ide-plugin.xml
diff --git a/pom.xml b/pom.xml
index 3f1c60b..98b1359 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,13 +22,12 @@
     <modelVersion>4.0.0</modelVersion>
     <parent>
         <groupId>org.apache.sling</groupId>
-        <artifactId>sling</artifactId>
-        <version>30</version>
+        <artifactId>sling-bundle-parent</artifactId>
+        <version>46</version>
         <relativePath />
     </parent>
 
     <artifactId>org.apache.sling.adapter</artifactId>
-    <packaging>bundle</packaging>
     <version>2.1.11-SNAPSHOT</version>
 
     <name>Apache Sling Adapter Manager Implementation</name>
@@ -47,32 +46,9 @@
     <properties>
         <site.jira.version.id>12314288</site.jira.version.id>
         <site.javadoc.exclude>**.impl.**</site.javadoc.exclude>
+        <project.build.outputTimestamp>1</project.build.outputTimestamp>
     </properties>
 
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.felix</groupId>
-                <artifactId>maven-bundle-plugin</artifactId>
-                <extensions>true</extensions>
-                <configuration>
-                    <instructions>
-                        <Import-Package>
-                            org.apache.sling.api.adapter;version="[2.2,2.3)",
-                            *
-                        </Import-Package>
-                    </instructions>
-                </configuration>
-            </plugin>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-javadoc-plugin</artifactId>
-                <configuration>
-                    <additionalparam>-Xdoclint:none</additionalparam>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
     <reporting>
         <plugins>
             <plugin>
@@ -88,48 +64,47 @@
     </reporting>
     <dependencies>
         <dependency>
-            <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.api</artifactId>
-            <version>2.2.0</version>
-            <scope>provided</scope>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.annotation.versioning</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.apache.geronimo.specs</groupId>
-            <artifactId>geronimo-json_1.0_spec</artifactId>
-            <version>1.0-alpha-1</version>
-            <scope>provided</scope>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.service.component.annotations</artifactId>
         </dependency>
         <dependency>
             <groupId>org.osgi</groupId>
             <artifactId>osgi.core</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-api</artifactId>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
         </dependency>
         <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.api</artifactId>
+            <version>2.12.0</version>
+            <scope>provided</scope>
         </dependency>
         <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-simple</artifactId>
-            <scope>test</scope>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-json_1.1_spec</artifactId>
+            <version>1.2</version>
+            <scope>provided</scope>
         </dependency>
         <dependency>
-            <groupId>javax.servlet</groupId>
-            <artifactId>javax.servlet-api</artifactId>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.commons.osgi</artifactId>
-            <version>2.1.0</version>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.util.converter</artifactId>
+            <version>1.0.0</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
             <groupId>org.osgi</groupId>
-            <artifactId>org.osgi.service.component</artifactId>
-            <version>1.3.0</version>
+            <artifactId>org.osgi.util.function</artifactId>
+            <version>1.0.0</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
@@ -139,25 +114,17 @@
             <scope>provided</scope>
         </dependency>
         <dependency>
-            <groupId>org.jmock</groupId>
-            <artifactId>jmock-junit4</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>commons-io</groupId>
-            <artifactId>commons-io</artifactId>
-            <version>1.4</version>
-            <scope>provided</scope>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.apache.commons</groupId>
-            <artifactId>commons-lang3</artifactId>
-            <version>3.4</version>
-            <scope>provided</scope>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
         </dependency>
         <dependency>
-            <groupId>junit-addons</groupId>
-            <artifactId>junit-addons</artifactId>
-            <version>1.4</version>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <version>2.22.0</version>
             <scope>test</scope>
         </dependency>
     </dependencies>
diff --git a/src/main/java/org/apache/sling/adapter/internal/AdapterFactoryDescriptor.java b/src/main/java/org/apache/sling/adapter/internal/AdapterFactoryDescriptor.java
index 1ff0e0d..be1bf22 100644
--- a/src/main/java/org/apache/sling/adapter/internal/AdapterFactoryDescriptor.java
+++ b/src/main/java/org/apache/sling/adapter/internal/AdapterFactoryDescriptor.java
@@ -20,9 +20,7 @@ package org.apache.sling.adapter.internal;
 
 import org.apache.sling.adapter.Adaption;
 import org.apache.sling.api.adapter.AdapterFactory;
-import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.component.ComponentContext;
 
 /**
  * The <code>AdapterFactoryDescriptor</code> is an entry in the
@@ -31,30 +29,20 @@ import org.osgi.service.component.ComponentContext;
  */
 public class AdapterFactoryDescriptor {
 
-    private volatile AdapterFactory factory;
+    private final AdapterFactory factory;
 
     private final String[] adapters;
 
-    private final ServiceReference<AdapterFactory> reference;
-
-    private final ComponentContext context;
-
     private volatile ServiceRegistration<Adaption> adaption;
 
     public AdapterFactoryDescriptor(
-            final ComponentContext context,
-            final ServiceReference<AdapterFactory> reference,
+            final AdapterFactory factory,
             final String[] adapters) {
-        this.reference = reference;
-        this.context = context;
+        this.factory = factory;
         this.adapters = adapters;
     }
 
     public AdapterFactory getFactory() {
-        if ( factory == null ) {
-            factory = context.locateService(
-                    "AdapterFactory", reference);
-        }
         return factory;
     }
 
@@ -66,7 +54,7 @@ public class AdapterFactoryDescriptor {
         return adaption;
     }
 
-    public void setAdaption(ServiceRegistration<Adaption> adaption) {
+    public void setAdaption(final ServiceRegistration<Adaption> adaption) {
         this.adaption = adaption;
     }
 }
diff --git a/src/main/java/org/apache/sling/adapter/internal/AdapterManagerImpl.java b/src/main/java/org/apache/sling/adapter/internal/AdapterManagerImpl.java
index 35f96fa..16a661b 100644
--- a/src/main/java/org/apache/sling/adapter/internal/AdapterManagerImpl.java
+++ b/src/main/java/org/apache/sling/adapter/internal/AdapterManagerImpl.java
@@ -26,7 +26,6 @@ import java.util.Arrays;
 import java.util.Dictionary;
 import java.util.HashMap;
 import java.util.Hashtable;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
@@ -36,19 +35,21 @@ import org.apache.sling.adapter.Adaption;
 import org.apache.sling.api.SlingConstants;
 import org.apache.sling.api.adapter.AdapterFactory;
 import org.apache.sling.api.adapter.AdapterManager;
-import org.apache.sling.api.resource.SyntheticResource;
-import org.apache.sling.commons.osgi.PropertiesUtil;
+import org.apache.sling.api.adapter.SlingAdaptable;
 import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
 import org.osgi.service.component.annotations.Reference;
 import org.osgi.service.component.annotations.ReferenceCardinality;
 import org.osgi.service.component.annotations.ReferencePolicy;
 import org.osgi.service.event.Event;
 import org.osgi.service.event.EventAdmin;
 import org.osgi.service.packageadmin.PackageAdmin;
+import org.osgi.util.converter.Converter;
+import org.osgi.util.converter.Converters;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -70,19 +71,6 @@ public class AdapterManagerImpl implements AdapterManager {
     static final String ALLOWED_IN_PRIVATE = "adapter.allowed.in.private.package";
 
     /**
-     * The OSGi <code>ComponentContext</code> to retrieve
-     * {@link AdapterFactory} service instances.
-     */
-    private volatile ComponentContext context;
-
-    /**
-     * A list of {@link AdapterFactory} services bound to this manager before
-     * the manager has been activated. These bound services will be accessed as
-     * soon as the manager is being activated.
-     */
-    private final List<ServiceReference<AdapterFactory>> boundAdapterFactories = new LinkedList<>();
-
-    /**
      * A map of {@link AdapterFactoryDescriptorMap} instances. The map is
      * indexed by the fully qualified class names listed in the
      * {@link AdapterFactory#ADAPTABLE_CLASSES} property of the
@@ -101,16 +89,14 @@ public class AdapterManagerImpl implements AdapterManager {
      * {@link #getAdapterFactories(Class)} method. It is cleared
      * whenever an adapter factory is registered on unregistered.
      */
-    private final ConcurrentMap<String, Map<String, List<AdapterFactoryDescriptor>>> factoryCache
-    = new ConcurrentHashMap<>();
+    private final ConcurrentMap<String, Map<String, List<AdapterFactoryDescriptor>>> factoryCache = new ConcurrentHashMap<>();
 
     /**
-     * The service tracker for the event admin
+     * The optional event admin
      */
     @Reference(cardinality=ReferenceCardinality.OPTIONAL, policy=ReferencePolicy.DYNAMIC)
     private volatile EventAdmin eventAdmin;
 
-    @Reference
     private PackageAdmin packageAdmin;
 
     // ---------- AdapterManager interface -------------------------------------
@@ -160,33 +146,22 @@ public class AdapterManagerImpl implements AdapterManager {
 
     /**
      * Activate the manager.
-     * Bind all already registered factories
-     * @param context Component context
+     * @param pckAdmin Required package admin
      */
-    protected void activate(final ComponentContext context) {
-        this.context = context;
-
-        // register all adapter factories bound before activation
-        final List<ServiceReference<AdapterFactory>> refs;
-        synchronized ( this.boundAdapterFactories ) {
-            refs = new ArrayList<>(this.boundAdapterFactories);
-            boundAdapterFactories.clear();
-        }
-        for (final ServiceReference<AdapterFactory> reference : refs) {
-            registerAdapterFactory(context, reference);
-        }
+    @Activate
+    public AdapterManagerImpl(final @Reference PackageAdmin pckAdmin) {
+        this.packageAdmin = pckAdmin;
 
-        // final "enable" this manager by setting the instance
-        SyntheticResource.setAdapterManager(this);
+        // "enable" this manager by setting the instance
+        SlingAdaptable.setAdapterManager(this);
     }
 
     /**
      * Deactivate
-     * @param context Not used
      */
-    protected void deactivate(final ComponentContext context) {
-        SyntheticResource.unsetAdapterManager(this);
-        this.context = null;
+    @Deactivate
+    protected void deactivate() {
+        SlingAdaptable.unsetAdapterManager(this);
     }
 
     /**
@@ -194,19 +169,8 @@ public class AdapterManagerImpl implements AdapterManager {
      */
     @Reference(name="AdapterFactory", service=AdapterFactory.class,
             cardinality=ReferenceCardinality.MULTIPLE, policy=ReferencePolicy.DYNAMIC)
-    protected void bindAdapterFactory(final ServiceReference<AdapterFactory> reference) {
-        boolean create = true;
-        if (context == null) {
-            synchronized ( this.boundAdapterFactories ) {
-                if (context == null) {
-                    boundAdapterFactories.add(reference);
-                    create = false;
-                }
-            }
-        }
-        if ( create ) {
-            registerAdapterFactory(context, reference);
-        }
+    protected void bindAdapterFactory(final AdapterFactory factory, final ServiceReference<AdapterFactory> reference) {
+        registerAdapterFactory(factory, reference);
     }
 
     /**
@@ -242,14 +206,13 @@ public class AdapterManagerImpl implements AdapterManager {
      * Unregisters the {@link AdapterFactory} referred to by the service
      * <code>reference</code> from the registry.
      */
-    private void registerAdapterFactory(final ComponentContext context,
-            final ServiceReference<AdapterFactory> reference) {
-        final String[] adaptables = PropertiesUtil.toStringArray(reference.getProperty(ADAPTABLE_CLASSES));
-        final String[] adapters = PropertiesUtil.toStringArray(reference.getProperty(ADAPTER_CLASSES));
-        final boolean allowedInPrivatePackage = PropertiesUtil.toBoolean(reference.getProperty(ALLOWED_IN_PRIVATE), false);
-
-        if (adaptables == null || adaptables.length == 0 || adapters == null
-                || adapters.length == 0) {
+    private void registerAdapterFactory(final AdapterFactory factory, final ServiceReference<AdapterFactory> reference) {
+        final Converter converter = Converters.standardConverter();
+        final String[] adaptables = converter.convert(reference.getProperty(ADAPTABLE_CLASSES)).to(String[].class);
+        final String[] adapters = converter.convert(reference.getProperty(ADAPTER_CLASSES)).to(String[].class);
+        final boolean allowedInPrivatePackage = converter.convert(reference.getProperty(ALLOWED_IN_PRIVATE)).defaultValue(false).to(Boolean.class);
+
+        if (adaptables == null || adaptables.length == 0 || adapters == null || adapters.length == 0) {
             return;
         }
 
@@ -265,17 +228,12 @@ public class AdapterManagerImpl implements AdapterManager {
             }
         }
 
-        final AdapterFactoryDescriptor factoryDesc = new AdapterFactoryDescriptor(context,
-                reference, adapters);
+        final AdapterFactoryDescriptor factoryDesc = new AdapterFactoryDescriptor(factory, adapters);
 
         for (final String adaptable : adaptables) {
             AdapterFactoryDescriptorMap adfMap = null;
             synchronized ( this.descriptors ) {
-                adfMap = descriptors.get(adaptable);
-                if (adfMap == null) {
-                    adfMap = new AdapterFactoryDescriptorMap();
-                    descriptors.put(adaptable, adfMap);
-                }
+                adfMap = descriptors.computeIfAbsent(adaptable, key -> new AdapterFactoryDescriptorMap());
             }
             synchronized ( adfMap ) {
                 adfMap.put(reference, factoryDesc);
@@ -290,14 +248,13 @@ public class AdapterManagerImpl implements AdapterManager {
         props.put(SlingConstants.PROPERTY_ADAPTABLE_CLASSES, adaptables);
         props.put(SlingConstants.PROPERTY_ADAPTER_CLASSES, adapters);
 
-        ServiceRegistration<Adaption> adaptionRegistration = this.context.getBundleContext().registerService(
-                Adaption.class, AdaptionImpl.INSTANCE, props);
+        factoryDesc.setAdaption(reference.getBundle().getBundleContext().registerService(
+                Adaption.class, AdaptionImpl.INSTANCE, props));
         if (log.isDebugEnabled()) {
             log.debug("Registered service {} with {} : {} and {} : {}", new Object[] { Adaption.class.getName(),
                     SlingConstants.PROPERTY_ADAPTABLE_CLASSES, Arrays.toString(adaptables),
                     SlingConstants.PROPERTY_ADAPTER_CLASSES, Arrays.toString(adapters) });
         }
-        factoryDesc.setAdaption(adaptionRegistration);
 
         // send event
         final EventAdmin localEA = this.eventAdmin;
@@ -333,14 +290,11 @@ public class AdapterManagerImpl implements AdapterManager {
      * <code>reference</code> from the registry.
      */
     private void unregisterAdapterFactory(final ServiceReference<AdapterFactory> reference) {
-        synchronized ( this.boundAdapterFactories ) {
-            boundAdapterFactories.remove(reference);
-        }
-        final String[] adaptables = PropertiesUtil.toStringArray(reference.getProperty(ADAPTABLE_CLASSES));
-        final String[] adapters = PropertiesUtil.toStringArray(reference.getProperty(ADAPTER_CLASSES));
+        final Converter converter = Converters.standardConverter();
+        final String[] adaptables = converter.convert(reference.getProperty(ADAPTABLE_CLASSES)).to(String[].class);
+        final String[] adapters = converter.convert(reference.getProperty(ADAPTER_CLASSES)).to(String[].class);
 
-        if (adaptables == null || adaptables.length == 0 || adapters == null
-                || adapters.length == 0) {
+        if (adaptables == null || adaptables.length == 0 || adapters == null || adapters.length == 0) {
             return;
         }
 
diff --git a/src/main/java/org/apache/sling/adapter/internal/AdapterWebConsolePlugin.java b/src/main/java/org/apache/sling/adapter/internal/AdapterWebConsolePlugin.java
index 0fca176..7b7f703 100644
--- a/src/main/java/org/apache/sling/adapter/internal/AdapterWebConsolePlugin.java
+++ b/src/main/java/org/apache/sling/adapter/internal/AdapterWebConsolePlugin.java
@@ -20,10 +20,11 @@ import static org.apache.sling.api.adapter.AdapterFactory.ADAPTABLE_CLASSES;
 import static org.apache.sling.api.adapter.AdapterFactory.ADAPTER_CLASSES;
 
 import java.io.IOException;
-import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.io.PrintWriter;
-import java.io.StringReader;
+import java.io.Reader;
 import java.net.URL;
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -48,10 +49,7 @@ import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.builder.CompareToBuilder;
 import org.apache.sling.api.adapter.AdapterFactory;
-import org.apache.sling.commons.osgi.PropertiesUtil;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleEvent;
@@ -60,10 +58,13 @@ import org.osgi.framework.Constants;
 import org.osgi.framework.Filter;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
-import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
 import org.osgi.service.component.annotations.Reference;
 import org.osgi.service.packageadmin.PackageAdmin;
+import org.osgi.util.converter.Converter;
+import org.osgi.util.converter.Converters;
 import org.osgi.util.tracker.ServiceTracker;
 import org.osgi.util.tracker.ServiceTrackerCustomizer;
 import org.slf4j.Logger;
@@ -82,8 +83,6 @@ import org.slf4j.LoggerFactory;
     })
 public class AdapterWebConsolePlugin extends HttpServlet implements ServiceTrackerCustomizer, BundleListener {
 
-    private static final int INDENT = 4;
-
     private static final String ADAPTER_CONDITION = "adapter.condition";
 
     private static final String ADAPTER_DEPRECATED = "adapter.deprecated";
@@ -103,24 +102,26 @@ public class AdapterWebConsolePlugin extends HttpServlet implements ServiceTrack
 
     @Override
     public Object addingService(final ServiceReference reference) {
-        final Object service = this.bundleContext.getService(reference);
-        addServiceMetadata(reference, service);
-        return service;
+        addServiceMetadata(reference);
+        return reference;
     }
 
-    private void addServiceMetadata(final ServiceReference reference, final Object service) {
-        final String[] adapters = PropertiesUtil.toStringArray(reference.getProperty(ADAPTER_CLASSES));
-        final String condition = PropertiesUtil.toString(reference.getProperty(ADAPTER_CONDITION), null);
-        final boolean deprecated = PropertiesUtil.toBoolean(reference.getProperty(ADAPTER_DEPRECATED), false);
-        final String[] adaptables = PropertiesUtil.toStringArray(reference.getProperty(ADAPTABLE_CLASSES));
-        final List<AdaptableDescription> descriptions = new ArrayList<>(adaptables.length);
-        final boolean allowedInPrivatePackage = PropertiesUtil.toBoolean(reference.getProperty(AdapterManagerImpl.ALLOWED_IN_PRIVATE), false);
-        for (final String adaptable : adaptables) {
-            descriptions.add(new AdaptableDescription(reference.getBundle(), adaptable, adapters, condition, deprecated));
-        }
-        synchronized (this) {
-            adapterServiceReferences.put(reference, descriptions);
-            update();
+    private void addServiceMetadata(final ServiceReference reference) {
+        final Converter converter = Converters.standardConverter();
+        final String[] adaptables = converter.convert(reference.getProperty(ADAPTABLE_CLASSES)).to(String[].class);
+        final String[] adapters = converter.convert(reference.getProperty(ADAPTER_CLASSES)).to(String[].class);
+        final String condition = converter.convert(reference.getProperty(ADAPTER_CONDITION)).defaultValue("").to(String.class);
+        final boolean deprecated = converter.convert(reference.getProperty(ADAPTER_DEPRECATED)).defaultValue(false).to(Boolean.class);
+
+        if ( adapters != null && adapters.length > 0 ) {
+            final List<AdaptableDescription> descriptions = new ArrayList<>(adaptables.length);
+            for (final String adaptable : adaptables) {
+                descriptions.add(new AdaptableDescription(reference.getBundle(), adaptable, adapters, condition, deprecated));
+            }
+            synchronized (this) {
+                adapterServiceReferences.put(reference, descriptions);
+                update();
+            }    
         }
     }
 
@@ -135,7 +136,7 @@ public class AdapterWebConsolePlugin extends HttpServlet implements ServiceTrack
 
     @Override
     public void modifiedService(final ServiceReference reference, final Object service) {
-        addServiceMetadata(reference, service);
+        addServiceMetadata(reference);
     }
 
     @Override
@@ -153,26 +154,25 @@ public class AdapterWebConsolePlugin extends HttpServlet implements ServiceTrack
             final Enumeration<URL> files = bundle.getResources("SLING-INF/adapters.json");
             if (files != null) {
                 while (files.hasMoreElements()) {
-                    final InputStream stream = files.nextElement().openStream();
-                    final String contents = IOUtils.toString(stream);
-                    IOUtils.closeQuietly(stream);
-                    Map<String, Object> config = new HashMap<>();
-                    config.put("org.apache.johnzon.supports-comments", true);
-                    final JsonObject obj = Json.createReaderFactory(config).createReader(new StringReader(contents)).readObject();
-                    for (final Iterator<String> adaptableNames = obj.keySet().iterator(); adaptableNames.hasNext();) {
-                        final String adaptableName = adaptableNames.next();
-                        final JsonObject adaptable = obj.getJsonObject(adaptableName);
-                        for (final Iterator<String> conditions = adaptable.keySet().iterator(); conditions.hasNext();) {
-                            final String condition = conditions.next();
-                            String[] adapters;
-                            final Object value = adaptable.get(condition);
-                            if (value instanceof JsonArray) {
-                                adapters = toStringArray((JsonArray) value);
-                            } else {
-                                adapters = new String[] { unbox(value).toString() };
+                    try (final Reader reader = new InputStreamReader(files.nextElement().openStream(), StandardCharsets.UTF_8)) {
+                        final Map<String, Object> config = new HashMap<>();
+                        config.put("org.apache.johnzon.supports-comments", true);
+                        final JsonObject obj = Json.createReaderFactory(config).createReader(reader).readObject();
+                        for (final Iterator<String> adaptableNames = obj.keySet().iterator(); adaptableNames.hasNext();) {
+                            final String adaptableName = adaptableNames.next();
+                            final JsonObject adaptable = obj.getJsonObject(adaptableName);
+                            for (final Iterator<String> conditions = adaptable.keySet().iterator(); conditions.hasNext();) {
+                                final String condition = conditions.next();
+                                String[] adapters;
+                                final Object value = adaptable.get(condition);
+                                if (value instanceof JsonArray) {
+                                    adapters = toStringArray((JsonArray) value);
+                                } else {
+                                    adapters = new String[] { unbox(value).toString() };
+                                }
+                                descs.add(new AdaptableDescription(bundle, adaptableName, adapters, condition, false));
                             }
-                            descs.add(new AdaptableDescription(bundle, adaptableName, adapters, condition, false));
-                        }
+                        }    
                     }
                 }
             }
@@ -239,8 +239,9 @@ public class AdapterWebConsolePlugin extends HttpServlet implements ServiceTrack
         allAdaptables = newList;
     }
 
-    protected void activate(final ComponentContext ctx) throws InvalidSyntaxException {
-        this.bundleContext = ctx.getBundleContext();
+    @Activate
+    protected void activate(final BundleContext ctx) throws InvalidSyntaxException {
+        this.bundleContext = ctx;
         this.adapterServiceReferences = new HashMap<>();
         this.adapterBundles = new HashMap<>();
         for (final Bundle bundle : this.bundleContext.getBundles()) {
@@ -255,7 +256,8 @@ public class AdapterWebConsolePlugin extends HttpServlet implements ServiceTrack
         this.adapterTracker.open();
     }
 
-    protected void deactivate(final ComponentContext ctx) {
+    @Deactivate
+    protected void deactivate() {
         this.bundleContext.removeBundleListener(this);
         this.adapterTracker.close();
         this.adapterServiceReferences = null;
@@ -437,9 +439,17 @@ public class AdapterWebConsolePlugin extends HttpServlet implements ServiceTrack
 
         @Override
         public int compareTo(final AdaptableDescription o) {
-            return new CompareToBuilder().append(this.adaptable, o.adaptable).append(this.condition, o.condition)
-                            .append(this.adapters.length, o.adapters.length)
-                            .append(this.bundle.getBundleId(), o.bundle.getBundleId()).toComparison();
+            int result = this.adaptable.compareTo(o.adaptable);
+            if ( result == 0 ) {
+                result = this.condition.compareTo(o.condition);
+                if ( result == 0 ) {
+                    result = this.adapters.length - o.adapters.length;
+                    if ( result == 0 ) {
+                        result = (int)this.bundle.getBundleId() - (int)o.bundle.getBundleId();
+                    }
+                }
+            }
+            return result;
         }
 
     }
diff --git a/src/test/java/org/apache/sling/adapter/internal/AdapterManagerTest.java b/src/test/java/org/apache/sling/adapter/internal/AdapterManagerTest.java
index 1208c85..8b35ddf 100644
--- a/src/test/java/org/apache/sling/adapter/internal/AdapterManagerTest.java
+++ b/src/test/java/org/apache/sling/adapter/internal/AdapterManagerTest.java
@@ -23,235 +23,82 @@ import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
-import java.util.Dictionary;
 import java.util.Map;
 
 import org.apache.sling.adapter.Adaption;
 import org.apache.sling.adapter.mock.MockAdapterFactory;
 import org.apache.sling.api.adapter.AdapterFactory;
 import org.apache.sling.api.adapter.SlingAdaptable;
-import org.hamcrest.Matcher;
-import org.hamcrest.core.IsAnything;
-import org.jmock.Expectations;
-import org.jmock.Mockery;
-import org.jmock.integration.junit4.JMock;
-import org.jmock.integration.junit4.JUnit4Mockery;
-import org.junit.runner.RunWith;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
-import org.osgi.framework.Filter;
-import org.osgi.framework.ServiceListener;
 import org.osgi.framework.ServiceReference;
-import org.osgi.service.component.ComponentContext;
 import org.osgi.service.packageadmin.ExportedPackage;
 import org.osgi.service.packageadmin.PackageAdmin;
 
-import junitx.util.PrivateAccessor;
 
-@RunWith(JMock.class)
 public class AdapterManagerTest {
 
     private AdapterManagerImpl am;
 
-    protected final Mockery context = new JUnit4Mockery();
-
-    @org.junit.Before public void setUp() throws Exception {
-        am = new AdapterManagerImpl();
-        final PackageAdmin pa = this.context.mock(PackageAdmin.class);
-        final ExportedPackage ep = this.context.mock(ExportedPackage.class);
-        this.context.checking(new Expectations(){{
-            allowing(pa).getExportedPackage(with(any(String.class)));
-            will(returnValue(ep));
-        }});
-        PrivateAccessor.setField(am, "packageAdmin", pa);
-    }
+    @Before public void setUp() throws Exception {
+        final PackageAdmin pa = Mockito.mock(PackageAdmin.class);
+        final ExportedPackage ep = Mockito.mock(ExportedPackage.class);
+        Mockito.when(pa.getExportedPackage(Mockito.anyString())).thenReturn(ep);
 
-    @org.junit.After public void tearDown() {
-        am.deactivate(null); // not correct, but argument unused
+        this.am = new AdapterManagerImpl(pa);
     }
 
     /**
-     * Helper method to create a mock bundle
+     * Helper method to create a mock service reference
      */
-    protected Bundle createBundle(String name) {
-        final Bundle bundle = this.context.mock(Bundle.class, name);
-        this.context.checking(new Expectations() {{
-            allowing(bundle).getBundleId();
-            will(returnValue(1L));
-        }});
-        return bundle;
+    protected ServiceReference<AdapterFactory> createServiceReference() {
+        return createServiceReference(1, new String[]{ TestSlingAdaptable.class.getName() }, new String[]{ITestAdapter.class.getName()});
     }
 
     /**
-     * Helper method to create a mock component context
+     * Helper method to create a mock service reference
      */
-    protected ComponentContext createComponentContext() throws Exception {
-        final BundleContext bundleCtx = this.context.mock(BundleContext.class);
-        final Filter filter = this.context.mock(Filter.class);
-        final ComponentContext ctx = this.context.mock(ComponentContext.class);
-        this.context.checking(new Expectations() {{
-            allowing(ctx).locateService(with(any(String.class)), with(any(ServiceReference.class)));
-            will(returnValue(new MockAdapterFactory()));
-            allowing(ctx).getBundleContext();
-            will(returnValue(bundleCtx));
-            allowing(bundleCtx).createFilter(with(any(String.class)));
-            will(returnValue(filter));
-            allowing(bundleCtx).addServiceListener(with(any(ServiceListener.class)), with(any(String.class)));
-            allowing(bundleCtx).getServiceReferences(with(any(String.class)), with(any(String.class)));
-            will(returnValue(null));
-            allowing(bundleCtx).removeServiceListener(with(any(ServiceListener.class)));
-            allowing(bundleCtx).registerService(with(Adaption.class), with(AdaptionImpl.INSTANCE), with(any(Dictionary.class)));
-            will(returnValue(null));
-        }});
-        return ctx;
-    }
+    protected ServiceReference<AdapterFactory> createServiceReference(final int ranking, final String[] adaptables, final String[] adapters) {
+        final ServiceReference<AdapterFactory> ref = Mockito.mock(ServiceReference.class);
+        Mockito.when(ref.getProperty(Constants.SERVICE_RANKING)).thenReturn(ranking);
+        Mockito.when(ref.getProperty(AdapterFactory.ADAPTABLE_CLASSES)).thenReturn(adaptables);
+        Mockito.when(ref.getProperty(AdapterFactory.ADAPTER_CLASSES)).thenReturn(adapters);
 
-        /**
-     * Helper method to create a mock component context
-     */
-    protected ComponentContext createMultipleAdaptersComponentContext(final ServiceReference firstServiceReference, final ServiceReference secondServiceReference) throws Exception {
-        final BundleContext bundleCtx = this.context.mock(BundleContext.class);
-        final Filter filter = this.context.mock(Filter.class);
-        final ComponentContext ctx = this.context.mock(ComponentContext.class);
-        this.context.checking(new Expectations() {{
-            allowing(ctx).locateService(with(any(String.class)), with(firstServiceReference));
-            will(returnValue(new FirstImplementationAdapterFactory()));
-            allowing(ctx).locateService(with(any(String.class)), with(secondServiceReference));
-            will(returnValue(new SecondImplementationAdapterFactory()));
-            allowing(ctx).getBundleContext();
-            will(returnValue(bundleCtx));
-            allowing(bundleCtx).createFilter(with(any(String.class)));
-            will(returnValue(filter));
-            allowing(bundleCtx).addServiceListener(with(any(ServiceListener.class)), with(any(String.class)));
-            allowing(bundleCtx).getServiceReferences(with(any(String.class)), with(any(String.class)));
-            will(returnValue(null));
-            allowing(bundleCtx).removeServiceListener(with(any(ServiceListener.class)));
-            allowing(bundleCtx).registerService(with(Adaption.class), with(AdaptionImpl.INSTANCE), with(any(Dictionary.class)));
-            will(returnValue(null));
-        }});
-        return ctx;
-    }
+        final Bundle bundle = Mockito.mock(Bundle.class);
+        final BundleContext ctx = Mockito.mock(BundleContext.class);
 
-    public static <T> Matcher<T> any(Class<T> type) {
-        return new IsAnything<>();
-    }
+        Mockito.when(ref.getBundle()).thenReturn(bundle);
+        Mockito.when(bundle.getBundleContext()).thenReturn(ctx);
 
-    /**
-     * Helper method to create a mock service reference
-     */
-    protected ServiceReference createServiceReference() {
-        final ServiceReference ref = new ServiceReferenceImpl(1, new String[]{ TestSlingAdaptable.class.getName() }, new String[]{ITestAdapter.class.getName()});
         return ref;
     }
-
-    private static final class ServiceReferenceImpl implements ServiceReference {
-
-        private int ranking;
-        private String[] adapters;
-        private String[] classes;
-
-        public ServiceReferenceImpl(final int order, final String[] adapters, final String[] classes) {
-            this.ranking = order;
-            this.adapters = adapters;
-            this.classes = classes;
-        }
-
-        @Override
-        public boolean isAssignableTo(Bundle bundle, String className) {
-            // TODO Auto-generated method stub
-            return false;
-        }
-
-        @Override
-        public Bundle[] getUsingBundles() {
-            // TODO Auto-generated method stub
-            return null;
-        }
-
-        @Override
-        public String[] getPropertyKeys() {
-            // TODO Auto-generated method stub
-            return null;
-        }
-
-        @Override
-        public Object getProperty(String key) {
-            if ( key.equals(Constants.SERVICE_RANKING) ) {
-                return ranking;
-            }
-            if ( key.equals(AdapterFactory.ADAPTABLE_CLASSES) ) {
-                return adapters;
-            }
-            if ( key.equals(AdapterFactory.ADAPTER_CLASSES) ) {
-                return classes;
-            }
-
-            return null;
-        }
-
-        @Override
-        public Bundle getBundle() {
-            // TODO Auto-generated method stub
-            return null;
-        }
-
-        @Override
-        public int compareTo(Object reference) {
-            Integer ranking1 = (Integer)getProperty(Constants.SERVICE_RANKING);
-            Integer ranking2 = (Integer)((ServiceReference)reference).getProperty(Constants.SERVICE_RANKING);
-            return ranking1.compareTo(ranking2);
-        }
-    };
+    
     /**
      * Helper method to create a mock service reference
      */
-    protected ServiceReference createServiceReference2() {
-        final ServiceReference ref = new ServiceReferenceImpl(2, new String[]{ TestSlingAdaptable2.class.getName() }, new String[]{TestAdapter.class.getName()});
-        return ref;
+    protected ServiceReference<AdapterFactory> createServiceReference2() {
+        return createServiceReference(2, new String[]{ TestSlingAdaptable2.class.getName() }, new String[]{TestAdapter.class.getName()});
     }
 
-    @org.junit.Test public void testUnitialized() {
+    @Test
+    public void testInitialized() throws Exception {
         assertNotNull("AdapterFactoryDescriptors must not be null", am.getFactories());
         assertTrue("AdapterFactoryDescriptors must be empty", am.getFactories().isEmpty());
         assertTrue("AdapterFactory cache must be empty", am.getFactoryCache().isEmpty());
     }
 
-    @org.junit.Test public void testInitialized() throws Exception {
-        am.activate(this.createComponentContext());
-
-        assertNotNull("AdapterFactoryDescriptors must not be null", am.getFactories());
-        assertTrue("AdapterFactoryDescriptors must be empty", am.getFactories().isEmpty());
-        assertTrue("AdapterFactory cache must be empty", am.getFactoryCache().isEmpty());
-    }
-
-    @org.junit.Test public void testBindBeforeActivate() throws Exception {
-        final ServiceReference ref = createServiceReference();
-        am.bindAdapterFactory(ref);
-
-        // no cache and no factories yet
-        assertNotNull("AdapterFactoryDescriptors must not be null", am.getFactories());
-        assertTrue("AdapterFactoryDescriptors must be empty", am.getFactories().isEmpty());
-        assertTrue("AdapterFactory cache must be empty", am.getFactoryCache().isEmpty());
-
-        am.activate(this.createComponentContext());
-
-        // expect the factory, but cache is empty
-        assertNotNull("AdapterFactoryDescriptors must not be null", am.getFactories());
-        assertEquals("AdapterFactoryDescriptors must contain one entry", 1, am.getFactories().size());
-        assertTrue("AdapterFactory cache must be empty", am.getFactoryCache().isEmpty());
-    }
-
-    @org.junit.Test public void testBindAfterActivate() throws Exception {
-        am.activate(this.createComponentContext());
-
-        // no cache and no factories yet
-        assertNotNull("AdapterFactoryDescriptors must not be null", am.getFactories());
-        assertTrue("AdapterFactoryDescriptors must be empty", am.getFactories().isEmpty());
-        assertTrue("AdapterFactory cache must be empty", am.getFactoryCache().isEmpty());
+    @Test
+    public void testBindAfterActivate() throws Exception {
+        final ServiceReference<AdapterFactory> ref = createServiceReference();
+        am.bindAdapterFactory(Mockito.mock(AdapterFactory.class), ref);
 
-        final ServiceReference ref = createServiceReference();
-        am.bindAdapterFactory(ref);
+        // check that a service is registered
+        Mockito.verify(ref.getBundle().getBundleContext()).registerService(Mockito.eq(Adaption.class), 
+                   Mockito.eq(AdaptionImpl.INSTANCE), Mockito.any());
 
         // expect the factory, but cache is empty
         assertNotNull("AdapterFactoryDescriptors must not be null", am.getFactories());
@@ -272,59 +119,55 @@ public class AdapterManagerTest {
         assertNull(f.get(TestSlingAdaptable2.class.getName()));
     }
 
-    @org.junit.Test public void testAdaptBase() throws Exception {
-        am.activate(this.createComponentContext());
-
+    @Test
+    public void testAdaptBase() throws Exception {
         TestSlingAdaptable data = new TestSlingAdaptable();
         assertNull("Expect no adapter", am.getAdapter(data, ITestAdapter.class));
 
-        final ServiceReference ref = createServiceReference();
-        am.bindAdapterFactory(ref);
+        final ServiceReference<AdapterFactory> ref = createServiceReference();
+        am.bindAdapterFactory(new MockAdapterFactory(), ref);
 
         Object adapter = am.getAdapter(data, ITestAdapter.class);
         assertNotNull(adapter);
         assertTrue(adapter instanceof ITestAdapter);
     }
 
-    @org.junit.Test public void testAdaptExtended() throws Exception {
-        am.activate(this.createComponentContext());
-
+    @Test
+    public void testAdaptExtended() throws Exception {
         TestSlingAdaptable2 data = new TestSlingAdaptable2();
         assertNull("Expect no adapter", am.getAdapter(data, ITestAdapter.class));
 
-        final ServiceReference ref = createServiceReference();
-        am.bindAdapterFactory(ref);
+        final ServiceReference<AdapterFactory> ref = createServiceReference();
+        am.bindAdapterFactory(new MockAdapterFactory(), ref);
 
         Object adapter = am.getAdapter(data, ITestAdapter.class);
         assertNotNull(adapter);
         assertTrue(adapter instanceof ITestAdapter);
     }
 
-    @org.junit.Test public void testAdaptBase2() throws Exception {
-        am.activate(this.createComponentContext());
-
+    @Test
+    public void testAdaptBase2() throws Exception {
         TestSlingAdaptable data = new TestSlingAdaptable();
         assertNull("Expect no adapter", am.getAdapter(data, ITestAdapter.class));
 
-        final ServiceReference ref = createServiceReference();
-        am.bindAdapterFactory(ref);
+        final ServiceReference<AdapterFactory> ref = createServiceReference();
+        am.bindAdapterFactory(new MockAdapterFactory(), ref);
 
-        final ServiceReference ref2 = createServiceReference2();
-        am.bindAdapterFactory(ref2);
+        final ServiceReference<AdapterFactory> ref2 = createServiceReference2();
+        am.bindAdapterFactory(new MockAdapterFactory(), ref2);
 
         Object adapter = am.getAdapter(data, ITestAdapter.class);
         assertNotNull(adapter);
         assertTrue(adapter instanceof ITestAdapter);
     }
 
-    @org.junit.Test public void testAdaptExtended2() throws Exception {
-        am.activate(this.createComponentContext());
-
-        final ServiceReference ref = createServiceReference();
-        am.bindAdapterFactory(ref);
+    @Test
+    public void testAdaptExtended2() throws Exception {
+        final ServiceReference<AdapterFactory> ref = createServiceReference();
+        am.bindAdapterFactory(new MockAdapterFactory(), ref);
 
-        final ServiceReference ref2 = createServiceReference2();
-        am.bindAdapterFactory(ref2);
+        final ServiceReference<AdapterFactory> ref2 = createServiceReference2();
+        am.bindAdapterFactory(new MockAdapterFactory(), ref2);
 
         TestSlingAdaptable data = new TestSlingAdaptable();
         Object adapter = am.getAdapter(data, ITestAdapter.class);
@@ -342,11 +185,12 @@ public class AdapterManagerTest {
         assertTrue(adapter instanceof TestAdapter);
     }
 
-    @org.junit.Test public void testAdaptMultipleAdapterFactories() throws Exception {
-        final ServiceReference firstAdaptable = new ServiceReferenceImpl(1, new String[]{AdapterObject.class.getName()},  new String[]{ ParentInterface.class.getName(), FirstImplementation.class.getName()});
-        final ServiceReference secondAdaptable = new ServiceReferenceImpl(2, new String[]{ AdapterObject.class.getName() }, new String[]{ParentInterface.class.getName(), SecondImplementation.class.getName()});
-
-        am.activate(this.createMultipleAdaptersComponentContext(firstAdaptable, secondAdaptable));
+    @Test
+    public void testAdaptMultipleAdapterFactories() throws Exception {
+        final ServiceReference<AdapterFactory> firstAdaptable = this.createServiceReference(1, new String[]{AdapterObject.class.getName()},  new String[]{ ParentInterface.class.getName(), FirstImplementation.class.getName()});
+        final ServiceReference<AdapterFactory> secondAdaptable = this.createServiceReference(2, new String[]{ AdapterObject.class.getName() }, new String[]{ParentInterface.class.getName(), SecondImplementation.class.getName()});
+        Mockito.when(firstAdaptable.compareTo(secondAdaptable)).thenReturn(-1);
+        Mockito.when(secondAdaptable.compareTo(firstAdaptable)).thenReturn(1);
 
         AdapterObject first = new AdapterObject(Want.FIRST_IMPL);
         assertNull("Expect no adapter", am.getAdapter(first, ParentInterface.class));
@@ -354,8 +198,8 @@ public class AdapterManagerTest {
         AdapterObject second = new AdapterObject(Want.SECOND_IMPL);
         assertNull("Expect no adapter", am.getAdapter(second, ParentInterface.class));
 
-        am.bindAdapterFactory(firstAdaptable);
-        am.bindAdapterFactory(secondAdaptable);
+        am.bindAdapterFactory(new FirstImplementationAdapterFactory(), firstAdaptable);
+        am.bindAdapterFactory(new SecondImplementationAdapterFactory(), secondAdaptable);
 
         Object adapter = am.getAdapter(first, ParentInterface.class);
         assertNotNull("Did not get an adapter back for first implementation, service ranking 1", adapter);
@@ -374,10 +218,12 @@ public class AdapterManagerTest {
         assertTrue("Did not get the correct adaptable back for second implementation, service ranking 2, ", adapter instanceof SecondImplementation);
     }
 
-    @org.junit.Test public void testAdaptMultipleAdapterFactoriesReverseOrder() throws Exception {
-        final ServiceReference firstAdaptable = new ServiceReferenceImpl(2, new String[]{AdapterObject.class.getName()},  new String[]{ ParentInterface.class.getName()});
-        final ServiceReference secondAdaptable = new ServiceReferenceImpl(1, new String[]{AdapterObject.class.getName()},  new String[]{ ParentInterface.class.getName()});
-        am.activate(this.createMultipleAdaptersComponentContext(firstAdaptable, secondAdaptable));
+    @Test
+    public void testAdaptMultipleAdapterFactoriesReverseOrder() throws Exception {
+        final ServiceReference<AdapterFactory> firstAdaptable = this.createServiceReference(2, new String[]{AdapterObject.class.getName()},  new String[]{ ParentInterface.class.getName()});
+        final ServiceReference<AdapterFactory> secondAdaptable = this.createServiceReference(1, new String[]{AdapterObject.class.getName()},  new String[]{ ParentInterface.class.getName()});
+        Mockito.when(firstAdaptable.compareTo(secondAdaptable)).thenReturn(1);
+        Mockito.when(secondAdaptable.compareTo(firstAdaptable)).thenReturn(-1);
 
         AdapterObject first = new AdapterObject(Want.FIRST_IMPL);
         assertNull("Expect no adapter", am.getAdapter(first, ParentInterface.class));
@@ -385,8 +231,8 @@ public class AdapterManagerTest {
         AdapterObject second = new AdapterObject(Want.SECOND_IMPL);
         assertNull("Expect no adapter", am.getAdapter(second, ParentInterface.class));
 
-        am.bindAdapterFactory(firstAdaptable);
-        am.bindAdapterFactory(secondAdaptable);
+        am.bindAdapterFactory(new FirstImplementationAdapterFactory(), firstAdaptable);
+        am.bindAdapterFactory(new SecondImplementationAdapterFactory(), secondAdaptable);
 
         Object adapter = am.getAdapter(first, ParentInterface.class);
         assertNotNull("Did not get an adapter back for first implementation, service ranking 2", adapter);
@@ -394,11 +240,12 @@ public class AdapterManagerTest {
 
     }
 
-    @org.junit.Test public void testAdaptMultipleAdapterFactoriesServiceRanking() throws Exception {
-        final ServiceReference firstAdaptable = new ServiceReferenceImpl(1, new String[]{AdapterObject.class.getName()},  new String[]{ ParentInterface.class.getName(), FirstImplementation.class.getName()});
-        final ServiceReference secondAdaptable = new ServiceReferenceImpl(2, new String[]{ AdapterObject.class.getName() }, new String[]{ParentInterface.class.getName(), SecondImplementation.class.getName()});
-
-        am.activate(this.createMultipleAdaptersComponentContext(firstAdaptable, secondAdaptable));
+    @Test
+    public void testAdaptMultipleAdapterFactoriesServiceRanking() throws Exception {
+        final ServiceReference<AdapterFactory> firstAdaptable = createServiceReference(1, new String[]{AdapterObject.class.getName()},  new String[]{ ParentInterface.class.getName(), FirstImplementation.class.getName()});
+        final ServiceReference<AdapterFactory> secondAdaptable = createServiceReference(2, new String[]{ AdapterObject.class.getName() }, new String[]{ParentInterface.class.getName(), SecondImplementation.class.getName()});
+        Mockito.when(firstAdaptable.compareTo(secondAdaptable)).thenReturn(-1);
+        Mockito.when(secondAdaptable.compareTo(firstAdaptable)).thenReturn(1);
 
         AdapterObject first = new AdapterObject(Want.INDIFFERENT);
         assertNull("Expect no adapter", am.getAdapter(first, ParentInterface.class));
@@ -406,8 +253,8 @@ public class AdapterManagerTest {
         AdapterObject second = new AdapterObject(Want.INDIFFERENT);
         assertNull("Expect no adapter", am.getAdapter(second, ParentInterface.class));
 
-        am.bindAdapterFactory(firstAdaptable);
-        am.bindAdapterFactory(secondAdaptable);
+        am.bindAdapterFactory(new FirstImplementationAdapterFactory(), firstAdaptable);
+        am.bindAdapterFactory(new SecondImplementationAdapterFactory(), secondAdaptable);
 
         Object adapter = am.getAdapter(first, ParentInterface.class);
         assertNotNull("Did not get an adapter back for first implementation (from ParentInterface), service ranking 1", adapter);
@@ -422,11 +269,12 @@ public class AdapterManagerTest {
         assertTrue("Did not get the correct adaptable back for second implementation, service ranking 2, ", adapter instanceof SecondImplementation);
     }
 
-    @org.junit.Test public void testAdaptMultipleAdapterFactoriesServiceRankingSecondHigherOrder() throws Exception {
-        final ServiceReference firstAdaptable = new ServiceReferenceImpl(2, new String[]{AdapterObject.class.getName()},  new String[]{ ParentInterface.class.getName(), FirstImplementation.class.getName()});
-        final ServiceReference secondAdaptable = new ServiceReferenceImpl(1, new String[]{ AdapterObject.class.getName() }, new String[]{ParentInterface.class.getName(), SecondImplementation.class.getName()});
-
-        am.activate(this.createMultipleAdaptersComponentContext(firstAdaptable, secondAdaptable));
+    @Test
+    public void testAdaptMultipleAdapterFactoriesServiceRankingSecondHigherOrder() throws Exception {
+        final ServiceReference<AdapterFactory> firstAdaptable = createServiceReference(2, new String[]{AdapterObject.class.getName()},  new String[]{ ParentInterface.class.getName(), FirstImplementation.class.getName()});
+        final ServiceReference<AdapterFactory> secondAdaptable = createServiceReference(1, new String[]{ AdapterObject.class.getName() }, new String[]{ParentInterface.class.getName(), SecondImplementation.class.getName()});
+        Mockito.when(firstAdaptable.compareTo(secondAdaptable)).thenReturn(1);
+        Mockito.when(secondAdaptable.compareTo(firstAdaptable)).thenReturn(-1);
 
         AdapterObject first = new AdapterObject(Want.INDIFFERENT);
         assertNull("Expect no adapter", am.getAdapter(first, ParentInterface.class));
@@ -434,8 +282,8 @@ public class AdapterManagerTest {
         AdapterObject second = new AdapterObject(Want.INDIFFERENT);
         assertNull("Expect no adapter", am.getAdapter(second, ParentInterface.class));
 
-        am.bindAdapterFactory(firstAdaptable);
-        am.bindAdapterFactory(secondAdaptable);
+        am.bindAdapterFactory(new FirstImplementationAdapterFactory(), firstAdaptable);
+        am.bindAdapterFactory(new SecondImplementationAdapterFactory(), secondAdaptable);
 
         Object adapter = am.getAdapter(first, ParentInterface.class);
         assertNotNull("Did not get an adapter back for second implementation (from ParentInterface), service ranking 1", adapter);
@@ -450,11 +298,11 @@ public class AdapterManagerTest {
         assertTrue("Did not get the correct adaptable back for second implementation, service ranking 2, ", adapter instanceof SecondImplementation);
     }
 
-    @org.junit.Test public void testAdaptMultipleAdapterFactoriesServiceRankingReverse() throws Exception {
-        final ServiceReference firstAdaptable = new ServiceReferenceImpl(1, new String[]{AdapterObject.class.getName()},  new String[]{ ParentInterface.class.getName(), FirstImplementation.class.getName()});
-        final ServiceReference secondAdaptable = new ServiceReferenceImpl(2, new String[]{ AdapterObject.class.getName() }, new String[]{ParentInterface.class.getName(), SecondImplementation.class.getName()});
-
-        am.activate(this.createMultipleAdaptersComponentContext(firstAdaptable, secondAdaptable));
+    @Test public void testAdaptMultipleAdapterFactoriesServiceRankingReverse() throws Exception {
+        final ServiceReference<AdapterFactory> firstAdaptable = this.createServiceReference(1, new String[]{AdapterObject.class.getName()},  new String[]{ ParentInterface.class.getName(), FirstImplementation.class.getName()});
+        final ServiceReference<AdapterFactory> secondAdaptable = this.createServiceReference(2, new String[]{ AdapterObject.class.getName() }, new String[]{ParentInterface.class.getName(), SecondImplementation.class.getName()});
+        Mockito.when(firstAdaptable.compareTo(secondAdaptable)).thenReturn(-1);
+        Mockito.when(secondAdaptable.compareTo(firstAdaptable)).thenReturn(1);
 
         AdapterObject first = new AdapterObject(Want.INDIFFERENT);
         assertNull("Expect no adapter", am.getAdapter(first, ParentInterface.class));
@@ -463,8 +311,8 @@ public class AdapterManagerTest {
         assertNull("Expect no adapter", am.getAdapter(second, ParentInterface.class));
 
         // bind these in reverse order from the non-reverse test
-        am.bindAdapterFactory(secondAdaptable);
-        am.bindAdapterFactory(firstAdaptable);
+        am.bindAdapterFactory(new SecondImplementationAdapterFactory(), secondAdaptable);
+        am.bindAdapterFactory(new FirstImplementationAdapterFactory(), firstAdaptable);
 
         Object adapter = am.getAdapter(first, ParentInterface.class);
         assertNotNull("Did not get an adapter back for first implementation (from ParentInterface), service ranking 1", adapter);