You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by cs...@apache.org on 2022/11/14 10:32:04 UTC

[maven-resolver] branch master updated: [MRESOLVER-291] Undo params use (#219)

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

cstamas pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven-resolver.git


The following commit(s) were added to refs/heads/master by this push:
     new 21b0ac88 [MRESOLVER-291] Undo params use (#219)
21b0ac88 is described below

commit 21b0ac880166beaa42220e4d02c9f7b073130345
Author: Tamas Cservenak <ta...@cservenak.net>
AuthorDate: Mon Nov 14 11:31:59 2022 +0100

    [MRESOLVER-291] Undo params use (#219)
    
    Pull out ctor param injection, provide generic enough helper to allow anyone to customize as they want.
    
    Changes in short:
    Nor SyncContextFactory nor NamedLockFactoryAdapter should shut down. This was the problem, and I was mislead by it. NamedLockFactory instances are **singletons**, and **are inited in ctor**. Hence, if two adapters used same factory, in case one adapter is shut down, it would shut down the lock factory of the other one as well (unexpectedly). Hence, it is solely the adapter factory duty to shut down factories, but again, as we saw, they are inited in ctor, hence if we assume there is l [...]
    
    Minor: do not create static initializers to be used in SL, make them methods invoked when needed.
    
    ---
    
    https://issues.apache.org/jira/browse/MRESOLVER-291
---
 .../eclipse/aether/impl/DefaultServiceLocator.java |   3 +
 .../eclipse/aether/impl/guice/AetherModule.java    |   7 +-
 .../synccontext/DefaultSyncContextFactory.java     |  36 ++-
 .../synccontext/named/NamedLockFactoryAdapter.java |  15 +-
 ...or.java => NamedLockFactoryAdapterFactory.java} |  22 +-
 .../named/NamedLockFactoryAdapterFactoryImpl.java  | 256 +++++++++++++++++++++
 .../ParameterizedNamedLockFactorySelector.java     | 147 ------------
 .../NamedLockFactoryAdapterTestSupport.java        |   2 +-
 .../NamedLockFactoryAdapterTestSupport.java        |   2 +-
 .../transport/http/HttpTransporterFactory.java     |   8 +-
 10 files changed, 305 insertions(+), 193 deletions(-)

diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/impl/DefaultServiceLocator.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/impl/DefaultServiceLocator.java
index 69cfc2c8..f197ebba 100644
--- a/maven-resolver-impl/src/main/java/org/eclipse/aether/impl/DefaultServiceLocator.java
+++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/impl/DefaultServiceLocator.java
@@ -60,6 +60,8 @@ import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory;
 import org.eclipse.aether.internal.impl.filter.DefaultRemoteRepositoryFilterManager;
 import org.eclipse.aether.internal.impl.slf4j.Slf4jLoggerFactory;
 import org.eclipse.aether.internal.impl.synccontext.DefaultSyncContextFactory;
+import org.eclipse.aether.internal.impl.synccontext.named.NamedLockFactoryAdapterFactoryImpl;
+import org.eclipse.aether.internal.impl.synccontext.named.NamedLockFactoryAdapterFactory;
 import org.eclipse.aether.spi.connector.checksum.ChecksumAlgorithmFactorySelector;
 import org.eclipse.aether.spi.connector.checksum.ChecksumPolicyProvider;
 import org.eclipse.aether.spi.connector.layout.RepositoryLayoutFactory;
@@ -231,6 +233,7 @@ public final class DefaultServiceLocator
         addService( LocalPathComposer.class, DefaultLocalPathComposer.class );
         addService( RemoteRepositoryFilterManager.class, DefaultRemoteRepositoryFilterManager.class );
         addService( RepositorySystemLifecycle.class, DefaultRepositorySystemLifecycle.class );
+        addService( NamedLockFactoryAdapterFactory.class, NamedLockFactoryAdapterFactoryImpl.class );
     }
 
     private <T> Entry<T> getEntry( Class<T> type, boolean create )
diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/impl/guice/AetherModule.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/impl/guice/AetherModule.java
index 54e04788..bf4fbc1e 100644
--- a/maven-resolver-impl/src/main/java/org/eclipse/aether/impl/guice/AetherModule.java
+++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/impl/guice/AetherModule.java
@@ -65,9 +65,9 @@ import org.eclipse.aether.internal.impl.filter.GroupIdRemoteRepositoryFilterSour
 import org.eclipse.aether.internal.impl.filter.PrefixesRemoteRepositoryFilterSource;
 import org.eclipse.aether.internal.impl.resolution.TrustedChecksumsArtifactResolverPostProcessor;
 import org.eclipse.aether.internal.impl.synccontext.DefaultSyncContextFactory;
+import org.eclipse.aether.internal.impl.synccontext.named.NamedLockFactoryAdapterFactoryImpl;
 import org.eclipse.aether.internal.impl.synccontext.named.NameMapper;
-import org.eclipse.aether.internal.impl.synccontext.named.NamedLockFactorySelector;
-import org.eclipse.aether.internal.impl.synccontext.named.ParameterizedNamedLockFactorySelector;
+import org.eclipse.aether.internal.impl.synccontext.named.NamedLockFactoryAdapterFactory;
 import org.eclipse.aether.internal.impl.synccontext.named.providers.DiscriminatingNameMapperProvider;
 import org.eclipse.aether.internal.impl.synccontext.named.providers.FileGAVNameMapperProvider;
 import org.eclipse.aether.internal.impl.synccontext.named.providers.FileHashingGAVNameMapperProvider;
@@ -229,7 +229,8 @@ public class AetherModule
         bind( RepositorySystemLifecycle.class )
                 .to( DefaultRepositorySystemLifecycle.class ).in( Singleton.class );
 
-        bind( NamedLockFactorySelector.class ).toInstance( new ParameterizedNamedLockFactorySelector() );
+        bind( NamedLockFactoryAdapterFactory.class )
+                .to( NamedLockFactoryAdapterFactoryImpl.class ).in( Singleton.class );
         bind( SyncContextFactory.class ).to( DefaultSyncContextFactory.class ).in( Singleton.class );
         bind( org.eclipse.aether.impl.SyncContextFactory.class )
                 .to( org.eclipse.aether.internal.impl.synccontext.legacy.DefaultSyncContextFactory.class )
diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/DefaultSyncContextFactory.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/DefaultSyncContextFactory.java
index 9fbc5f66..646e4968 100644
--- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/DefaultSyncContextFactory.java
+++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/DefaultSyncContextFactory.java
@@ -25,10 +25,8 @@ import javax.inject.Singleton;
 
 import org.eclipse.aether.RepositorySystemSession;
 import org.eclipse.aether.SyncContext;
-import org.eclipse.aether.impl.RepositorySystemLifecycle;
 import org.eclipse.aether.internal.impl.synccontext.named.NamedLockFactoryAdapter;
-import org.eclipse.aether.internal.impl.synccontext.named.NamedLockFactorySelector;
-import org.eclipse.aether.internal.impl.synccontext.named.ParameterizedNamedLockFactorySelector;
+import org.eclipse.aether.internal.impl.synccontext.named.NamedLockFactoryAdapterFactory;
 import org.eclipse.aether.spi.locator.Service;
 import org.eclipse.aether.spi.locator.ServiceLocator;
 import org.eclipse.aether.spi.synccontext.SyncContextFactory;
@@ -37,24 +35,26 @@ import static java.util.Objects.requireNonNull;
 
 /**
  * Default {@link SyncContextFactory} implementation that uses named locks.
+ * <p>
+ * The implementation relies fully on {@link NamedLockFactoryAdapterFactory} and all it does is just "stuff" the
+ * adapter instance into session, hence factory is called only when given session has no instance created.
  */
 @Singleton
 @Named
 public final class DefaultSyncContextFactory
         implements SyncContextFactory, Service
 {
-    private NamedLockFactoryAdapter namedLockFactoryAdapter;
+    private static final String ADAPTER_KEY = DefaultSyncContextFactory.class.getName() + ".adapter";
+
+    private NamedLockFactoryAdapterFactory namedLockFactoryAdapterFactory;
 
     /**
      * Constructor used with DI, where factories are injected and selected based on key.
      */
     @Inject
-    public DefaultSyncContextFactory( final RepositorySystemLifecycle repositorySystemLifecycle,
-                                      final NamedLockFactorySelector selector )
+    public DefaultSyncContextFactory( final NamedLockFactoryAdapterFactory namedLockFactoryAdapterFactory )
     {
-        repositorySystemLifecycle.addOnSystemEndedHandler( this::shutDownAdapter );
-        this.namedLockFactoryAdapter =
-                new NamedLockFactoryAdapter( selector.getSelectedNameMapper(), selector.getSelectedNamedLockFactory() );
+        this.namedLockFactoryAdapterFactory = requireNonNull( namedLockFactoryAdapterFactory );
     }
 
     /**
@@ -71,24 +71,16 @@ public final class DefaultSyncContextFactory
     @Override
     public void initService( final ServiceLocator locator )
     {
-        locator.getService( RepositorySystemLifecycle.class ).addOnSystemEndedHandler( this::shutDownAdapter );
-        NamedLockFactorySelector selector = new ParameterizedNamedLockFactorySelector();
-        this.namedLockFactoryAdapter =
-                new NamedLockFactoryAdapter( selector.getSelectedNameMapper(), selector.getSelectedNamedLockFactory() );
+        this.namedLockFactoryAdapterFactory = requireNonNull(
+                locator.getService( NamedLockFactoryAdapterFactory.class ) );
     }
 
     @Override
     public SyncContext newInstance( final RepositorySystemSession session, final boolean shared )
     {
         requireNonNull( session, "session cannot be null" );
-        return namedLockFactoryAdapter.newInstance( session, shared );
-    }
-
-    private void shutDownAdapter()
-    {
-        if ( namedLockFactoryAdapter != null )
-        {
-            namedLockFactoryAdapter.shutdown();
-        }
+        NamedLockFactoryAdapter adapter = (NamedLockFactoryAdapter) session.getData().computeIfAbsent(
+                ADAPTER_KEY, () -> namedLockFactoryAdapterFactory.getAdapter( session ) );
+        return adapter.newInstance( session, shared );
     }
 }
diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/named/NamedLockFactoryAdapter.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/named/NamedLockFactoryAdapter.java
index 07ee8e6d..29f992bf 100644
--- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/named/NamedLockFactoryAdapter.java
+++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/named/NamedLockFactoryAdapter.java
@@ -73,9 +73,20 @@ public final class NamedLockFactoryAdapter
         return new AdaptedLockSyncContext( session, shared, nameMapper, namedLockFactory );
     }
 
-    public void shutdown()
+    /**
+     * @since 1.9.1
+     */
+    public NameMapper getNameMapper()
     {
-        namedLockFactory.shutdown();
+        return nameMapper;
+    }
+
+    /**
+     * @since 1.9.1
+     */
+    public NamedLockFactory getNamedLockFactory()
+    {
+        return namedLockFactory;
     }
 
     public String toString()
diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/named/NamedLockFactorySelector.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/named/NamedLockFactoryAdapterFactory.java
similarity index 58%
rename from maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/named/NamedLockFactorySelector.java
rename to maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/named/NamedLockFactoryAdapterFactory.java
index db9ceefb..195bb9cb 100644
--- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/named/NamedLockFactorySelector.java
+++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/named/NamedLockFactoryAdapterFactory.java
@@ -19,23 +19,21 @@ package org.eclipse.aether.internal.impl.synccontext.named;
  * under the License.
  */
 
-import org.eclipse.aether.named.NamedLockFactory;
+import org.eclipse.aether.RepositorySystemSession;
 
 /**
- * Selector for {@link NamedLockFactory} and {@link NameMapper} that selects and exposes selected ones. Essentially
- * all the named locks configuration is here. Implementations may use different strategies to perform selection.
+ * Factory for {@link NamedLockFactoryAdapter}.
  *
- * @since 1.7.3
+ * @since 1.9.1
  */
-public interface NamedLockFactorySelector
+public interface NamedLockFactoryAdapterFactory
 {
     /**
-     * Returns the selected {@link NamedLockFactory}, never {@code null}.
+     * Creates or returns pre-created {@link NamedLockFactoryAdapter}, never {@code null}.
+     * <p>
+     * It is left at the discretion of the implementation what happens on this method call: it may create always new
+     * instances, or return the same instance. One thing is required for the implementation: to shut down any name
+     * lock factory it used during any invocation of this method.
      */
-    NamedLockFactory getSelectedNamedLockFactory();
-
-    /**
-     * Returns the selected {@link NameMapper}, never {@code null}.
-     */
-    NameMapper getSelectedNameMapper();
+    NamedLockFactoryAdapter getAdapter( RepositorySystemSession session );
 }
\ No newline at end of file
diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/named/NamedLockFactoryAdapterFactoryImpl.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/named/NamedLockFactoryAdapterFactoryImpl.java
new file mode 100644
index 00000000..e558db4d
--- /dev/null
+++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/named/NamedLockFactoryAdapterFactoryImpl.java
@@ -0,0 +1,256 @@
+package org.eclipse.aether.internal.impl.synccontext.named;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.aether.MultiRuntimeException;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.impl.RepositorySystemLifecycle;
+import org.eclipse.aether.internal.impl.synccontext.named.providers.DiscriminatingNameMapperProvider;
+import org.eclipse.aether.internal.impl.synccontext.named.providers.FileGAVNameMapperProvider;
+import org.eclipse.aether.internal.impl.synccontext.named.providers.FileHashingGAVNameMapperProvider;
+import org.eclipse.aether.internal.impl.synccontext.named.providers.GAVNameMapperProvider;
+import org.eclipse.aether.internal.impl.synccontext.named.providers.StaticNameMapperProvider;
+import org.eclipse.aether.named.NamedLockFactory;
+import org.eclipse.aether.named.providers.FileLockNamedLockFactory;
+import org.eclipse.aether.named.providers.LocalReadWriteLockNamedLockFactory;
+import org.eclipse.aether.named.providers.LocalSemaphoreNamedLockFactory;
+import org.eclipse.aether.named.providers.NoopNamedLockFactory;
+import org.eclipse.aether.spi.locator.Service;
+import org.eclipse.aether.spi.locator.ServiceLocator;
+import org.eclipse.aether.util.ConfigUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static java.util.Objects.requireNonNull;
+
+/**
+ * Default implementation of {@link NamedLockFactoryAdapterFactory}. This implementation creates new instances of the
+ * adapter on every call. In turn, on shutdown, it will shut down all existing named lock factories. This is merely for
+ * simplicity, to not have to track "used" named lock factories, while it exposes all available named lock factories to
+ * callers.
+ * <p>
+ * Most members and methods of this class are protected. It is meant to be extended in case of need to customize its
+ * behavior. An exception from this are private static methods, mostly meant to provide out of the box
+ * defaults and to be used when no Eclipse Sisu component container is used.
+ *
+ * @since 1.9.1
+ */
+@Singleton
+@Named
+public class NamedLockFactoryAdapterFactoryImpl implements NamedLockFactoryAdapterFactory, Service
+{
+    private static final String DEFAULT_FACTORY_NAME = LocalReadWriteLockNamedLockFactory.NAME;
+
+    private static final String DEFAULT_NAME_MAPPER_NAME = GAVNameMapperProvider.NAME;
+
+    private static Map<String, NamedLockFactory> getManuallyCreatedFactories()
+    {
+        HashMap<String, NamedLockFactory> factories = new HashMap<>();
+        factories.put( NoopNamedLockFactory.NAME, new NoopNamedLockFactory() );
+        factories.put( LocalReadWriteLockNamedLockFactory.NAME, new LocalReadWriteLockNamedLockFactory() );
+        factories.put( LocalSemaphoreNamedLockFactory.NAME, new LocalSemaphoreNamedLockFactory() );
+        factories.put( FileLockNamedLockFactory.NAME, new FileLockNamedLockFactory() );
+        return Collections.unmodifiableMap( factories );
+    }
+
+    private static Map<String, NameMapper> getManuallyCreatedNameMappers()
+    {
+        HashMap<String, NameMapper> mappers = new HashMap<>();
+        mappers.put( StaticNameMapperProvider.NAME, new StaticNameMapperProvider().get() );
+        mappers.put( GAVNameMapperProvider.NAME, new GAVNameMapperProvider().get() );
+        mappers.put( DiscriminatingNameMapperProvider.NAME, new DiscriminatingNameMapperProvider().get() );
+        mappers.put( FileGAVNameMapperProvider.NAME, new FileGAVNameMapperProvider().get() );
+        mappers.put( FileHashingGAVNameMapperProvider.NAME, new FileHashingGAVNameMapperProvider().get() );
+        return Collections.unmodifiableMap( mappers );
+    }
+
+    protected static final String FACTORY_KEY = "aether.syncContext.named.factory";
+
+    protected static final String NAME_MAPPER_KEY = "aether.syncContext.named.nameMapper";
+
+    protected final Logger logger = LoggerFactory.getLogger( getClass() );
+
+    protected final Map<String, NamedLockFactory> factories;
+
+    protected final String defaultFactoryName;
+
+    protected final Map<String, NameMapper> nameMappers;
+
+    protected final String defaultNameMapperName;
+
+    /**
+     * Default constructor for non Eclipse Sisu uses.
+     *
+     * @deprecated for use in SL only.
+     */
+    @Deprecated
+    public NamedLockFactoryAdapterFactoryImpl()
+    {
+        this.factories = getManuallyCreatedFactories();
+        this.defaultFactoryName = DEFAULT_FACTORY_NAME;
+        this.nameMappers = getManuallyCreatedNameMappers();
+        this.defaultNameMapperName = DEFAULT_NAME_MAPPER_NAME;
+    }
+
+    @Override
+    public void initService( ServiceLocator locator )
+    {
+        locator.getService( RepositorySystemLifecycle.class ).addOnSystemEndedHandler( this::shutdown );
+    }
+
+    @Inject
+    public NamedLockFactoryAdapterFactoryImpl( final Map<String, NamedLockFactory> factories,
+                                               final Map<String, NameMapper> nameMappers,
+                                               final RepositorySystemLifecycle lifecycle )
+    {
+        this( factories, DEFAULT_FACTORY_NAME, nameMappers, DEFAULT_NAME_MAPPER_NAME, lifecycle );
+    }
+
+    public NamedLockFactoryAdapterFactoryImpl( final Map<String, NamedLockFactory> factories,
+                                               final String defaultFactoryName,
+                                               final Map<String, NameMapper> nameMappers,
+                                               final String defaultNameMapperName,
+                                               final RepositorySystemLifecycle lifecycle )
+    {
+        this.factories = requireNonNull( factories );
+        this.defaultFactoryName = requireNonNull( defaultFactoryName );
+        this.nameMappers = requireNonNull( nameMappers );
+        this.defaultNameMapperName = requireNonNull( defaultNameMapperName );
+        lifecycle.addOnSystemEndedHandler( this::shutdown );
+
+        logger.debug( "Created adapter factory; available factories {}; available name mappers {}",
+                factories.keySet(), nameMappers.keySet() );
+    }
+
+    /**
+     * Current implementation simply delegates to {@link #createAdapter(RepositorySystemSession)}.
+     */
+    @Override
+    public NamedLockFactoryAdapter getAdapter( RepositorySystemSession session )
+    {
+        return createAdapter( session );
+    }
+
+    /**
+     * Creates a new adapter instance, never returns {@code null}.
+     */
+    protected NamedLockFactoryAdapter createAdapter( RepositorySystemSession session )
+    {
+        final String nameMapperName = requireNonNull( getNameMapperName( session ) );
+        final String factoryName = requireNonNull( getFactoryName( session ) );
+        final NameMapper nameMapper = selectNameMapper( nameMapperName );
+        final NamedLockFactory factory = selectFactory( factoryName );
+        logger.debug( "Creating adapter using nameMapper '{}' and factory '{}'",
+                nameMapperName, factoryName );
+        return new NamedLockFactoryAdapter( nameMapper, factory );
+    }
+
+    /**
+     * Returns the selected (user configured or default) named lock factory name, never {@code null}.
+     */
+    protected String getFactoryName( RepositorySystemSession session )
+    {
+        return ConfigUtils.getString( session, getDefaultFactoryName(), FACTORY_KEY );
+    }
+
+    /**
+     * Returns the default named lock factory name, never {@code null}.
+     */
+    protected String getDefaultFactoryName()
+    {
+        return defaultFactoryName;
+    }
+
+    /**
+     * Returns the selected (user configured or default) name mapper name, never {@code null}.
+     */
+    protected String getNameMapperName( RepositorySystemSession session )
+    {
+        return ConfigUtils.getString( session, getDefaultNameMapperName(), NAME_MAPPER_KEY );
+    }
+
+    /**
+     * Returns the default name mapper name, never {@code null}.
+     */
+    protected String getDefaultNameMapperName()
+    {
+        return defaultNameMapperName;
+    }
+
+    /**
+     * Selects a named lock factory, never returns {@code null}.
+     */
+    protected NamedLockFactory selectFactory( final String factoryName )
+    {
+        NamedLockFactory factory = factories.get( factoryName );
+        if ( factory == null )
+        {
+            throw new IllegalArgumentException(
+                    "Unknown NamedLockFactory name: '" + factoryName + "', known ones: " + factories.keySet() );
+        }
+        return factory;
+    }
+
+    /**
+     * Selects a name mapper, never returns {@code null}.
+     */
+    protected NameMapper selectNameMapper( final String nameMapperName )
+    {
+        NameMapper nameMapper = nameMappers.get( nameMapperName );
+        if ( nameMapper == null )
+        {
+            throw new IllegalArgumentException(
+                    "Unknown NameMapper name: '" + nameMapperName + "', known ones: " + nameMappers.keySet() );
+        }
+        return nameMapper;
+    }
+
+    /**
+     * To be invoked on repository system shut down. This method will shut down each {@link NamedLockFactory}.
+     */
+    protected void shutdown()
+    {
+        logger.debug( "Shutting down adapter factory; available factories {}; available name mappers {}",
+                factories.keySet(), nameMappers.keySet() );
+        ArrayList<Exception> exceptions = new ArrayList<>();
+        for ( Map.Entry<String, NamedLockFactory> entry : factories.entrySet() )
+        {
+            try
+            {
+                logger.debug( "Shutting down '{}' factory", entry.getKey() );
+                entry.getValue().shutdown();
+            }
+            catch ( Exception e )
+            {
+                exceptions.add( e );
+            }
+        }
+        MultiRuntimeException.mayThrow( "Problem shutting down factories", exceptions );
+    }
+}
\ No newline at end of file
diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/named/ParameterizedNamedLockFactorySelector.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/named/ParameterizedNamedLockFactorySelector.java
deleted file mode 100644
index 9d13fa14..00000000
--- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/named/ParameterizedNamedLockFactorySelector.java
+++ /dev/null
@@ -1,147 +0,0 @@
-package org.eclipse.aether.internal.impl.synccontext.named;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import javax.inject.Inject;
-import javax.inject.Named;
-import javax.inject.Singleton;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.eclipse.aether.internal.impl.synccontext.named.providers.DiscriminatingNameMapperProvider;
-import org.eclipse.aether.internal.impl.synccontext.named.providers.FileGAVNameMapperProvider;
-import org.eclipse.aether.internal.impl.synccontext.named.providers.FileHashingGAVNameMapperProvider;
-import org.eclipse.aether.internal.impl.synccontext.named.providers.GAVNameMapperProvider;
-import org.eclipse.aether.internal.impl.synccontext.named.providers.StaticNameMapperProvider;
-import org.eclipse.aether.named.NamedLockFactory;
-import org.eclipse.aether.named.providers.FileLockNamedLockFactory;
-import org.eclipse.aether.named.providers.LocalReadWriteLockNamedLockFactory;
-import org.eclipse.aether.named.providers.LocalSemaphoreNamedLockFactory;
-import org.eclipse.aether.named.providers.NoopNamedLockFactory;
-
-/**
- * Parameterized selector implementation that selects based on injected parameters.
- *
- * @since 1.9.0
- */
-@Singleton
-@Named
-public final class ParameterizedNamedLockFactorySelector
-        implements NamedLockFactorySelector
-{
-    private static final String FACTORY_KEY = "aether.syncContext.named.factory";
-
-    private static final String NAME_MAPPER_KEY = "aether.syncContext.named.nameMapper";
-
-    private static final Map<String, NamedLockFactory> FACTORIES;
-
-    private static final String DEFAULT_FACTORY = LocalReadWriteLockNamedLockFactory.NAME;
-
-    private static final Map<String, NameMapper> NAME_MAPPERS;
-
-    private static final String DEFAULT_NAME_MAPPER = GAVNameMapperProvider.NAME;
-
-    static
-    {
-        HashMap<String, NamedLockFactory> factories = new HashMap<>();
-        factories.put( NoopNamedLockFactory.NAME, new NoopNamedLockFactory() );
-        factories.put( LocalReadWriteLockNamedLockFactory.NAME, new LocalReadWriteLockNamedLockFactory() );
-        factories.put( LocalSemaphoreNamedLockFactory.NAME, new LocalSemaphoreNamedLockFactory() );
-        factories.put( FileLockNamedLockFactory.NAME, new FileLockNamedLockFactory() );
-        FACTORIES = factories;
-
-        HashMap<String, NameMapper> mappers = new HashMap<>();
-        mappers.put( StaticNameMapperProvider.NAME, new StaticNameMapperProvider().get() );
-        mappers.put( GAVNameMapperProvider.NAME, new GAVNameMapperProvider().get() );
-        mappers.put( DiscriminatingNameMapperProvider.NAME, new DiscriminatingNameMapperProvider().get() );
-        mappers.put( FileGAVNameMapperProvider.NAME, new FileGAVNameMapperProvider().get() );
-        mappers.put( FileHashingGAVNameMapperProvider.NAME, new FileHashingGAVNameMapperProvider().get() );
-        NAME_MAPPERS = mappers;
-    }
-
-    private final NamedLockFactory namedLockFactory;
-
-    private final NameMapper nameMapper;
-
-    /**
-     * Default constructor for non Eclipse Sisu uses.
-     */
-    public ParameterizedNamedLockFactorySelector()
-    {
-        this( FACTORIES, DEFAULT_FACTORY, NAME_MAPPERS, DEFAULT_NAME_MAPPER );
-    }
-
-    /**
-     * Constructor that uses Eclipse Sisu parameter injection.
-     */
-    @SuppressWarnings( "checkstyle:LineLength" )
-    @Inject
-    public ParameterizedNamedLockFactorySelector( final Map<String, NamedLockFactory> factories,
-                                                  @Named( "${" + FACTORY_KEY + ":-" + DEFAULT_FACTORY + "}" ) final String selectedFactoryName,
-                                                  final Map<String, NameMapper> nameMappers,
-                                                  @Named( "${" + NAME_MAPPER_KEY + ":-" + DEFAULT_NAME_MAPPER + "}" ) final String selectedMapperName )
-    {
-        this.namedLockFactory = selectNamedLockFactory( factories, selectedFactoryName );
-        this.nameMapper = selectNameMapper( nameMappers, selectedMapperName );
-    }
-
-    /**
-     * Returns the selected {@link NamedLockFactory}, never null.
-     */
-    @Override
-    public NamedLockFactory getSelectedNamedLockFactory()
-    {
-        return namedLockFactory;
-    }
-
-    /**
-     * Returns the selected {@link NameMapper}, never null.
-     */
-    @Override
-    public NameMapper getSelectedNameMapper()
-    {
-        return nameMapper;
-    }
-
-    private static NamedLockFactory selectNamedLockFactory( final Map<String, NamedLockFactory> factories,
-                                                     final String factoryName )
-    {
-        NamedLockFactory factory = factories.get( factoryName );
-        if ( factory == null )
-        {
-            throw new IllegalArgumentException( "Unknown NamedLockFactory name: " + factoryName
-                    + ", known ones: " + factories.keySet() );
-        }
-        return factory;
-    }
-
-    private static NameMapper selectNameMapper( final Map<String, NameMapper> nameMappers,
-                                         final String nameMapperName )
-    {
-        NameMapper nameMapper = nameMappers.get( nameMapperName );
-        if ( nameMapper == null )
-        {
-            throw new IllegalArgumentException( "Unknown NameMapper name: " + nameMapperName
-                    + ", known ones: " + nameMappers.keySet() );
-        }
-        return nameMapper;
-    }
-}
\ No newline at end of file
diff --git a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/synccontext/NamedLockFactoryAdapterTestSupport.java b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/synccontext/NamedLockFactoryAdapterTestSupport.java
index 9deadba8..9b87e2cc 100644
--- a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/synccontext/NamedLockFactoryAdapterTestSupport.java
+++ b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/synccontext/NamedLockFactoryAdapterTestSupport.java
@@ -77,7 +77,7 @@ public abstract class NamedLockFactoryAdapterTestSupport
     @AfterClass
     public static void cleanupAdapter() {
         if (adapter != null) {
-            adapter.shutdown();
+            adapter.getNamedLockFactory().shutdown();
         }
     }
 
diff --git a/maven-resolver-named-locks-hazelcast/src/test/java/org/eclipse/aether/named/hazelcast/NamedLockFactoryAdapterTestSupport.java b/maven-resolver-named-locks-hazelcast/src/test/java/org/eclipse/aether/named/hazelcast/NamedLockFactoryAdapterTestSupport.java
index 86a55ae9..1450604c 100644
--- a/maven-resolver-named-locks-hazelcast/src/test/java/org/eclipse/aether/named/hazelcast/NamedLockFactoryAdapterTestSupport.java
+++ b/maven-resolver-named-locks-hazelcast/src/test/java/org/eclipse/aether/named/hazelcast/NamedLockFactoryAdapterTestSupport.java
@@ -75,7 +75,7 @@ public abstract class NamedLockFactoryAdapterTestSupport
     {
         if ( adapter != null )
         {
-            adapter.shutdown();
+            adapter.getNamedLockFactory().shutdown();
         }
 
         utils.cleanup();
diff --git a/maven-resolver-transport-http/src/main/java/org/eclipse/aether/transport/http/HttpTransporterFactory.java b/maven-resolver-transport-http/src/main/java/org/eclipse/aether/transport/http/HttpTransporterFactory.java
index 0143035a..a38ed686 100644
--- a/maven-resolver-transport-http/src/main/java/org/eclipse/aether/transport/http/HttpTransporterFactory.java
+++ b/maven-resolver-transport-http/src/main/java/org/eclipse/aether/transport/http/HttpTransporterFactory.java
@@ -42,14 +42,12 @@ import static java.util.Objects.requireNonNull;
 public final class HttpTransporterFactory
     implements TransporterFactory
 {
-    private static final Map<String, ChecksumExtractor> EXTRACTORS;
-
-    static
+    private static Map<String, ChecksumExtractor> getManuallyCreatedExtractors()
     {
         HashMap<String, ChecksumExtractor> map = new HashMap<>();
         map.put( Nexus2ChecksumExtractor.NAME, new Nexus2ChecksumExtractor() );
         map.put( XChecksumChecksumExtractor.NAME, new XChecksumChecksumExtractor() );
-        EXTRACTORS = Collections.unmodifiableMap( map );
+        return Collections.unmodifiableMap( map );
     }
 
     private float priority = 5.0f;
@@ -62,7 +60,7 @@ public final class HttpTransporterFactory
     @Deprecated
     public HttpTransporterFactory()
     {
-        this( EXTRACTORS );
+        this( getManuallyCreatedExtractors() );
     }
 
     /**