Pass config to ContextClassLoaderFactory (#3400)

* Added a context class loader environment that supplies configuration
* Improve javadoc comments on environment interface

This fixes #3399 

Co-authored-by: Christopher Tubbs <ctubbsii@apache.org>
Co-authored-by: Keith Turner <kturner@apache.org>
diff --git a/core/src/main/java/org/apache/accumulo/core/classloader/ClassLoaderUtil.java b/core/src/main/java/org/apache/accumulo/core/classloader/ClassLoaderUtil.java
index 47e7ef5..3a5d0eb 100644
--- a/core/src/main/java/org/apache/accumulo/core/classloader/ClassLoaderUtil.java
+++ b/core/src/main/java/org/apache/accumulo/core/classloader/ClassLoaderUtil.java
@@ -21,6 +21,7 @@
 import org.apache.accumulo.core.conf.AccumuloConfiguration;
 import org.apache.accumulo.core.conf.Property;
 import org.apache.accumulo.core.spi.common.ContextClassLoaderFactory;
+import org.apache.accumulo.core.util.ConfigurationImpl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -46,11 +47,12 @@
             ContextClassLoaderFactory.class.getName());
         FACTORY = new DefaultContextClassLoaderFactory(conf);
       } else {
-        // load user's selected implementation
+        // load user's selected implementation and provide it with the service environment
         try {
           var factoryClass = Class.forName(factoryName).asSubclass(ContextClassLoaderFactory.class);
           LOG.info("Creating {}: {}", ContextClassLoaderFactory.class.getName(), factoryName);
           FACTORY = factoryClass.getDeclaredConstructor().newInstance();
+          FACTORY.init(() -> new ConfigurationImpl(conf));
         } catch (ReflectiveOperationException e) {
           throw new IllegalStateException("Unable to load and initialize class: " + factoryName, e);
         }
diff --git a/core/src/main/java/org/apache/accumulo/core/spi/common/ContextClassLoaderEnvironment.java b/core/src/main/java/org/apache/accumulo/core/spi/common/ContextClassLoaderEnvironment.java
new file mode 100644
index 0000000..328165a
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/spi/common/ContextClassLoaderEnvironment.java
@@ -0,0 +1,34 @@
+/*
+ * 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
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.accumulo.core.spi.common;
+
+/**
+ * The environment provided to the context class loader factory for its use
+ *
+ * @since 2.1.1
+ */
+public interface ContextClassLoaderEnvironment {
+
+  /**
+   * Get the service environment configuration
+   *
+   * @return The configuration
+   */
+  ServiceEnvironment.Configuration getConfiguration();
+}
diff --git a/core/src/main/java/org/apache/accumulo/core/spi/common/ContextClassLoaderFactory.java b/core/src/main/java/org/apache/accumulo/core/spi/common/ContextClassLoaderFactory.java
index e099049..7f423f3 100644
--- a/core/src/main/java/org/apache/accumulo/core/spi/common/ContextClassLoaderFactory.java
+++ b/core/src/main/java/org/apache/accumulo/core/spi/common/ContextClassLoaderFactory.java
@@ -39,13 +39,22 @@
  * <p>
  * Because this factory is expected to be instantiated early in the application startup process,
  * configuration is expected to be provided within the environment (such as in Java system
- * properties or process environment variables), and is implementation-specific.
+ * properties or process environment variables), and is implementation-specific. However, some
+ * limited environment is also available so implementations can have access to Accumulo's own system
+ * configuration.
  *
  * @since 2.1.0
  */
 public interface ContextClassLoaderFactory {
 
   /**
+   * Pass the service environment to allow for additional class loader configuration
+   *
+   * @param env the class loader environment
+   */
+  default void init(ContextClassLoaderEnvironment env) {}
+
+  /**
    * Get the class loader for the given contextName. Callers should not cache the ClassLoader result
    * as it may change if/when the ClassLoader reloads. Implementations should throw a
    * RuntimeException of some type (such as IllegalArgumentException) if the provided contextName is
@@ -56,5 +65,4 @@
    * @return the class loader for the given contextName
    */
   ClassLoader getClassLoader(String contextName);
-
 }
diff --git a/core/src/main/java/org/apache/accumulo/core/util/ConfigurationImpl.java b/core/src/main/java/org/apache/accumulo/core/util/ConfigurationImpl.java
index 72be9ac..6bb2015 100644
--- a/core/src/main/java/org/apache/accumulo/core/util/ConfigurationImpl.java
+++ b/core/src/main/java/org/apache/accumulo/core/util/ConfigurationImpl.java
@@ -32,6 +32,9 @@
 import org.apache.accumulo.core.conf.PropertyType;
 import org.apache.accumulo.core.spi.common.ServiceEnvironment.Configuration;
 
+/**
+ * The implementation class used for providing SPI configuration without exposing internal types.
+ */
 public class ConfigurationImpl implements Configuration {
 
   private final AccumuloConfiguration acfg;