From daad9569a7487bbc1acab5ba96211d0bedf8a11c Mon Sep 17 00:00:00 2001 From: leventov Date: Tue, 20 Jun 2017 23:07:24 -0500 Subject: [PATCH 1/6] Add ExtensionsConfig.excludeModules --- docs/content/configuration/index.md | 1 + .../main/java/io/druid/guice/ExtensionsConfig.java | 14 ++++++++++++++ .../io/druid/initialization/Initialization.java | 2 ++ 3 files changed, 17 insertions(+) diff --git a/docs/content/configuration/index.md b/docs/content/configuration/index.md index 4a259b1d5500..d92fcc16137c 100644 --- a/docs/content/configuration/index.md +++ b/docs/content/configuration/index.md @@ -24,6 +24,7 @@ Many of Druid's external dependencies can be plugged in as modules. Extensions c |`druid.extensions.directory`|The root extension directory where user can put extensions related files. Druid will load extensions stored under this directory.|`extensions` (This is a relative path to Druid's working directory)| |`druid.extensions.hadoopDependenciesDir`|The root hadoop dependencies directory where user can put hadoop related dependencies files. Druid will load the dependencies based on the hadoop coordinate specified in the hadoop index task.|`hadoop-dependencies` (This is a relative path to Druid's working directory| |`druid.extensions.loadList`|A JSON array of extensions to load from extension directories by Druid. If it is not specified, its value will be `null` and Druid will load all the extensions under `druid.extensions.directory`. If its value is empty list `[]`, then no extensions will be loaded at all. It is also allowed to specify absolute path of other custom extensions not stored in the common extensions directory.|null| +|`druid.extensions.excludeModules`|A JSON array of canonical class names (e. g. `"io.druid.somepackage.SomeClass"`) of modules, which shouldn't be loaded, despite they are found in the `loadList`. Useful when some useful extension contains some module, which shouldn't be loaded on some Druid node type because of some dependencies of that module couldn't be satisfied.|[]| |`druid.extensions.searchCurrentClassloader`|This is a boolean flag that determines if Druid will search the main classloader for extensions. It defaults to true but can be turned off if you have reason to not automatically add all modules on the classpath.|true| |`druid.extensions.hadoopContainerDruidClasspath`|Hadoop Indexing launches hadoop jobs and this configuration provides way to explicitly set the user classpath for the hadoop job. By default this is computed automatically by druid based on the druid process classpath and set of extensions. However, sometimes you might want to be explicit to resolve dependency conflicts between druid and hadoop.|null| |`druid.extensions.addExtensionsToHadoopContainer`|Only applicable if `druid.extensions.hadoopContainerDruidClasspath` is provided. If set to true, then extensions specified in the loadList are added to hadoop container classpath. Note that when `druid.extensions.hadoopContainerDruidClasspath` is not provided then extensions are always added to hadoop container classpath.|false| diff --git a/processing/src/main/java/io/druid/guice/ExtensionsConfig.java b/processing/src/main/java/io/druid/guice/ExtensionsConfig.java index e04e612a53d5..74ceb7a7403c 100644 --- a/processing/src/main/java/io/druid/guice/ExtensionsConfig.java +++ b/processing/src/main/java/io/druid/guice/ExtensionsConfig.java @@ -22,6 +22,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import javax.validation.constraints.NotNull; +import java.util.Collections; import java.util.List; /** @@ -48,6 +49,13 @@ public class ExtensionsConfig @JsonProperty private List loadList; + /** + * Canonical class names of modules, which should not be loaded despite they are founded in extensions from {@link + * #loadList}. + */ + @JsonProperty + private List excludeModules = Collections.emptyList(); + public boolean searchCurrentClassloader() { return searchCurrentClassloader; @@ -78,6 +86,11 @@ public List getLoadList() return loadList; } + public List getExcludeModules() + { + return excludeModules; + } + @Override public String toString() { @@ -88,6 +101,7 @@ public String toString() ", hadoopContainerDruidClasspath='" + hadoopContainerDruidClasspath + '\'' + ", addExtensionsToHadoopContainer=" + addExtensionsToHadoopContainer + ", loadList=" + loadList + + ", excludeModules=" + excludeModules + '}'; } } diff --git a/server/src/main/java/io/druid/initialization/Initialization.java b/server/src/main/java/io/druid/initialization/Initialization.java index d525391ac4d5..67a4cada44fd 100644 --- a/server/src/main/java/io/druid/initialization/Initialization.java +++ b/server/src/main/java/io/druid/initialization/Initialization.java @@ -142,6 +142,8 @@ public synchronized static Collection getFromExtensions(ExtensionsConfig "Extension module [%s] was ignored because it doesn't have a canonical name, is it a local or anonymous class?", module.getClass().getName() ); + } else if (config.getExcludeModules().contains(moduleName)) { + log.info("Not loading module [%s] because it is present in excludeModules config", moduleName); } else if (!loadedExtensionNames.contains(moduleName)) { log.info("Adding classpath extension module [%s] for class [%s]", moduleName, clazz.getName()); loadedExtensionNames.add(moduleName); From cd8d41b01846362e805ffeae478b6af91cfe9712 Mon Sep 17 00:00:00 2001 From: leventov Date: Wed, 21 Jun 2017 13:53:03 -0500 Subject: [PATCH 2/6] Add branch --- .../src/main/java/io/druid/initialization/Initialization.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/src/main/java/io/druid/initialization/Initialization.java b/server/src/main/java/io/druid/initialization/Initialization.java index 67a4cada44fd..7f4a81f7130a 100644 --- a/server/src/main/java/io/druid/initialization/Initialization.java +++ b/server/src/main/java/io/druid/initialization/Initialization.java @@ -163,6 +163,8 @@ public synchronized static Collection getFromExtensions(ExtensionsConfig "Extension module [%s] was ignored because it doesn't have a canonical name, is it a local or anonymous class?", module.getClass().getName() ); + } else if (config.getExcludeModules().contains(moduleName)) { + log.info("Not loading module [%s] because it is present in excludeModules config", moduleName); } else if (!loadedExtensionNames.contains(moduleName)) { log.info("Adding local file system extension module [%s] for class [%s]", moduleName, clazz.getName()); loadedExtensionNames.add(moduleName); From 1c7903f5198fe42e24bd78d0f7e0d5964a734265 Mon Sep 17 00:00:00 2001 From: leventov Date: Tue, 27 Jun 2017 15:12:04 -0500 Subject: [PATCH 3/6] Refactor Initialization.getFromExtensions() --- .../druid/initialization/Initialization.java | 104 ++++++++++-------- 1 file changed, 60 insertions(+), 44 deletions(-) diff --git a/server/src/main/java/io/druid/initialization/Initialization.java b/server/src/main/java/io/druid/initialization/Initialization.java index 7f4a81f7130a..a467c7ce872e 100644 --- a/server/src/main/java/io/druid/initialization/Initialization.java +++ b/server/src/main/java/io/druid/initialization/Initialization.java @@ -76,6 +76,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.ServiceLoader; @@ -127,60 +128,75 @@ static Map getLoadersMap() * @param config Extensions configuration * @param clazz The class of extension module (e.g., DruidModule) * - * @return A collection that contains distinct extension modules + * @return A set that contains distinct extension modules */ - public synchronized static Collection getFromExtensions(ExtensionsConfig config, Class clazz) + public synchronized static Set getFromExtensions(ExtensionsConfig config, Class serviceClass) { - final Set retVal = Sets.newHashSet(); - final Set loadedExtensionNames = Sets.newHashSet(); + Set modulesToLoad = new ServiceLoadingFromExtensions(config, serviceClass).implsToLoad; + extensionsMap.put(serviceClass, modulesToLoad); + return modulesToLoad; + } - if (config.searchCurrentClassloader()) { - for (T module : ServiceLoader.load(clazz, Thread.currentThread().getContextClassLoader())) { - final String moduleName = module.getClass().getCanonicalName(); - if (moduleName == null) { - log.warn( - "Extension module [%s] was ignored because it doesn't have a canonical name, is it a local or anonymous class?", - module.getClass().getName() - ); - } else if (config.getExcludeModules().contains(moduleName)) { - log.info("Not loading module [%s] because it is present in excludeModules config", moduleName); - } else if (!loadedExtensionNames.contains(moduleName)) { - log.info("Adding classpath extension module [%s] for class [%s]", moduleName, clazz.getName()); - loadedExtensionNames.add(moduleName); - retVal.add(module); - } + private static class ServiceLoadingFromExtensions + { + private final ExtensionsConfig extensionsConfig; + private final Class serviceClass; + private final Set implsToLoad = new HashSet<>(); + private final Set implClassNamesToLoad = new HashSet<>(); + + private ServiceLoadingFromExtensions(ExtensionsConfig extensionsConfig, Class serviceClass) + { + this.extensionsConfig = extensionsConfig; + this.serviceClass = serviceClass; + if (extensionsConfig.searchCurrentClassloader()) { + addAllFromCurrentClassLoader(); } + addAllFromFileSystem(); } - for (File extension : getExtensionFilesToLoad(config)) { - log.info("Loading extension [%s] for class [%s]", extension.getName(), clazz.getName()); - try { - final URLClassLoader loader = getClassLoaderForExtension(extension); - for (T module : ServiceLoader.load(clazz, loader)) { - final String moduleName = module.getClass().getCanonicalName(); - if (moduleName == null) { - log.warn( - "Extension module [%s] was ignored because it doesn't have a canonical name, is it a local or anonymous class?", - module.getClass().getName() - ); - } else if (config.getExcludeModules().contains(moduleName)) { - log.info("Not loading module [%s] because it is present in excludeModules config", moduleName); - } else if (!loadedExtensionNames.contains(moduleName)) { - log.info("Adding local file system extension module [%s] for class [%s]", moduleName, clazz.getName()); - loadedExtensionNames.add(moduleName); - retVal.add(module); - } + private void addAllFromCurrentClassLoader() + { + ServiceLoader + .load(serviceClass, Thread.currentThread().getContextClassLoader()) + .forEach(impl -> tryAdd(impl, "classpath")); + } + + private void addAllFromFileSystem() + { + for (File extension : getExtensionFilesToLoad(extensionsConfig)) { + log.info("Loading extension [%s] for class [%s]", extension.getName(), serviceClass); + try { + final URLClassLoader loader = getClassLoaderForExtension(extension); + ServiceLoader.load(serviceClass, loader).forEach(impl -> tryAdd(impl, "local file system")); + } + catch (Exception e) { + throw Throwables.propagate(e); } - } - catch (Exception e) { - throw Throwables.propagate(e); } } - // update the map with currently loaded modules - extensionsMap.put(clazz, retVal); - - return retVal; + private void tryAdd(T serviceImpl, String extensionType) + { + final String serviceImplName = serviceImpl.getClass().getCanonicalName(); + if (serviceImplName == null) { + log.warn( + "Implementation [%s] was ignored because it doesn't have a canonical name, " + + "is it a local or anonymous class?", + serviceImpl.getClass().getName() + ); + } else if (extensionsConfig.getExcludeModules().contains(serviceImplName)) { + log.info("Not loading module [%s] because it is present in excludeModules config", serviceImplName); + } else if (!implClassNamesToLoad.contains(serviceImplName)) { + log.info( + "Adding implementation [%s] for class [%s] from %s extension", + serviceImplName, + serviceClass, + extensionType + ); + implClassNamesToLoad.add(serviceImplName); + implsToLoad.add(serviceImpl); + } + } } /** From 9885bc9dfd7911a97071dac5d04202900b43bd0e Mon Sep 17 00:00:00 2001 From: leventov Date: Wed, 28 Jun 2017 12:23:38 -0500 Subject: [PATCH 4/6] excludeModules -> moduleExcludeList --- docs/content/configuration/index.md | 2 +- .../src/main/java/io/druid/guice/ExtensionsConfig.java | 8 ++++---- .../main/java/io/druid/initialization/Initialization.java | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/content/configuration/index.md b/docs/content/configuration/index.md index d92fcc16137c..838f8f3b2d85 100644 --- a/docs/content/configuration/index.md +++ b/docs/content/configuration/index.md @@ -24,7 +24,7 @@ Many of Druid's external dependencies can be plugged in as modules. Extensions c |`druid.extensions.directory`|The root extension directory where user can put extensions related files. Druid will load extensions stored under this directory.|`extensions` (This is a relative path to Druid's working directory)| |`druid.extensions.hadoopDependenciesDir`|The root hadoop dependencies directory where user can put hadoop related dependencies files. Druid will load the dependencies based on the hadoop coordinate specified in the hadoop index task.|`hadoop-dependencies` (This is a relative path to Druid's working directory| |`druid.extensions.loadList`|A JSON array of extensions to load from extension directories by Druid. If it is not specified, its value will be `null` and Druid will load all the extensions under `druid.extensions.directory`. If its value is empty list `[]`, then no extensions will be loaded at all. It is also allowed to specify absolute path of other custom extensions not stored in the common extensions directory.|null| -|`druid.extensions.excludeModules`|A JSON array of canonical class names (e. g. `"io.druid.somepackage.SomeClass"`) of modules, which shouldn't be loaded, despite they are found in the `loadList`. Useful when some useful extension contains some module, which shouldn't be loaded on some Druid node type because of some dependencies of that module couldn't be satisfied.|[]| +|`druid.extensions.moduleExcludeList`|A JSON array of canonical class names (e. g. `"io.druid.somepackage.SomeClass"`) of modules, which shouldn't be loaded, despite they are found in the `loadList`. Useful when some useful extension contains some module, which shouldn't be loaded on some Druid node type because of some dependencies of that module couldn't be satisfied.|[]| |`druid.extensions.searchCurrentClassloader`|This is a boolean flag that determines if Druid will search the main classloader for extensions. It defaults to true but can be turned off if you have reason to not automatically add all modules on the classpath.|true| |`druid.extensions.hadoopContainerDruidClasspath`|Hadoop Indexing launches hadoop jobs and this configuration provides way to explicitly set the user classpath for the hadoop job. By default this is computed automatically by druid based on the druid process classpath and set of extensions. However, sometimes you might want to be explicit to resolve dependency conflicts between druid and hadoop.|null| |`druid.extensions.addExtensionsToHadoopContainer`|Only applicable if `druid.extensions.hadoopContainerDruidClasspath` is provided. If set to true, then extensions specified in the loadList are added to hadoop container classpath. Note that when `druid.extensions.hadoopContainerDruidClasspath` is not provided then extensions are always added to hadoop container classpath.|false| diff --git a/processing/src/main/java/io/druid/guice/ExtensionsConfig.java b/processing/src/main/java/io/druid/guice/ExtensionsConfig.java index 74ceb7a7403c..e0f2b9fd06a5 100644 --- a/processing/src/main/java/io/druid/guice/ExtensionsConfig.java +++ b/processing/src/main/java/io/druid/guice/ExtensionsConfig.java @@ -54,7 +54,7 @@ public class ExtensionsConfig * #loadList}. */ @JsonProperty - private List excludeModules = Collections.emptyList(); + private List moduleExcludeList = Collections.emptyList(); public boolean searchCurrentClassloader() { @@ -86,9 +86,9 @@ public List getLoadList() return loadList; } - public List getExcludeModules() + public List getModuleExcludeList() { - return excludeModules; + return moduleExcludeList; } @Override @@ -101,7 +101,7 @@ public String toString() ", hadoopContainerDruidClasspath='" + hadoopContainerDruidClasspath + '\'' + ", addExtensionsToHadoopContainer=" + addExtensionsToHadoopContainer + ", loadList=" + loadList + - ", excludeModules=" + excludeModules + + ", moduleExcludeList=" + moduleExcludeList + '}'; } } diff --git a/server/src/main/java/io/druid/initialization/Initialization.java b/server/src/main/java/io/druid/initialization/Initialization.java index a467c7ce872e..3552081f1b66 100644 --- a/server/src/main/java/io/druid/initialization/Initialization.java +++ b/server/src/main/java/io/druid/initialization/Initialization.java @@ -184,8 +184,8 @@ private void tryAdd(T serviceImpl, String extensionType) + "is it a local or anonymous class?", serviceImpl.getClass().getName() ); - } else if (extensionsConfig.getExcludeModules().contains(serviceImplName)) { - log.info("Not loading module [%s] because it is present in excludeModules config", serviceImplName); + } else if (extensionsConfig.getModuleExcludeList().contains(serviceImplName)) { + log.info("Not loading module [%s] because it is present in moduleExcludeList", serviceImplName); } else if (!implClassNamesToLoad.contains(serviceImplName)) { log.info( "Adding implementation [%s] for class [%s] from %s extension", From 76ed4e6c6a1c012878e44f951ff9241e04369abb Mon Sep 17 00:00:00 2001 From: leventov Date: Wed, 28 Jun 2017 12:48:19 -0500 Subject: [PATCH 5/6] Initialization.getFromExtensions() and getLoadedModules() should return Collection, not Set --- .../druid/initialization/Initialization.java | 35 ++++++++++--------- .../java/io/druid/server/StatusResource.java | 2 +- .../initialization/InitializationTest.java | 21 ++++++----- .../src/main/java/io/druid/cli/Version.java | 2 +- 4 files changed, 33 insertions(+), 27 deletions(-) diff --git a/server/src/main/java/io/druid/initialization/Initialization.java b/server/src/main/java/io/druid/initialization/Initialization.java index 3552081f1b66..5bf4c42b402f 100644 --- a/server/src/main/java/io/druid/initialization/Initialization.java +++ b/server/src/main/java/io/druid/initialization/Initialization.java @@ -91,17 +91,18 @@ public class Initialization private static final Logger log = new Logger(Initialization.class); private static final ConcurrentMap loadersMap = new ConcurrentHashMap<>(); - private final static Map extensionsMap = Maps.newHashMap(); + private final static Map extensionsMap = Maps.newHashMap(); /** - * @param clazz Module class - * @param + * @param clazz service class + * @param the service type * - * @return Returns the set of modules loaded. + * @return Returns a collection of implementations loaded. */ - public static Set getLoadedModules(Class clazz) + public static Collection getLoadedImplementations(Class clazz) { - Set retVal = extensionsMap.get(clazz); + @SuppressWarnings("unchecked") + Collection retVal = extensionsMap.get(clazz); if (retVal == null) { return Sets.newHashSet(); } @@ -109,7 +110,7 @@ public static Set getLoadedModules(Class clazz) } @VisibleForTesting - static void clearLoadedModules() + static void clearLoadedImplementations() { extensionsMap.clear(); } @@ -121,18 +122,20 @@ static Map getLoadersMap() } /** - * Look for extension modules for the given class from both classpath and extensions directory. A user should never - * put the same two extensions in classpath and extensions directory, if he/she does that, the one that is in the - * classpath will be loaded, the other will be ignored. + * Look for implementations for the given class from both classpath and extensions directory, using {@link + * java.util.ServiceLoader}. A user should never put the same two extensions in classpath and extensions directory, if + * he/she does that, the one that is in the classpath will be loaded, the other will be ignored. * - * @param config Extensions configuration - * @param clazz The class of extension module (e.g., DruidModule) + * @param config Extensions configuration + * @param serviceClass The class to look the implementations of (e.g., DruidModule) * - * @return A set that contains distinct extension modules + * @return A collection that contains implementations (of distinct concrete classes) of the given class. The order of + * elements in the returned collection is not specified and not guaranteed to be the same for different calls to + * getFromExtensions(). */ - public synchronized static Set getFromExtensions(ExtensionsConfig config, Class serviceClass) + public synchronized static Collection getFromExtensions(ExtensionsConfig config, Class serviceClass) { - Set modulesToLoad = new ServiceLoadingFromExtensions(config, serviceClass).implsToLoad; + Collection modulesToLoad = new ServiceLoadingFromExtensions<>(config, serviceClass).implsToLoad; extensionsMap.put(serviceClass, modulesToLoad); return modulesToLoad; } @@ -141,7 +144,7 @@ private static class ServiceLoadingFromExtensions { private final ExtensionsConfig extensionsConfig; private final Class serviceClass; - private final Set implsToLoad = new HashSet<>(); + private final List implsToLoad = new ArrayList<>(); private final Set implClassNamesToLoad = new HashSet<>(); private ServiceLoadingFromExtensions(ExtensionsConfig extensionsConfig, Class serviceClass) diff --git a/server/src/main/java/io/druid/server/StatusResource.java b/server/src/main/java/io/druid/server/StatusResource.java index edbd65b4fdb7..127c840be412 100644 --- a/server/src/main/java/io/druid/server/StatusResource.java +++ b/server/src/main/java/io/druid/server/StatusResource.java @@ -44,7 +44,7 @@ public class StatusResource @Produces(MediaType.APPLICATION_JSON) public Status doGet() { - return new Status(Initialization.getLoadedModules(DruidModule.class)); + return new Status(Initialization.getLoadedImplementations(DruidModule.class)); } public static class Status diff --git a/server/src/test/java/io/druid/initialization/InitializationTest.java b/server/src/test/java/io/druid/initialization/InitializationTest.java index b5e238a0f040..80b0769c3c02 100644 --- a/server/src/test/java/io/druid/initialization/InitializationTest.java +++ b/server/src/test/java/io/druid/initialization/InitializationTest.java @@ -28,7 +28,6 @@ import com.google.inject.Binder; import com.google.inject.Injector; import com.google.inject.Key; - import io.druid.guice.ExtensionsConfig; import io.druid.guice.GuiceInjectors; import io.druid.guice.JsonConfigProvider; @@ -50,6 +49,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.Comparator; +import java.util.HashSet; import java.util.List; import java.util.Set; @@ -62,11 +62,11 @@ public class InitializationTest @Test public void test01InitialModulesEmpty() throws Exception { - Initialization.clearLoadedModules(); + Initialization.clearLoadedImplementations(); Assert.assertEquals( "Initial set of loaded modules must be empty", 0, - Initialization.getLoadedModules(DruidModule.class).size() + Initialization.getLoadedImplementations(DruidModule.class).size() ); } @@ -95,7 +95,7 @@ public String apply(@Nullable DruidModule input) Assert.assertFalse( "modules does not contain TestDruidModule", - Collections2.transform(Initialization.getLoadedModules(DruidModule.class), fnClassName) + Collections2.transform(Initialization.getLoadedImplementations(DruidModule.class), fnClassName) .contains("io.druid.initialization.InitializationTest.TestDruidModule") ); @@ -179,13 +179,16 @@ public int compare(URL o1, URL o2) public void testGetLoadedModules() { - Set modules = Initialization.getLoadedModules(DruidModule.class); + Collection modules = Initialization.getLoadedImplementations(DruidModule.class); + HashSet moduleSet = new HashSet<>(modules); - Set loadedModules = Initialization.getLoadedModules(DruidModule.class); - Assert.assertEquals("Set from loaded modules #1 should be same!", modules, loadedModules); + Collection loadedModules = Initialization.getLoadedImplementations(DruidModule.class); + Assert.assertEquals("Set from loaded modules #1 should be same!", modules.size(), loadedModules.size()); + Assert.assertEquals("Set from loaded modules #1 should be same!", moduleSet, new HashSet<>(loadedModules)); - Set loadedModules2 = Initialization.getLoadedModules(DruidModule.class); - Assert.assertEquals("Set from loaded modules #2 should be same!", modules, loadedModules2); + Collection loadedModules2 = Initialization.getLoadedImplementations(DruidModule.class); + Assert.assertEquals("Set from loaded modules #2 should be same!", modules.size(), loadedModules2.size()); + Assert.assertEquals("Set from loaded modules #2 should be same!", moduleSet, new HashSet<>(loadedModules2)); } @Test diff --git a/services/src/main/java/io/druid/cli/Version.java b/services/src/main/java/io/druid/cli/Version.java index c06d8fb3125a..71da1eb525c3 100644 --- a/services/src/main/java/io/druid/cli/Version.java +++ b/services/src/main/java/io/druid/cli/Version.java @@ -33,6 +33,6 @@ public class Version implements Runnable @Override public void run() { - System.out.println(new StatusResource.Status(Initialization.getLoadedModules(DruidModule.class))); + System.out.println(new StatusResource.Status(Initialization.getLoadedImplementations(DruidModule.class))); } } From c83f7ad901d30232247cc6780ada73b6708d5812 Mon Sep 17 00:00:00 2001 From: leventov Date: Wed, 28 Jun 2017 12:54:49 -0500 Subject: [PATCH 6/6] Fix doc --- docs/content/configuration/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/configuration/index.md b/docs/content/configuration/index.md index 838f8f3b2d85..10609730caa9 100644 --- a/docs/content/configuration/index.md +++ b/docs/content/configuration/index.md @@ -24,7 +24,7 @@ Many of Druid's external dependencies can be plugged in as modules. Extensions c |`druid.extensions.directory`|The root extension directory where user can put extensions related files. Druid will load extensions stored under this directory.|`extensions` (This is a relative path to Druid's working directory)| |`druid.extensions.hadoopDependenciesDir`|The root hadoop dependencies directory where user can put hadoop related dependencies files. Druid will load the dependencies based on the hadoop coordinate specified in the hadoop index task.|`hadoop-dependencies` (This is a relative path to Druid's working directory| |`druid.extensions.loadList`|A JSON array of extensions to load from extension directories by Druid. If it is not specified, its value will be `null` and Druid will load all the extensions under `druid.extensions.directory`. If its value is empty list `[]`, then no extensions will be loaded at all. It is also allowed to specify absolute path of other custom extensions not stored in the common extensions directory.|null| -|`druid.extensions.moduleExcludeList`|A JSON array of canonical class names (e. g. `"io.druid.somepackage.SomeClass"`) of modules, which shouldn't be loaded, despite they are found in the `loadList`. Useful when some useful extension contains some module, which shouldn't be loaded on some Druid node type because of some dependencies of that module couldn't be satisfied.|[]| +|`druid.extensions.moduleExcludeList`|A JSON array of canonical class names (e. g. `"io.druid.somepackage.SomeModule"`) of module classes which shouldn't be loaded, even if they are found in extensions specified by `druid.extensions.loadList`. Useful when some useful extension contains some module, which shouldn't be loaded on some Druid node type because some dependencies of that module couldn't be satisfied.|[]| |`druid.extensions.searchCurrentClassloader`|This is a boolean flag that determines if Druid will search the main classloader for extensions. It defaults to true but can be turned off if you have reason to not automatically add all modules on the classpath.|true| |`druid.extensions.hadoopContainerDruidClasspath`|Hadoop Indexing launches hadoop jobs and this configuration provides way to explicitly set the user classpath for the hadoop job. By default this is computed automatically by druid based on the druid process classpath and set of extensions. However, sometimes you might want to be explicit to resolve dependency conflicts between druid and hadoop.|null| |`druid.extensions.addExtensionsToHadoopContainer`|Only applicable if `druid.extensions.hadoopContainerDruidClasspath` is provided. If set to true, then extensions specified in the loadList are added to hadoop container classpath. Note that when `druid.extensions.hadoopContainerDruidClasspath` is not provided then extensions are always added to hadoop container classpath.|false|