You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by re...@apache.org on 2025/04/01 15:33:12 UTC

(sling-org-apache-sling-resourceresolver) branch master updated: SLING-12701: Resource Resolver: MapEntries - move alias handling into inner class (#163)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new a3f37529 SLING-12701: Resource Resolver: MapEntries - move alias handling into inner class (#163)
a3f37529 is described below

commit a3f37529bf36ef8c521f7fe8027667abdfd5e8cd
Author: Julian Reschke <ju...@gmx.de>
AuthorDate: Tue Apr 1 17:33:08 2025 +0200

    SLING-12701: Resource Resolver: MapEntries - move alias handling into inner class (#163)
---
 .../resourceresolver/impl/mapping/MapEntries.java  | 806 +++++++++++----------
 .../mapping/AbstractMappingMapEntriesTest.java     |   4 +-
 .../impl/mapping/AliasMapEntriesTest.java          |  30 +-
 .../impl/mapping/EtcMappingMapEntriesTest.java     |  12 +-
 .../impl/mapping/MapEntriesTest.java               |   6 +-
 .../mapping/StringInterpolationMapEntriesTest.java |   4 +-
 .../impl/mapping/VanityPathMapEntriesTest.java     |   2 +-
 7 files changed, 462 insertions(+), 402 deletions(-)

diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java b/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java
index 37029a62..9397f487 100644
--- a/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java
+++ b/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java
@@ -72,8 +72,6 @@ public class MapEntries implements MapEntriesHandler, ResourceChangeListener, Ex
 
     private static final String JCR_CONTENT = "jcr:content";
 
-    private static final String JCR_CONTENT_PREFIX = JCR_CONTENT + "/";
-
     private static final String JCR_CONTENT_SUFFIX = "/" + JCR_CONTENT;
 
     private static final String PROP_REG_EXP = "sling:match";
@@ -115,25 +113,14 @@ public class MapEntries implements MapEntriesHandler, ResourceChangeListener, Ex
 
     private Collection<MapEntry> mapMaps;
 
-    /**
-     * The key of the map is the parent path, while the value is a map with the the resource name as key and the actual aliases as values)
-     */
-    private Map<String, Map<String, Collection<String>>> aliasMapsMap;
-
-    private final AtomicLong aliasResourcesOnStartup;
-    private final AtomicLong detectedConflictingAliases;
-    private final AtomicLong detectedInvalidAliases;
-
-    // keep track of some defunct aliases for diagnostics (thus size-limited)
-    private static final int MAX_REPORT_DEFUNCT_ALIASES = 50;
-
     private final ReentrantLock initializing = new ReentrantLock();
 
     private final StringInterpolationProvider stringInterpolationProvider;
 
     private final boolean useOptimizeAliasResolution;
 
-    final VanityPathHandler vph;
+    AliasHandler ah;
+    VanityPathHandler vph;
 
     public MapEntries(
             final MapConfigurationProvider factory,
@@ -149,14 +136,11 @@ public class MapEntries implements MapEntriesHandler, ResourceChangeListener, Ex
 
         this.resolveMapsMap = new ConcurrentHashMap<>(Map.of(GLOBAL_LIST_KEY, List.of()));
         this.mapMaps = Collections.<MapEntry>emptyList();
-        this.aliasMapsMap = new ConcurrentHashMap<>();
         this.stringInterpolationProvider = stringInterpolationProvider;
 
-        this.aliasResourcesOnStartup = new AtomicLong(0);
-        this.detectedConflictingAliases = new AtomicLong(0);
-        this.detectedInvalidAliases = new AtomicLong(0);
+        this.ah = new AliasHandler(this.factory, this.initializing, this::doUpdateConfiguration, this::sendChangeEvent);
 
-        this.useOptimizeAliasResolution = initializeAliases();
+        this.useOptimizeAliasResolution = ah.initializeAliases();
 
         this.registration = registerResourceChangeListener(bundleContext);
 
@@ -166,10 +150,10 @@ public class MapEntries implements MapEntriesHandler, ResourceChangeListener, Ex
         this.metrics = metrics;
         if (metrics.isPresent()) {
             // aliases
-            this.metrics.get().setNumberOfDetectedConflictingAliasesSupplier(detectedConflictingAliases::get);
-            this.metrics.get().setNumberOfDetectedInvalidAliasesSupplier(detectedInvalidAliases::get);
-            this.metrics.get().setNumberOfResourcesWithAliasedChildrenSupplier(() -> (long) aliasMapsMap.size());
-            this.metrics.get().setNumberOfResourcesWithAliasesOnStartupSupplier(aliasResourcesOnStartup::get);
+            this.metrics.get().setNumberOfDetectedConflictingAliasesSupplier(ah.detectedConflictingAliases::get);
+            this.metrics.get().setNumberOfDetectedInvalidAliasesSupplier(ah.detectedInvalidAliases::get);
+            this.metrics.get().setNumberOfResourcesWithAliasedChildrenSupplier(() -> (long) ah.aliasMapsMap.size());
+            this.metrics.get().setNumberOfResourcesWithAliasesOnStartupSupplier(ah.aliasResourcesOnStartup::get);
 
             // vanity paths
             this.metrics.get().setNumberOfResourcesWithVanityPathsOnStartupSupplier(vph.vanityResourcesOnStartup::get);
@@ -206,7 +190,7 @@ public class MapEntries implements MapEntriesHandler, ResourceChangeListener, Ex
                 boolean changed = vph.doAddVanity(resource);
                 if (this.useOptimizeAliasResolution
                         && resource.getValueMap().containsKey(ResourceResolverImpl.PROP_ALIAS)) {
-                    changed |= doAddAlias(resource);
+                    changed |= ah.doAddAlias(resource);
                 }
                 return changed;
             }
@@ -240,7 +224,7 @@ public class MapEntries implements MapEntriesHandler, ResourceChangeListener, Ex
                         changed |= vph.doAddVanity(contentRsrc != null ? contentRsrc : resource);
                     }
                     if (this.useOptimizeAliasResolution) {
-                        changed |= doUpdateAlias(resource);
+                        changed |= ah.doUpdateAlias(resource);
                     }
 
                     return changed;
@@ -265,11 +249,12 @@ public class MapEntries implements MapEntriesHandler, ResourceChangeListener, Ex
         }
         if (this.useOptimizeAliasResolution) {
             final String pathPrefix = path + "/";
-            for (final String contentPath : this.aliasMapsMap.keySet()) {
+            for (final String contentPath : ah.aliasMapsMap.keySet()) {
                 if (path.startsWith(contentPath + "/")
                         || path.equals(contentPath)
                         || contentPath.startsWith(pathPrefix)) {
-                    changed |= removeAlias(contentPath, path, resolverRefreshed);
+                    changed |= ah.removeAlias(
+                            resolver, contentPath, path, () -> this.refreshResolverIfNecessary(resolverRefreshed));
                 }
             }
         }
@@ -299,6 +284,11 @@ public class MapEntries implements MapEntriesHandler, ResourceChangeListener, Ex
      */
     public void dispose() {
 
+        if (this.ah != null) {
+            ah.dispose();
+            ah = null;
+        }
+
         if (this.registration != null) {
             this.registration.unregister();
             this.registration = null;
@@ -384,6 +374,17 @@ public class MapEntries implements MapEntriesHandler, ResourceChangeListener, Ex
         return this.useOptimizeAliasResolution;
     }
 
+    @Override
+    public Map<String, List<String>> getVanityPathMappings() {
+        return vph.getVanityPathMappings();
+    }
+
+    @Override
+    public @NotNull Map<String, Collection<String>> getAliasMap(final String parentPath) {
+        Map<String, Collection<String>> aliasMapForParent = ah.aliasMapsMap.get(parentPath);
+        return aliasMapForParent != null ? aliasMapForParent : Collections.emptyMap();
+    }
+
     /**
      * Refresh the resource resolver if not already done
      * @param resolverRefreshed Boolean flag containing the state if the resolver
@@ -717,6 +718,11 @@ public class MapEntries implements MapEntriesHandler, ResourceChangeListener, Ex
         }
     }
 
+    @Override
+    public void logDisableAliasOptimization() {
+        this.ah.logDisableAliasOptimization(null);
+    }
+
     private MapEntry getMapEntry(final String url, final int status, final String... redirect) {
         return getMapEntry(url, status, 0, redirect);
     }
@@ -760,438 +766,490 @@ public class MapEntries implements MapEntriesHandler, ResourceChangeListener, Ex
 
     // Alias handling code
 
-    /**
-     * Actual initializer. Guards itself against concurrent use by using a
-     * ReentrantLock. Does nothing if the resource resolver has already been
-     * null-ed.
-     * @return true if the optimizedAliasResolution is enabled, false otherwise
-     */
-    protected boolean initializeAliases() {
+    class AliasHandler {
 
-        this.initializing.lock();
-        try {
-            // already disposed?
-            if (this.resolver == null || this.factory == null) {
-                return false;
-            }
+        private static final String JCR_CONTENT = "jcr:content";
 
-            List<String> conflictingAliases = new ArrayList<>();
-            List<String> invalidAliases = new ArrayList<>();
+        private static final String JCR_CONTENT_PREFIX = JCR_CONTENT + "/";
 
-            boolean isOptimizeAliasResolutionEnabled = this.factory.isOptimizeAliasResolutionEnabled();
+        private static final String JCR_CONTENT_SUFFIX = "/" + JCR_CONTENT;
 
-            // optimization made in SLING-2521
-            if (isOptimizeAliasResolutionEnabled) {
-                try {
-                    final Map<String, Map<String, Collection<String>>> loadedMap =
-                            this.loadAliases(resolver, conflictingAliases, invalidAliases);
-                    this.aliasMapsMap = loadedMap;
+        private MapConfigurationProvider factory;
 
-                    // warn if there are more than a few defunct aliases
-                    if (conflictingAliases.size() >= MAX_REPORT_DEFUNCT_ALIASES) {
-                        log.warn(
-                                "There are {} conflicting aliases; excerpt: {}",
-                                conflictingAliases.size(),
-                                conflictingAliases);
-                    } else if (!conflictingAliases.isEmpty()) {
-                        log.warn("There are {} conflicting aliases: {}", conflictingAliases.size(), conflictingAliases);
-                    }
-                    if (invalidAliases.size() >= MAX_REPORT_DEFUNCT_ALIASES) {
-                        log.warn("There are {} invalid aliases; excerpt: {}", invalidAliases.size(), invalidAliases);
-                    } else if (!invalidAliases.isEmpty()) {
-                        log.warn("There are {} invalid aliases: {}", invalidAliases.size(), invalidAliases);
-                    }
-                } catch (final Exception e) {
+        private final ReentrantLock initializing;
+
+        private final Logger log = LoggerFactory.getLogger(AliasHandler.class);
 
-                    logDisableAliasOptimization(e);
+        // keep track of some defunct aliases for diagnostics (thus size-limited)
+        private static final int MAX_REPORT_DEFUNCT_ALIASES = 50;
 
-                    // disable optimize alias resolution
-                    isOptimizeAliasResolutionEnabled = false;
+        private Runnable doUpdateConfiguration;
+        private Runnable sendChangeEvent;
+
+        /**
+         * The key of the map is the parent path, while the value is a map with the the resource name as key and the actual aliases as values)
+         */
+        private Map<String, Map<String, Collection<String>>> aliasMapsMap;
+
+        final AtomicLong aliasResourcesOnStartup;
+        final AtomicLong detectedConflictingAliases;
+        final AtomicLong detectedInvalidAliases;
+
+        public AliasHandler(
+                MapConfigurationProvider factory,
+                ReentrantLock initializing,
+                Runnable doUpdateConfiguration,
+                Runnable sendChangeEvent) {
+            this.factory = factory;
+            this.initializing = initializing;
+            this.aliasMapsMap = new ConcurrentHashMap<>();
+            this.doUpdateConfiguration = doUpdateConfiguration;
+            this.sendChangeEvent = sendChangeEvent;
+
+            this.aliasResourcesOnStartup = new AtomicLong(0);
+            this.detectedConflictingAliases = new AtomicLong(0);
+            this.detectedInvalidAliases = new AtomicLong(0);
+        }
+
+        public void dispose() {
+            this.factory = null;
+        }
+
+        /**
+         * Actual initializer. Guards itself against concurrent use by using a
+         * ReentrantLock. Does nothing if the resource resolver has already been
+         * null-ed.
+         * @return true if the optimizedAliasResolution is enabled, false otherwise
+         */
+        protected boolean initializeAliases() {
+
+            this.initializing.lock();
+            try {
+                // already disposed?
+                if (this.factory == null) {
+                    return false;
                 }
-            }
 
-            doUpdateConfiguration();
+                List<String> conflictingAliases = new ArrayList<>();
+                List<String> invalidAliases = new ArrayList<>();
+
+                boolean isOptimizeAliasResolutionEnabled = this.factory.isOptimizeAliasResolutionEnabled();
+
+                // optimization made in SLING-2521
+                if (isOptimizeAliasResolutionEnabled) {
+                    try {
+                        final Map<String, Map<String, Collection<String>>> loadedMap =
+                                this.loadAliases(conflictingAliases, invalidAliases);
+                        this.aliasMapsMap = loadedMap;
+
+                        // warn if there are more than a few defunct aliases
+                        if (conflictingAliases.size() >= MAX_REPORT_DEFUNCT_ALIASES) {
+                            log.warn(
+                                    "There are {} conflicting aliases; excerpt: {}",
+                                    conflictingAliases.size(),
+                                    conflictingAliases);
+                        } else if (!conflictingAliases.isEmpty()) {
+                            log.warn(
+                                    "There are {} conflicting aliases: {}",
+                                    conflictingAliases.size(),
+                                    conflictingAliases);
+                        }
+                        if (invalidAliases.size() >= MAX_REPORT_DEFUNCT_ALIASES) {
+                            log.warn(
+                                    "There are {} invalid aliases; excerpt: {}", invalidAliases.size(), invalidAliases);
+                        } else if (!invalidAliases.isEmpty()) {
+                            log.warn("There are {} invalid aliases: {}", invalidAliases.size(), invalidAliases);
+                        }
+                    } catch (final Exception e) {
 
-            sendChangeEvent();
+                        logDisableAliasOptimization(e);
+
+                        // disable optimize alias resolution
+                        isOptimizeAliasResolutionEnabled = false;
+                    }
+                }
 
-            return isOptimizeAliasResolutionEnabled;
+                doUpdateConfiguration.run();
+                sendChangeEvent.run();
 
-        } finally {
+                return isOptimizeAliasResolutionEnabled;
 
-            this.initializing.unlock();
+            } finally {
+
+                this.initializing.unlock();
+            }
         }
-    }
 
-    private boolean doAddAlias(final Resource resource) {
-        return loadAlias(resource, this.aliasMapsMap, null, null);
-    }
+        private boolean doAddAlias(final Resource resource) {
+            return loadAlias(resource, this.aliasMapsMap, null, null);
+        }
 
-    /**
-     * Remove all aliases for the content path
-     * @param contentPath The content path
-     * @param path Optional sub path of the vanity path
-     * @return {@code true} if a change happened
-     */
-    private boolean removeAlias(final String contentPath, final String path, final AtomicBoolean resolverRefreshed) {
-        // if path is specified we first need to find out if it is
-        // a direct child of vanity path but not jcr:content, or a jcr:content child of a direct child
-        // otherwise we can discard the event
-        boolean handle = true;
-        final String resourcePath;
-        if (path != null && path.length() > contentPath.length()) {
-            final String subPath = path.substring(contentPath.length() + 1);
-            final int firstSlash = subPath.indexOf('/');
-            if (firstSlash == -1) {
-                if (subPath.equals(JCR_CONTENT)) {
-                    handle = false;
-                }
-                resourcePath = path;
-            } else if (subPath.lastIndexOf('/') == firstSlash) {
-                if (subPath.startsWith(JCR_CONTENT_PREFIX) || !subPath.endsWith(JCR_CONTENT_SUFFIX)) {
+        /**
+         * Remove all aliases for the content path
+         * @param contentPath The content path
+         * @param path Optional sub path of the vanity path
+         * @return {@code true} if a change happened
+         */
+        private boolean removeAlias(
+                ResourceResolver resolver, final String contentPath, final String path, final Runnable notifyOfChange) {
+            // if path is specified we first need to find out if it is
+            // a direct child of vanity path but not jcr:content, or a jcr:content child of a direct child
+            // otherwise we can discard the event
+            boolean handle = true;
+            final String resourcePath;
+            if (path != null && path.length() > contentPath.length()) {
+                final String subPath = path.substring(contentPath.length() + 1);
+                final int firstSlash = subPath.indexOf('/');
+                if (firstSlash == -1) {
+                    if (subPath.equals(JCR_CONTENT)) {
+                        handle = false;
+                    }
+                    resourcePath = path;
+                } else if (subPath.lastIndexOf('/') == firstSlash) {
+                    if (subPath.startsWith(JCR_CONTENT_PREFIX) || !subPath.endsWith(JCR_CONTENT_SUFFIX)) {
+                        handle = false;
+                    }
+                    resourcePath = ResourceUtil.getParent(path);
+                } else {
                     handle = false;
+                    resourcePath = null;
                 }
-                resourcePath = ResourceUtil.getParent(path);
             } else {
-                handle = false;
-                resourcePath = null;
+                resourcePath = contentPath;
+            }
+            if (!handle) {
+                return false;
             }
-        } else {
-            resourcePath = contentPath;
-        }
-        if (!handle) {
-            return false;
-        }
-
-        this.initializing.lock();
-        try {
-            final Map<String, Collection<String>> aliasMapEntry = aliasMapsMap.get(contentPath);
-            if (aliasMapEntry != null) {
-                this.refreshResolverIfNecessary(resolverRefreshed);
 
-                String prefix = contentPath.endsWith("/") ? contentPath : contentPath + "/";
-                if (aliasMapEntry.entrySet().removeIf(e -> (prefix + e.getKey()).startsWith(resourcePath))
-                        && (aliasMapEntry.isEmpty())) {
-                    this.aliasMapsMap.remove(contentPath);
-                }
+            this.initializing.lock();
+            try {
+                final Map<String, Collection<String>> aliasMapEntry = aliasMapsMap.get(contentPath);
+                if (aliasMapEntry != null) {
+                    notifyOfChange.run();
+
+                    String prefix = contentPath.endsWith("/") ? contentPath : contentPath + "/";
+                    if (aliasMapEntry.entrySet().removeIf(e -> (prefix + e.getKey()).startsWith(resourcePath))
+                            && (aliasMapEntry.isEmpty())) {
+                        this.aliasMapsMap.remove(contentPath);
+                    }
 
-                Resource containingResource = this.resolver != null ? this.resolver.getResource(resourcePath) : null;
+                    Resource containingResource = resolver != null ? resolver.getResource(resourcePath) : null;
 
-                if (containingResource != null) {
-                    if (containingResource.getValueMap().containsKey(ResourceResolverImpl.PROP_ALIAS)) {
-                        doAddAlias(containingResource);
-                    }
-                    final Resource child = containingResource.getChild(JCR_CONTENT);
-                    if (child != null && child.getValueMap().containsKey(ResourceResolverImpl.PROP_ALIAS)) {
-                        doAddAlias(child);
+                    if (containingResource != null) {
+                        if (containingResource.getValueMap().containsKey(ResourceResolverImpl.PROP_ALIAS)) {
+                            doAddAlias(containingResource);
+                        }
+                        final Resource child = containingResource.getChild(JCR_CONTENT);
+                        if (child != null && child.getValueMap().containsKey(ResourceResolverImpl.PROP_ALIAS)) {
+                            doAddAlias(child);
+                        }
                     }
                 }
+                return aliasMapEntry != null;
+            } finally {
+                this.initializing.unlock();
             }
-            return aliasMapEntry != null;
-        } finally {
-            this.initializing.unlock();
         }
-    }
 
-    /**
-     * Update alias from a resource
-     * @param resource The resource
-     * @return {@code true} if any change
-     */
-    private boolean doUpdateAlias(final Resource resource) {
+        /**
+         * Update alias from a resource
+         * @param resource The resource
+         * @return {@code true} if any change
+         */
+        private boolean doUpdateAlias(final Resource resource) {
 
-        // resource containing the alias
-        final Resource containingResource = getResourceToBeAliased(resource);
+            // resource containing the alias
+            final Resource containingResource = getResourceToBeAliased(resource);
 
-        if (containingResource != null) {
-            final String containingResourceName = containingResource.getName();
-            final String parentPath = ResourceUtil.getParent(containingResource.getPath());
+            if (containingResource != null) {
+                final String containingResourceName = containingResource.getName();
+                final String parentPath = ResourceUtil.getParent(containingResource.getPath());
 
-            final Map<String, Collection<String>> aliasMapEntry =
-                    parentPath == null ? null : aliasMapsMap.get(parentPath);
-            if (aliasMapEntry != null) {
-                aliasMapEntry.remove(containingResourceName);
-                if (aliasMapEntry.isEmpty()) {
-                    this.aliasMapsMap.remove(parentPath);
+                final Map<String, Collection<String>> aliasMapEntry =
+                        parentPath == null ? null : aliasMapsMap.get(parentPath);
+                if (aliasMapEntry != null) {
+                    aliasMapEntry.remove(containingResourceName);
+                    if (aliasMapEntry.isEmpty()) {
+                        this.aliasMapsMap.remove(parentPath);
+                    }
                 }
-            }
 
-            boolean changed = aliasMapEntry != null;
+                boolean changed = aliasMapEntry != null;
 
-            if (containingResource.getValueMap().containsKey(ResourceResolverImpl.PROP_ALIAS)) {
-                changed |= doAddAlias(containingResource);
-            }
-            final Resource child = containingResource.getChild(JCR_CONTENT);
-            if (child != null && child.getValueMap().containsKey(ResourceResolverImpl.PROP_ALIAS)) {
-                changed |= doAddAlias(child);
+                if (containingResource.getValueMap().containsKey(ResourceResolverImpl.PROP_ALIAS)) {
+                    changed |= doAddAlias(containingResource);
+                }
+                final Resource child = containingResource.getChild(JCR_CONTENT);
+                if (child != null && child.getValueMap().containsKey(ResourceResolverImpl.PROP_ALIAS)) {
+                    changed |= doAddAlias(child);
+                }
+
+                return changed;
+            } else {
+                log.warn("containingResource is null for alias on {}, skipping.", resource.getPath());
             }
 
-            return changed;
-        } else {
-            log.warn("containingResource is null for alias on {}, skipping.", resource.getPath());
+            return false;
         }
 
-        return false;
-    }
+        public @NotNull Map<String, Collection<String>> getAliasMap(final String parentPath) {
+            Map<String, Collection<String>> aliasMapForParent = aliasMapsMap.get(parentPath);
+            return aliasMapForParent != null ? aliasMapForParent : Collections.emptyMap();
+        }
 
-    @Override
-    public @NotNull Map<String, Collection<String>> getAliasMap(final String parentPath) {
-        Map<String, Collection<String>> aliasMapForParent = aliasMapsMap.get(parentPath);
-        return aliasMapForParent != null ? aliasMapForParent : Collections.emptyMap();
-    }
+        /**
+         * Load aliases - Search for all nodes (except under /jcr:system) below
+         * configured alias locations having the sling:alias property
+         */
+        private Map<String, Map<String, Collection<String>>> loadAliases(
+                List<String> conflictingAliases, List<String> invalidAliases) throws LoginException {
 
-    @Override
-    public Map<String, List<String>> getVanityPathMappings() {
-        return vph.getVanityPathMappings();
-    }
+            final ResourceResolver resolver =
+                    factory.getServiceResourceResolver(factory.getServiceUserAuthenticationInfo("mapping"));
 
-    /**
-     * Load aliases - Search for all nodes (except under /jcr:system) below
-     * configured alias locations having the sling:alias property
-     */
-    private Map<String, Map<String, Collection<String>>> loadAliases(
-            final ResourceResolver resolver, List<String> conflictingAliases, List<String> invalidAliases) {
+            final Map<String, Map<String, Collection<String>>> map = new ConcurrentHashMap<>();
+            final String baseQueryString = generateAliasQuery();
 
-        final Map<String, Map<String, Collection<String>>> map = new ConcurrentHashMap<>();
-        final String baseQueryString = generateAliasQuery();
+            Iterator<Resource> it;
+            try {
+                final String queryStringWithSort =
+                        baseQueryString + " AND FIRST([sling:alias]) >= '%s' ORDER BY FIRST([sling:alias])";
+                it = new PagedQueryIterator("alias", "sling:alias", resolver, queryStringWithSort, 2000);
+            } catch (QuerySyntaxException ex) {
+                log.debug("sort with first() not supported, falling back to base query", ex);
+                it = queryUnpaged("alias", baseQueryString);
+            } catch (UnsupportedOperationException ex) {
+                log.debug("query failed as unsupported, retrying without paging/sorting", ex);
+                it = queryUnpaged("alias", baseQueryString);
+            }
 
-        Iterator<Resource> it;
-        try {
-            final String queryStringWithSort =
-                    baseQueryString + " AND FIRST([sling:alias]) >= '%s' ORDER BY FIRST([sling:alias])";
-            it = new PagedQueryIterator("alias", "sling:alias", resolver, queryStringWithSort, 2000);
-        } catch (QuerySyntaxException ex) {
-            log.debug("sort with first() not supported, falling back to base query", ex);
-            it = queryUnpaged("alias", baseQueryString);
-        } catch (UnsupportedOperationException ex) {
-            log.debug("query failed as unsupported, retrying without paging/sorting", ex);
-            it = queryUnpaged("alias", baseQueryString);
-        }
+            log.debug("alias initialization - start");
+            long count = 0;
+            long processStart = System.nanoTime();
+            while (it.hasNext()) {
+                count += 1;
+                loadAlias(it.next(), map, conflictingAliases, invalidAliases);
+            }
+            long processElapsed = System.nanoTime() - processStart;
+            long resourcePerSecond = (count * TimeUnit.SECONDS.toNanos(1) / (processElapsed == 0 ? 1 : processElapsed));
 
-        log.debug("alias initialization - start");
-        long count = 0;
-        long processStart = System.nanoTime();
-        while (it.hasNext()) {
-            count += 1;
-            loadAlias(it.next(), map, conflictingAliases, invalidAliases);
-        }
-        long processElapsed = System.nanoTime() - processStart;
-        long resourcePerSecond = (count * TimeUnit.SECONDS.toNanos(1) / (processElapsed == 0 ? 1 : processElapsed));
+            String diagnostics = "";
+            if (it instanceof PagedQueryIterator) {
+                PagedQueryIterator pit = (PagedQueryIterator) it;
 
-        String diagnostics = "";
-        if (it instanceof PagedQueryIterator) {
-            PagedQueryIterator pit = (PagedQueryIterator) it;
+                if (!pit.getWarning().isEmpty()) {
+                    log.warn(pit.getWarning());
+                }
 
-            if (!pit.getWarning().isEmpty()) {
-                log.warn(pit.getWarning());
+                diagnostics = pit.getStatistics();
             }
 
-            diagnostics = pit.getStatistics();
-        }
-
-        log.info(
-                "alias initialization - completed, processed {} resources with sling:alias properties in {}ms (~{} resource/s){}",
-                count,
-                TimeUnit.NANOSECONDS.toMillis(processElapsed),
-                resourcePerSecond,
-                diagnostics);
+            log.info(
+                    "alias initialization - completed, processed {} resources with sling:alias properties in {}ms (~{} resource/s){}",
+                    count,
+                    TimeUnit.NANOSECONDS.toMillis(processElapsed),
+                    resourcePerSecond,
+                    diagnostics);
 
-        this.aliasResourcesOnStartup.set(count);
+            this.aliasResourcesOnStartup.set(count);
 
-        return map;
-    }
+            return map;
+        }
 
-    /*
-     * generate alias query based on configured alias locations
-     */
-    private String generateAliasQuery() {
-        final Set<String> allowedLocations = this.factory.getAllowedAliasLocations();
+        /*
+         * generate alias query based on configured alias locations
+         */
+        private String generateAliasQuery() {
+            final Set<String> allowedLocations = this.factory.getAllowedAliasLocations();
 
-        StringBuilder baseQuery = new StringBuilder("SELECT [sling:alias] FROM [nt:base] WHERE");
+            StringBuilder baseQuery = new StringBuilder("SELECT [sling:alias] FROM [nt:base] WHERE");
 
-        if (allowedLocations.isEmpty()) {
-            baseQuery.append(" ").append(QueryBuildHelper.excludeSystemPath());
-        } else {
-            Iterator<String> pathIterator = allowedLocations.iterator();
-            baseQuery.append(" (");
-            String sep = "";
-            while (pathIterator.hasNext()) {
-                String prefix = pathIterator.next();
-                baseQuery
-                        .append(sep)
-                        .append("isdescendantnode('")
-                        .append(QueryBuildHelper.escapeString(prefix))
-                        .append("')");
-                sep = " OR ";
+            if (allowedLocations.isEmpty()) {
+                baseQuery.append(" ").append(QueryBuildHelper.excludeSystemPath());
+            } else {
+                Iterator<String> pathIterator = allowedLocations.iterator();
+                baseQuery.append(" (");
+                String sep = "";
+                while (pathIterator.hasNext()) {
+                    String prefix = pathIterator.next();
+                    baseQuery
+                            .append(sep)
+                            .append("isdescendantnode('")
+                            .append(QueryBuildHelper.escapeString(prefix))
+                            .append("')");
+                    sep = " OR ";
+                }
+                baseQuery.append(")");
             }
-            baseQuery.append(")");
-        }
-
-        baseQuery.append(" AND [sling:alias] IS NOT NULL");
-        return baseQuery.toString();
-    }
 
-    /**
-     * Load alias given a resource
-     */
-    private boolean loadAlias(
-            final Resource resource,
-            Map<String, Map<String, Collection<String>>> map,
-            List<String> conflictingAliases,
-            List<String> invalidAliases) {
+            baseQuery.append(" AND [sling:alias] IS NOT NULL");
+            return baseQuery.toString();
+        }
 
-        // resource containing the alias
-        final Resource containingResource = getResourceToBeAliased(resource);
+        /**
+         * Load alias given a resource
+         */
+        private boolean loadAlias(
+                final Resource resource,
+                Map<String, Map<String, Collection<String>>> map,
+                List<String> conflictingAliases,
+                List<String> invalidAliases) {
 
-        if (containingResource == null) {
-            log.warn("containingResource is null for alias on {}, skipping.", resource.getPath());
-            return false;
-        } else {
-            final Resource parent = containingResource.getParent();
+            // resource containing the alias
+            final Resource containingResource = getResourceToBeAliased(resource);
 
-            if (parent == null) {
-                log.warn(
-                        "{} is null for alias on {}, skipping.",
-                        containingResource == resource ? "parent" : "grandparent",
-                        resource.getPath());
+            if (containingResource == null) {
+                log.warn("containingResource is null for alias on {}, skipping.", resource.getPath());
                 return false;
             } else {
-                final String[] aliasArray = resource.getValueMap().get(ResourceResolverImpl.PROP_ALIAS, String[].class);
-                if (aliasArray == null) {
+                final Resource parent = containingResource.getParent();
+
+                if (parent == null) {
+                    log.warn(
+                            "{} is null for alias on {}, skipping.",
+                            containingResource == resource ? "parent" : "grandparent",
+                            resource.getPath());
                     return false;
                 } else {
-                    return loadAliasFromArray(
-                            aliasArray,
-                            map,
-                            conflictingAliases,
-                            invalidAliases,
-                            containingResource.getName(),
-                            parent.getPath());
+                    final String[] aliasArray =
+                            resource.getValueMap().get(ResourceResolverImpl.PROP_ALIAS, String[].class);
+                    if (aliasArray == null) {
+                        return false;
+                    } else {
+                        return loadAliasFromArray(
+                                aliasArray,
+                                map,
+                                conflictingAliases,
+                                invalidAliases,
+                                containingResource.getName(),
+                                parent.getPath());
+                    }
                 }
             }
         }
-    }
 
-    /**
-     * Load alias given a an alias array, return success flag.
-     */
-    private boolean loadAliasFromArray(
-            final String[] aliasArray,
-            Map<String, Map<String, Collection<String>>> map,
-            List<String> conflictingAliases,
-            List<String> invalidAliases,
-            final String resourceName,
-            final String parentPath) {
-
-        boolean hasAlias = false;
-
-        log.debug("Found alias, total size {}", aliasArray.length);
-
-        // the order matters here, the first alias in the array must come first
-        for (final String alias : aliasArray) {
-            if (isAliasInvalid(alias)) {
-                long invalids = detectedInvalidAliases.incrementAndGet();
-                log.warn(
-                        "Encountered invalid alias '{}' under parent path '{}' (total so far: {}). Refusing to use it.",
-                        alias,
-                        parentPath,
-                        invalids);
-                if (invalidAliases != null && invalids < MAX_REPORT_DEFUNCT_ALIASES) {
-                    invalidAliases.add((String.format("'%s'/'%s'", parentPath, alias)));
-                }
-            } else {
-                Map<String, Collection<String>> parentMap =
-                        map.computeIfAbsent(parentPath, key -> new ConcurrentHashMap<>());
-                Optional<String> siblingResourceNameWithDuplicateAlias = parentMap.entrySet().stream()
-                        .filter(entry -> !entry.getKey().equals(resourceName)) // ignore entry for the current resource
-                        .filter(entry -> entry.getValue().contains(alias))
-                        .findFirst()
-                        .map(Map.Entry::getKey);
-                if (siblingResourceNameWithDuplicateAlias.isPresent()) {
-                    long conflicting = detectedConflictingAliases.incrementAndGet();
+        /**
+         * Load alias given a an alias array, return success flag.
+         */
+        private boolean loadAliasFromArray(
+                final String[] aliasArray,
+                Map<String, Map<String, Collection<String>>> map,
+                List<String> conflictingAliases,
+                List<String> invalidAliases,
+                final String resourceName,
+                final String parentPath) {
+
+            boolean hasAlias = false;
+
+            log.debug("Found alias, total size {}", aliasArray.length);
+
+            // the order matters here, the first alias in the array must come first
+            for (final String alias : aliasArray) {
+                if (isAliasInvalid(alias)) {
+                    long invalids = detectedInvalidAliases.incrementAndGet();
                     log.warn(
-                            "Encountered duplicate alias '{}' under parent path '{}'. Refusing to replace current target '{}' with '{}' (total duplicated aliases so far: {}).",
+                            "Encountered invalid alias '{}' under parent path '{}' (total so far: {}). Refusing to use it.",
                             alias,
                             parentPath,
-                            siblingResourceNameWithDuplicateAlias.get(),
-                            resourceName,
-                            conflicting);
-                    if (conflictingAliases != null && conflicting < MAX_REPORT_DEFUNCT_ALIASES) {
-                        conflictingAliases.add((String.format(
-                                "'%s': '%s'/'%s' vs '%s'/'%s'",
-                                parentPath, resourceName, alias, siblingResourceNameWithDuplicateAlias.get(), alias)));
+                            invalids);
+                    if (invalidAliases != null && invalids < MAX_REPORT_DEFUNCT_ALIASES) {
+                        invalidAliases.add((String.format("'%s'/'%s'", parentPath, alias)));
                     }
                 } else {
-                    Collection<String> existingAliases =
-                            parentMap.computeIfAbsent(resourceName, name -> new CopyOnWriteArrayList<>());
-                    existingAliases.add(alias);
-                    hasAlias = true;
+                    Map<String, Collection<String>> parentMap =
+                            map.computeIfAbsent(parentPath, key -> new ConcurrentHashMap<>());
+                    Optional<String> siblingResourceNameWithDuplicateAlias = parentMap.entrySet().stream()
+                            .filter(entry ->
+                                    !entry.getKey().equals(resourceName)) // ignore entry for the current resource
+                            .filter(entry -> entry.getValue().contains(alias))
+                            .findFirst()
+                            .map(Map.Entry::getKey);
+                    if (siblingResourceNameWithDuplicateAlias.isPresent()) {
+                        long conflicting = detectedConflictingAliases.incrementAndGet();
+                        log.warn(
+                                "Encountered duplicate alias '{}' under parent path '{}'. Refusing to replace current target '{}' with '{}' (total duplicated aliases so far: {}).",
+                                alias,
+                                parentPath,
+                                siblingResourceNameWithDuplicateAlias.get(),
+                                resourceName,
+                                conflicting);
+                        if (conflictingAliases != null && conflicting < MAX_REPORT_DEFUNCT_ALIASES) {
+                            conflictingAliases.add((String.format(
+                                    "'%s': '%s'/'%s' vs '%s'/'%s'",
+                                    parentPath,
+                                    resourceName,
+                                    alias,
+                                    siblingResourceNameWithDuplicateAlias.get(),
+                                    alias)));
+                        }
+                    } else {
+                        Collection<String> existingAliases =
+                                parentMap.computeIfAbsent(resourceName, name -> new CopyOnWriteArrayList<>());
+                        existingAliases.add(alias);
+                        hasAlias = true;
+                    }
                 }
             }
-        }
 
-        return hasAlias;
-    }
+            return hasAlias;
+        }
 
-    /**
-     * Given a resource, check whether the name is "jcr:content", in which case return the parent resource
-     * @param resource resource to check
-     * @return parent of jcr:content resource (may be null), otherwise the resource itself
-     */
-    @Nullable
-    private Resource getResourceToBeAliased(Resource resource) {
-        if (JCR_CONTENT.equals(resource.getName())) {
-            return resource.getParent();
-        } else {
-            return resource;
+        /**
+         * Given a resource, check whether the name is "jcr:content", in which case return the parent resource
+         * @param resource resource to check
+         * @return parent of jcr:content resource (may be null), otherwise the resource itself
+         */
+        @Nullable
+        private Resource getResourceToBeAliased(Resource resource) {
+            if (JCR_CONTENT.equals(resource.getName())) {
+                return resource.getParent();
+            } else {
+                return resource;
+            }
         }
-    }
 
-    /**
-     * Check alias syntax
-     */
-    private static boolean isAliasInvalid(String alias) {
-        boolean invalid = alias.equals("..") || alias.equals(".") || alias.isEmpty();
-        if (!invalid) {
-            for (final char c : alias.toCharArray()) {
-                // invalid if / or # or a ?
-                if (c == '/' || c == '#' || c == '?') {
-                    invalid = true;
-                    break;
+        /**
+         * Check alias syntax
+         */
+        private boolean isAliasInvalid(String alias) {
+            boolean invalid = alias.equals("..") || alias.equals(".") || alias.isEmpty();
+            if (!invalid) {
+                for (final char c : alias.toCharArray()) {
+                    // invalid if / or # or a ?
+                    if (c == '/' || c == '#' || c == '?') {
+                        invalid = true;
+                        break;
+                    }
                 }
             }
+            return invalid;
         }
-        return invalid;
-    }
 
-    private Iterator<Resource> queryUnpaged(String subject, String query) {
-        log.debug("start {} query: {}", subject, query);
-        long queryStart = System.nanoTime();
-        final Iterator<Resource> it = resolver.findResources(query, "JCR-SQL2");
-        long queryElapsed = System.nanoTime() - queryStart;
-        log.debug("end {} query; elapsed {}ms", subject, TimeUnit.NANOSECONDS.toMillis(queryElapsed));
-        return it;
-    }
+        private Iterator<Resource> queryUnpaged(String subject, String query) {
+            log.debug("start {} query: {}", subject, query);
+            long queryStart = System.nanoTime();
+            final Iterator<Resource> it = resolver.findResources(query, "JCR-SQL2");
+            long queryElapsed = System.nanoTime() - queryStart;
+            log.debug("end {} query; elapsed {}ms", subject, TimeUnit.NANOSECONDS.toMillis(queryElapsed));
+            return it;
+        }
 
-    private final AtomicLong lastTimeLogged = new AtomicLong(-1);
+        private final AtomicLong lastTimeLogged = new AtomicLong(-1);
 
-    private final long LOGGING_ERROR_PERIOD = 1000 * 60 * 5;
+        private final long LOGGING_ERROR_PERIOD = 1000 * 60 * 5;
 
-    @Override
-    public void logDisableAliasOptimization() {
-        this.logDisableAliasOptimization(null);
-    }
-
-    private void logDisableAliasOptimization(final Exception e) {
-        if (e != null) {
-            log.error(
-                    "Unexpected problem during initialization of optimize alias resolution. Therefore disabling optimize alias resolution. Please fix the problem.",
-                    e);
-        } else {
-            final long now = System.currentTimeMillis();
-            if (now - lastTimeLogged.getAndSet(now) > LOGGING_ERROR_PERIOD) {
+        private void logDisableAliasOptimization(final Exception e) {
+            if (e != null) {
                 log.error(
-                        "A problem occured during initialization of optimize alias resolution. Optimize alias resolution is disabled. Check the logs for the reported problem.",
+                        "Unexpected problem during initialization of optimize alias resolution. Therefore disabling optimize alias resolution. Please fix the problem.",
                         e);
+            } else {
+                final long now = System.currentTimeMillis();
+                if (now - lastTimeLogged.getAndSet(now) > LOGGING_ERROR_PERIOD) {
+                    log.error(
+                            "A problem occured during initialization of optimize alias resolution. Optimize alias resolution is disabled. Check the logs for the reported problem.",
+                            e);
+                }
             }
         }
     }
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/AbstractMappingMapEntriesTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/AbstractMappingMapEntriesTest.java
index b5cb274f..9472e0c3 100644
--- a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/AbstractMappingMapEntriesTest.java
+++ b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/AbstractMappingMapEntriesTest.java
@@ -123,9 +123,9 @@ public abstract class AbstractMappingMapEntriesTest {
         mapEntries = new MapEntries(
                 resourceResolverFactory, bundleContext, eventAdmin, stringInterpolationProvider, metrics);
 
-        final Field aliasMapField = MapEntries.class.getDeclaredField("aliasMapsMap");
+        final Field aliasMapField = MapEntries.AliasHandler.class.getDeclaredField("aliasMapsMap");
         aliasMapField.setAccessible(true);
-        this.aliasMap = (Map<String, Map<String, String>>) aliasMapField.get(mapEntries);
+        this.aliasMap = (Map<String, Map<String, String>>) aliasMapField.get(mapEntries.ah);
     }
 
     List<MapConfigurationProvider.VanityPathConfig> getVanityPathConfigs() {
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/AliasMapEntriesTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/AliasMapEntriesTest.java
index 9534d14b..d6bd49fb 100644
--- a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/AliasMapEntriesTest.java
+++ b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/AliasMapEntriesTest.java
@@ -114,17 +114,19 @@ public class AliasMapEntriesTest extends AbstractMappingMapEntriesTest {
         mapEntries = new MapEntries(
                 resourceResolverFactory, bundleContext, eventAdmin, stringInterpolationProvider, metrics);
 
-        final Field aliasMapField = MapEntries.class.getDeclaredField("aliasMapsMap");
+        final Field aliasMapField = MapEntries.AliasHandler.class.getDeclaredField("aliasMapsMap");
         aliasMapField.setAccessible(true);
-        this.aliasMap = (Map<String, Map<String, String>>) aliasMapField.get(mapEntries);
+        this.aliasMap = (Map<String, Map<String, String>>) aliasMapField.get(mapEntries.ah);
 
-        final Field detectedInvalidAliasesField = MapEntries.class.getDeclaredField("detectedInvalidAliases");
+        final Field detectedInvalidAliasesField =
+                MapEntries.AliasHandler.class.getDeclaredField("detectedInvalidAliases");
         detectedInvalidAliasesField.setAccessible(true);
-        this.detectedInvalidAliases = (AtomicLong) detectedInvalidAliasesField.get(mapEntries);
+        this.detectedInvalidAliases = (AtomicLong) detectedInvalidAliasesField.get(mapEntries.ah);
 
-        final Field detectedConflictingAliasesField = MapEntries.class.getDeclaredField("detectedConflictingAliases");
+        final Field detectedConflictingAliasesField =
+                MapEntries.AliasHandler.class.getDeclaredField("detectedConflictingAliases");
         detectedConflictingAliasesField.setAccessible(true);
-        this.detectedConflictingAliases = (AtomicLong) detectedConflictingAliasesField.get(mapEntries);
+        this.detectedConflictingAliases = (AtomicLong) detectedConflictingAliasesField.get(mapEntries.ah);
     }
 
     @Override
@@ -165,7 +167,7 @@ public class AliasMapEntriesTest extends AbstractMappingMapEntriesTest {
 
     private void internal_test_simple_alias_support(boolean onJcrContent) {
         prepareMapEntriesForAlias(onJcrContent, false, "alias");
-        mapEntries.initializeAliases();
+        mapEntries.ah.initializeAliases();
         Map<String, Collection<String>> aliasMap = mapEntries.getAliasMap("/parent");
         assertNotNull(aliasMap);
         assertTrue(aliasMap.containsKey("child"));
@@ -184,7 +186,7 @@ public class AliasMapEntriesTest extends AbstractMappingMapEntriesTest {
 
     private void internal_test_simple_multi_alias_support(boolean onJcrContent) {
         prepareMapEntriesForAlias(onJcrContent, false, "foo", "bar");
-        mapEntries.initializeAliases();
+        mapEntries.ah.initializeAliases();
         Map<String, Collection<String>> aliasMap = mapEntries.getAliasMap("/parent");
         assertNotNull(aliasMap);
         assertTrue(aliasMap.containsKey("child"));
@@ -194,7 +196,7 @@ public class AliasMapEntriesTest extends AbstractMappingMapEntriesTest {
     @Test
     public void internal_test_simple_alias_support_throwing_unsupported_operation_exception_exception() {
         prepareMapEntriesForAlias(false, false, UnsupportedOperationException.class, "foo", "bar");
-        assertFalse(mapEntries.initializeAliases());
+        assertFalse(mapEntries.ah.initializeAliases());
     }
 
     @Test
@@ -211,7 +213,7 @@ public class AliasMapEntriesTest extends AbstractMappingMapEntriesTest {
     public void test_simple_multi_alias_support_with_null_parent() {
         // see SLING-12383
         prepareMapEntriesForAlias(true, true, "foo", "bar");
-        mapEntries.initializeAliases();
+        mapEntries.ah.initializeAliases();
         Map<String, Collection<String>> aliasMap = mapEntries.getAliasMap("/parent");
         assertNotNull(aliasMap);
         assertFalse(aliasMap.containsKey("child"));
@@ -221,7 +223,7 @@ public class AliasMapEntriesTest extends AbstractMappingMapEntriesTest {
     public void test_simple_multi_alias_support_with_blank_and_invalid() {
         // invalid aliases filtered out
         prepareMapEntriesForAlias(false, false, "", "foo", ".", "bar", "x/y", "qux", " ");
-        mapEntries.initializeAliases();
+        mapEntries.ah.initializeAliases();
         Map<String, Collection<String>> aliasMap = mapEntries.getAliasMap("/parent");
         assertNotNull(aliasMap);
         assertTrue(aliasMap.containsKey("child"));
@@ -234,7 +236,7 @@ public class AliasMapEntriesTest extends AbstractMappingMapEntriesTest {
         List<String> invalidAliases = List.of(".", "..", "foo/bar", "# foo", "");
         for (String invalidAlias : invalidAliases) {
             prepareMapEntriesForAlias(false, false, invalidAlias);
-            mapEntries.initializeAliases();
+            mapEntries.ah.initializeAliases();
             Map<String, Collection<String>> aliasMap = mapEntries.getAliasMap("/parent");
             assertEquals(Collections.emptyMap(), aliasMap);
         }
@@ -307,7 +309,7 @@ public class AliasMapEntriesTest extends AbstractMappingMapEntriesTest {
                     }
                 });
 
-        mapEntries.initializeAliases();
+        mapEntries.ah.initializeAliases();
 
         Map<String, Collection<String>> aliasMap = mapEntries.getAliasMap("/parent");
         assertNotNull(aliasMap);
@@ -1168,7 +1170,7 @@ public class AliasMapEntriesTest extends AbstractMappingMapEntriesTest {
     @Test
     public void test_initAliasesAfterDispose() {
         mapEntries.dispose();
-        boolean enabled = mapEntries.initializeAliases();
+        boolean enabled = mapEntries.ah.initializeAliases();
         assertFalse("return value (isOptimizeAliasResolutionEnabled) should be false", enabled);
     }
 }
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/EtcMappingMapEntriesTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/EtcMappingMapEntriesTest.java
index 225159eb..87f68cd5 100644
--- a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/EtcMappingMapEntriesTest.java
+++ b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/EtcMappingMapEntriesTest.java
@@ -67,7 +67,7 @@ public class EtcMappingMapEntriesTest extends AbstractMappingMapEntriesTest {
     public void root_node_to_content_mapping() throws Exception {
         setupEtcMapResource("localhost.8080", http, PROP_REDIRECT_EXTERNAL, "/content/simple-node");
 
-        mapEntries.initializeAliases();
+        mapEntries.ah.initializeAliases();
         ExpectedEtcMapping expectedEtcMapping =
                 new ExpectedEtcMapping("^http/localhost.8080/", "/content/simple-node/");
         expectedEtcMapping.assertEtcMap("Etc Mapping for simple node", mapEntries.getResolveMaps());
@@ -78,7 +78,7 @@ public class EtcMappingMapEntriesTest extends AbstractMappingMapEntriesTest {
         setupEtcMapResource(
                 "test-node", http, PROP_REG_EXP, "localhost.8080/", PROP_REDIRECT_EXTERNAL, "/content/simple-match/");
 
-        mapEntries.initializeAliases();
+        mapEntries.ah.initializeAliases();
         ExpectedEtcMapping expectedEtcMapping =
                 new ExpectedEtcMapping("^http/localhost.8080/", "/content/simple-match/");
         expectedEtcMapping.assertEtcMap("Etc Mapping for simple match", mapEntries.getResolveMaps());
@@ -91,7 +91,7 @@ public class EtcMappingMapEntriesTest extends AbstractMappingMapEntriesTest {
     public void internal_to_external_node_mapping() throws Exception {
         setupEtcMapResource("example.com.80", http, PROP_REDIRECT_EXTERNAL, "http://www.example.com/");
 
-        mapEntries.initializeAliases();
+        mapEntries.ah.initializeAliases();
         ExpectedEtcMapping expectedEtcMapping =
                 new ExpectedEtcMapping("^http/example.com.80/", "http://www.example.com/");
         expectedEtcMapping.assertEtcMap(
@@ -102,7 +102,7 @@ public class EtcMappingMapEntriesTest extends AbstractMappingMapEntriesTest {
     public void internal_root_to_content_node_mapping() throws Exception {
         setupEtcMapResource("www.example.com.80", http, PROP_REDIRECT_INTERNAL, "/example");
 
-        mapEntries.initializeAliases();
+        mapEntries.ah.initializeAliases();
         ExpectedEtcMapping expectedEtcMapping =
                 new ExpectedEtcMapping().addEtcMapEntry("^http/www.example.com.80/", true, "/example/");
         expectedEtcMapping.assertEtcMap("Etc Mapping for internal root to content", mapEntries.getResolveMaps());
@@ -118,7 +118,7 @@ public class EtcMappingMapEntriesTest extends AbstractMappingMapEntriesTest {
                 PROP_REDIRECT_EXTERNAL,
                 "http://www.example.com/");
 
-        mapEntries.initializeAliases();
+        mapEntries.ah.initializeAliases();
         ExpectedEtcMapping expectedEtcMapping = new ExpectedEtcMapping()
                 .addEtcMapEntry("^http/.+\\.example\\.com\\.80", false, "http://www.example.com/");
         expectedEtcMapping.assertEtcMap("Etc Mapping for host redirect match mapping", mapEntries.getResolveMaps());
@@ -132,7 +132,7 @@ public class EtcMappingMapEntriesTest extends AbstractMappingMapEntriesTest {
         setupEtcMapResource("gateway", localhost, PROP_REDIRECT_INTERNAL, "http://gbiv.com");
         setupEtcMapResource("(stories)", localhost, PROP_REDIRECT_INTERNAL, "/anecdotes/$1");
 
-        mapEntries.initializeAliases();
+        mapEntries.ah.initializeAliases();
         ExpectedEtcMapping expectedEtcMapping = new ExpectedEtcMapping()
                 .addEtcMapEntry("^http/localhost\\.\\d*", true, "/content")
                 .addEtcMapEntry("^http/localhost\\.\\d*/cgi-bin/", true, "/scripts/")
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapEntriesTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapEntriesTest.java
index e44e93cf..4f650f45 100644
--- a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapEntriesTest.java
+++ b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapEntriesTest.java
@@ -110,9 +110,9 @@ public class MapEntriesTest extends AbstractMappingMapEntriesTest {
         mapEntries = new MapEntries(
                 resourceResolverFactory, bundleContext, eventAdmin, stringInterpolationProvider, metrics);
 
-        final Field aliasMapField = MapEntries.class.getDeclaredField("aliasMapsMap");
+        final Field aliasMapField = MapEntries.AliasHandler.class.getDeclaredField("aliasMapsMap");
         aliasMapField.setAccessible(true);
-        this.aliasMap = (Map<String, Map<String, String>>) aliasMapField.get(mapEntries);
+        this.aliasMap = (Map<String, Map<String, String>>) aliasMapField.get(mapEntries.ah);
     }
 
     @Override
@@ -215,6 +215,6 @@ public class MapEntriesTest extends AbstractMappingMapEntriesTest {
                     return Collections.emptyIterator();
                 });
 
-        mapEntries.initializeAliases();
+        mapEntries.ah.initializeAliases();
     }
 }
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/StringInterpolationMapEntriesTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/StringInterpolationMapEntriesTest.java
index d9964e6c..633f0a21 100644
--- a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/StringInterpolationMapEntriesTest.java
+++ b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/StringInterpolationMapEntriesTest.java
@@ -41,7 +41,7 @@ public class StringInterpolationMapEntriesTest extends AbstractMappingMapEntries
                 stringInterpolationProviderConfiguration,
                 new String[] {"siv.one=test-simple-node"});
 
-        mapEntries.initializeAliases();
+        mapEntries.ah.initializeAliases();
         ExpectedEtcMapping expectedEtcMapping =
                 new ExpectedEtcMapping("^http/test-simple-node/", "/content/simple-node/");
         expectedEtcMapping.assertEtcMap("String Interpolation for simple match", mapEntries.getResolveMaps());
@@ -62,7 +62,7 @@ public class StringInterpolationMapEntriesTest extends AbstractMappingMapEntries
                 stringInterpolationProviderConfiguration,
                 new String[] {"siv.one=test-simple-match"});
 
-        mapEntries.initializeAliases();
+        mapEntries.ah.initializeAliases();
         ExpectedEtcMapping expectedEtcMapping =
                 new ExpectedEtcMapping("^http/test-simple-match/", "/content/simple-match/");
         expectedEtcMapping.assertEtcMap("String Interpolation for simple match", mapEntries.getResolveMaps());
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/VanityPathMapEntriesTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/VanityPathMapEntriesTest.java
index 5dbfed78..fa03f4ce 100644
--- a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/VanityPathMapEntriesTest.java
+++ b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/VanityPathMapEntriesTest.java
@@ -1279,7 +1279,7 @@ public class VanityPathMapEntriesTest extends AbstractMappingMapEntriesTest {
         mapEntries = new MapEntries(
                 resourceResolverFactory, bundleContext, eventAdmin, stringInterpolationProvider, metrics);
 
-        mapEntries.initializeAliases();
+        mapEntries.ah.initializeAliases();
     }
 
     @Test