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;