Modularize Elasticsearch (#81066)
This PR represents the initial phase of Modularizing Elasticsearch (with Java Modules). This initial phase modularizes the core of the Elasticsearch server with Java Modules, which is then used to load and configure extension components atop the server. Only a subset of extension components are modularized at this stage (other components come in a later phase). Components are loaded dynamically at runtime with custom class loaders (same as is currently done). Components with a module-info.class are defined to a module layer. This architecture is somewhat akin to the Modular JDK, where applications run on the classpath. In the analogy, the Elasticsearch server modules are the platform (thus are always resolved and present), while components without a module-info.class are non-modular code running atop the Elasticsearch server modules. The extension components cannot access types from non-exported packages of the server modules, in the same way that classpath applications cannot access types from non-exported packages of modules from the JDK. Broadly, the core Elasticseach java modules simply "wrap" the existing packages and export them. There are opportunites to export less, which is best done in more narrowly focused follow-up PRs. The Elasticsearch distribution startup scripts are updated to put jars on the module path (the class path is empty), so the distribution will run the core of the server as java modules. A number of key components have been retrofitted with module-info.java's too, and the remaining components can follow later. Unit and functional tests run as non-modular (since they commonly require package-private access), while higher-level integration tests, that run the distribution, run as modular. Co-authored-by: Chris Hegarty <christopher.hegarty@elastic.co> Co-authored-by: Ryan Ernst <ryan@iernst.net> Co-authored-by: Rene Groeschke <rene@elastic.co>
This commit is contained in:
parent
f06da24c8f
commit
3071c6a055
|
@ -6,5 +6,8 @@
|
|||
<option name="m_ignoreExpressionsContainingConstants" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="jol" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="IllegalDependencyOnInternalPackage" enabled="true" level="ERROR" enabled_by_default="false">
|
||||
<scope name="Production" level="ERROR" enabled="true" />
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
</component>
|
||||
</component>
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
package org.elasticsearch.gradle.internal
|
||||
|
||||
import spock.lang.IgnoreIf
|
||||
|
||||
import org.elasticsearch.gradle.VersionProperties
|
||||
import org.elasticsearch.gradle.fixtures.AbstractJavaGradleFuncTest
|
||||
import org.gradle.internal.os.OperatingSystem
|
||||
|
@ -17,6 +19,7 @@ import org.objectweb.asm.tree.ClassNode
|
|||
|
||||
import java.nio.file.Files
|
||||
|
||||
@IgnoreIf({ os.isWindows() })
|
||||
class ElasticsearchJavaModulePathPluginFuncTest extends AbstractJavaGradleFuncTest {
|
||||
|
||||
public static final GString JAVA_BASE_MODULE = "java.base:${System.getProperty("java.version")}"
|
||||
|
|
|
@ -159,6 +159,7 @@ public class ElasticsearchJavaModulePathPlugin implements Plugin<Project> {
|
|||
}
|
||||
if (isModuleProject) {
|
||||
extraArgs.add("--module-version=" + VersionProperties.getElasticsearch());
|
||||
extraArgs.add("-Xlint:-module,-exports,-requires-automatic,-requires-transitive-automatic,-missing-explicit-ctor");
|
||||
}
|
||||
return List.copyOf(extraArgs);
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ public class ElasticsearchJavaPlugin implements Plugin<Project> {
|
|||
public void apply(Project project) {
|
||||
project.getPluginManager().apply(ElasticsearchJavaBasePlugin.class);
|
||||
project.getPluginManager().apply(JavaLibraryPlugin.class);
|
||||
project.getPluginManager().apply(ElasticsearchJavaModulePathPlugin.class);
|
||||
|
||||
// configureConfigurations(project);
|
||||
configureJars(project);
|
||||
|
@ -137,5 +138,4 @@ public class ElasticsearchJavaPlugin implements Plugin<Project> {
|
|||
// ensure javadoc task is run with 'check'
|
||||
project.getTasks().named(LifecycleBasePlugin.CHECK_TASK_NAME).configure(t -> t.dependsOn(javadoc));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -55,13 +55,17 @@ public class InternalDistributionArchiveCheckPlugin implements InternalPlugin {
|
|||
// sanity checks if archives can be extracted
|
||||
TaskProvider<Copy> checkExtraction = registerCheckExtractionTask(project, buildDistTask, archiveExtractionDir);
|
||||
TaskProvider<Task> checkLicense = registerCheckLicenseTask(project, checkExtraction);
|
||||
|
||||
TaskProvider<Task> checkNotice = registerCheckNoticeTask(project, checkExtraction);
|
||||
TaskProvider<Task> checkModulesTask = InternalDistributionModuleCheckTaskProvider.registerCheckModulesTask(
|
||||
project,
|
||||
checkExtraction
|
||||
);
|
||||
TaskProvider<Task> checkTask = project.getTasks().named("check");
|
||||
checkTask.configure(task -> {
|
||||
task.dependsOn(checkExtraction);
|
||||
task.dependsOn(checkLicense);
|
||||
task.dependsOn(checkNotice);
|
||||
task.dependsOn(checkModulesTask);
|
||||
});
|
||||
|
||||
String projectName = project.getName();
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.gradle.internal;
|
||||
|
||||
import org.elasticsearch.gradle.VersionProperties;
|
||||
import org.gradle.api.Action;
|
||||
import org.gradle.api.GradleException;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.Task;
|
||||
import org.gradle.api.logging.Logger;
|
||||
import org.gradle.api.logging.Logging;
|
||||
import org.gradle.api.tasks.Copy;
|
||||
import org.gradle.api.tasks.TaskProvider;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.lang.module.ModuleFinder;
|
||||
import java.lang.module.ModuleReference;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
import static java.util.stream.Collectors.joining;
|
||||
|
||||
/**
|
||||
* Distribution level checks for Elasticsearch Java modules, i.e. modular jar files.
|
||||
* Currently, ES modular jar files are in the lib directory.
|
||||
*/
|
||||
public class InternalDistributionModuleCheckTaskProvider {
|
||||
|
||||
private static final Logger LOGGER = Logging.getLogger(InternalDistributionModuleCheckTaskProvider.class);
|
||||
|
||||
private static final String MODULE_INFO = "module-info.class";
|
||||
|
||||
private static final String ES_JAR_PREFIX = "elasticsearch-";
|
||||
|
||||
/** ES jars in the lib directory that are not modularized. For now, es-log4j is the only one. */
|
||||
private static final List<String> ES_JAR_EXCLUDES = List.of("elasticsearch-log4j");
|
||||
|
||||
/** List of the current Elasticsearch Java Modules, by name. */
|
||||
private static final List<String> EXPECTED_ES_SERVER_MODULES = List.of(
|
||||
"org.elasticsearch.base",
|
||||
"org.elasticsearch.cli",
|
||||
"org.elasticsearch.geo",
|
||||
"org.elasticsearch.lz4",
|
||||
"org.elasticsearch.pluginclassloader",
|
||||
"org.elasticsearch.securesm",
|
||||
"org.elasticsearch.server",
|
||||
"org.elasticsearch.xcontent"
|
||||
);
|
||||
|
||||
private static final Predicate<ModuleReference> isESModule = mref -> mref.descriptor().name().startsWith("org.elasticsearch");
|
||||
|
||||
private static Predicate<Path> isESJar = path -> path.getFileName().toString().startsWith(ES_JAR_PREFIX);
|
||||
|
||||
private static Predicate<Path> isNotExcluded = path -> ES_JAR_EXCLUDES.stream()
|
||||
.filter(path.getFileName().toString()::startsWith)
|
||||
.findAny()
|
||||
.isEmpty();
|
||||
|
||||
private static final Function<ModuleReference, String> toName = mref -> mref.descriptor().name();
|
||||
|
||||
private InternalDistributionModuleCheckTaskProvider() {};
|
||||
|
||||
/** Registers the checkModules tasks, which contains all checks relevant to ES Java Modules. */
|
||||
static TaskProvider<Task> registerCheckModulesTask(Project project, TaskProvider<Copy> checkExtraction) {
|
||||
return project.getTasks().register("checkModules", task -> {
|
||||
task.dependsOn(checkExtraction);
|
||||
task.doLast(new Action<Task>() {
|
||||
@Override
|
||||
public void execute(Task task) {
|
||||
final Path libPath = checkExtraction.get()
|
||||
.getDestinationDir()
|
||||
.toPath()
|
||||
.resolve("elasticsearch-" + VersionProperties.getElasticsearch())
|
||||
.resolve("lib");
|
||||
try {
|
||||
assertAllESJarsAreModular(libPath);
|
||||
assertAllModulesPresent(libPath);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/** Checks that all expected ES jar files are modular, i.e. contain a module-info.class in their root. */
|
||||
private static void assertAllESJarsAreModular(Path libPath) throws IOException {
|
||||
try (var s = Files.walk(libPath, 1)) {
|
||||
s.filter(Files::isRegularFile).filter(isESJar).filter(isNotExcluded).sorted().forEach(path -> {
|
||||
try (JarFile jf = new JarFile(path.toFile())) {
|
||||
JarEntry entry = jf.getJarEntry(MODULE_INFO);
|
||||
if (entry == null) {
|
||||
throw new GradleException(MODULE_INFO + " no found in " + path);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new GradleException("Failed when reading jar file " + path, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/** Checks that all expected Elasticsearch modules are present. */
|
||||
private static void assertAllModulesPresent(Path libPath) {
|
||||
List<String> actualESModules = ModuleFinder.of(libPath).findAll().stream().filter(isESModule).map(toName).sorted().toList();
|
||||
if (actualESModules.equals(EXPECTED_ES_SERVER_MODULES) == false) {
|
||||
throw new GradleException(
|
||||
"expected modules " + listToString(EXPECTED_ES_SERVER_MODULES) + ", \nactual modules " + listToString(actualESModules)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ####: eventually assert hashes, etc
|
||||
|
||||
static String listToString(List<String> list) {
|
||||
return list.stream().sorted().collect(joining("\n ", "[\n ", "]"));
|
||||
}
|
||||
}
|
|
@ -44,6 +44,7 @@ public class InternalPrecommitTasks {
|
|||
project.getPluginManager().apply(ThirdPartyAuditPrecommitPlugin.class);
|
||||
project.getPluginManager().apply(DependencyLicensesPrecommitPlugin.class);
|
||||
project.getPluginManager().apply(SplitPackagesAuditPrecommitPlugin.class);
|
||||
project.getPluginManager().apply(JavaModulePrecommitPlugin.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.gradle.internal.precommit;
|
||||
|
||||
import org.elasticsearch.gradle.internal.InternalPlugin;
|
||||
import org.elasticsearch.gradle.internal.conventions.precommit.PrecommitPlugin;
|
||||
import org.elasticsearch.gradle.util.GradleUtils;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.Task;
|
||||
import org.gradle.api.plugins.JavaPlugin;
|
||||
import org.gradle.api.tasks.SourceSet;
|
||||
import org.gradle.api.tasks.TaskProvider;
|
||||
|
||||
public class JavaModulePrecommitPlugin extends PrecommitPlugin implements InternalPlugin {
|
||||
|
||||
public static final String TASK_NAME = "validateModule";
|
||||
|
||||
@Override
|
||||
public TaskProvider<? extends Task> createTask(Project project) {
|
||||
TaskProvider<JavaModulePrecommitTask> task = project.getTasks().register(TASK_NAME, JavaModulePrecommitTask.class);
|
||||
task.configure(t -> {
|
||||
SourceSet mainSourceSet = GradleUtils.getJavaSourceSets(project).findByName(SourceSet.MAIN_SOURCE_SET_NAME);
|
||||
t.getSrcDirs().set(project.provider(() -> mainSourceSet.getAllSource().getSrcDirs()));
|
||||
t.setClasspath(project.getConfigurations().getByName(JavaPlugin.COMPILE_CLASSPATH_CONFIGURATION_NAME));
|
||||
t.setClassesDirs(mainSourceSet.getOutput().getClassesDirs());
|
||||
t.setResourcesDirs(mainSourceSet.getOutput().getResourcesDir());
|
||||
});
|
||||
return task;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,164 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.gradle.internal.precommit;
|
||||
|
||||
import org.elasticsearch.gradle.VersionProperties;
|
||||
import org.elasticsearch.gradle.internal.conventions.precommit.PrecommitTask;
|
||||
import org.gradle.api.GradleException;
|
||||
import org.gradle.api.file.FileCollection;
|
||||
import org.gradle.api.model.ObjectFactory;
|
||||
import org.gradle.api.provider.SetProperty;
|
||||
import org.gradle.api.tasks.Classpath;
|
||||
import org.gradle.api.tasks.InputFiles;
|
||||
import org.gradle.api.tasks.PathSensitive;
|
||||
import org.gradle.api.tasks.PathSensitivity;
|
||||
import org.gradle.api.tasks.SkipWhenEmpty;
|
||||
import org.gradle.api.tasks.TaskAction;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import java.lang.module.ModuleFinder;
|
||||
import java.lang.module.ModuleReference;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Comparator;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static java.util.stream.Collectors.toSet;
|
||||
|
||||
public class JavaModulePrecommitTask extends PrecommitTask {
|
||||
|
||||
private static final String expectedVersion = VersionProperties.getElasticsearch();
|
||||
|
||||
private final SetProperty<File> srcDirs;
|
||||
|
||||
private FileCollection classesDirs;
|
||||
|
||||
private FileCollection classpath;
|
||||
|
||||
private File resourcesDir;
|
||||
|
||||
@Inject
|
||||
public JavaModulePrecommitTask(ObjectFactory objectFactory) {
|
||||
srcDirs = objectFactory.setProperty(File.class);
|
||||
}
|
||||
|
||||
@InputFiles
|
||||
public FileCollection getClassesDirs() {
|
||||
return this.classesDirs;
|
||||
}
|
||||
|
||||
public void setClassesDirs(FileCollection classesDirs) {
|
||||
Objects.requireNonNull(classesDirs, "classesDirs");
|
||||
this.classesDirs = classesDirs;
|
||||
}
|
||||
|
||||
@InputFiles
|
||||
public File getResourcesDir() {
|
||||
return this.resourcesDir;
|
||||
}
|
||||
|
||||
public void setResourcesDirs(File resourcesDirs) {
|
||||
Objects.requireNonNull(resourcesDirs, "resourcesDirs");
|
||||
this.resourcesDir = resourcesDirs;
|
||||
}
|
||||
|
||||
@InputFiles
|
||||
@SkipWhenEmpty
|
||||
@PathSensitive(PathSensitivity.RELATIVE)
|
||||
public SetProperty<File> getSrcDirs() {
|
||||
return srcDirs;
|
||||
}
|
||||
|
||||
@Classpath
|
||||
@InputFiles
|
||||
public FileCollection getClasspath() {
|
||||
return classpath;
|
||||
}
|
||||
|
||||
public void setClasspath(FileCollection classpath) {
|
||||
this.classpath = classpath;
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
public void checkModule() {
|
||||
if (hasModuleInfoDotJava(getSrcDirs()) == false) {
|
||||
return; // non-modular project, nothing to do
|
||||
}
|
||||
ModuleReference mod = esModuleFor(getClassesDirs().getSingleFile());
|
||||
getLogger().info("%s checking module %s".formatted(this, mod));
|
||||
checkModuleVersion(mod);
|
||||
checkModuleNamePrefix(mod);
|
||||
checkModuleServices(mod);
|
||||
}
|
||||
|
||||
private void checkModuleVersion(ModuleReference mref) {
|
||||
getLogger().info("%s checking module version for %s".formatted(this, mref.descriptor().name()));
|
||||
String mVersion = mref.descriptor()
|
||||
.rawVersion()
|
||||
.orElseThrow(() -> new GradleException("no version found in module " + mref.descriptor().name()));
|
||||
if (mVersion.equals(expectedVersion) == false) {
|
||||
throw new GradleException("Expected version [" + expectedVersion + "], in " + mref.descriptor());
|
||||
}
|
||||
}
|
||||
|
||||
private void checkModuleNamePrefix(ModuleReference mref) {
|
||||
getLogger().info("%s checking module name prefix for %s".formatted(this, mref.descriptor().name()));
|
||||
if (mref.descriptor().name().startsWith("org.elasticsearch.") == false) {
|
||||
throw new GradleException("Expected name starting with \"org.elasticsearch.\", in " + mref.descriptor());
|
||||
}
|
||||
}
|
||||
|
||||
private void checkModuleServices(ModuleReference mref) {
|
||||
getLogger().info("%s checking module services for %s".formatted(this, mref.descriptor().name()));
|
||||
Set<String> modServices = mref.descriptor().provides().stream().map(ModuleDescriptor.Provides::service).collect(toSet());
|
||||
Path servicesRoot = getResourcesDir().toPath().resolve("META-INF").resolve("services");
|
||||
getLogger().info("%s servicesRoot %s".formatted(this, servicesRoot));
|
||||
if (Files.exists(servicesRoot)) {
|
||||
try {
|
||||
Files.walk(servicesRoot)
|
||||
.filter(Files::isRegularFile)
|
||||
.map(p -> servicesRoot.relativize(p))
|
||||
.map(Path::toString)
|
||||
.peek(s -> getLogger().info("%s checking service %s".formatted(this, s)))
|
||||
.forEach(service -> {
|
||||
if (modServices.contains(service) == false) {
|
||||
throw new GradleException(
|
||||
"Expected provides %s in module %s with provides %s.".formatted(
|
||||
service,
|
||||
mref.descriptor().name(),
|
||||
mref.descriptor().provides()
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean hasModuleInfoDotJava(SetProperty<File> srcDirs) {
|
||||
return srcDirs.get().stream().map(dir -> dir.toPath().resolve("module-info.java")).anyMatch(Files::exists);
|
||||
}
|
||||
|
||||
private static ModuleReference esModuleFor(File filePath) {
|
||||
return ModuleFinder.of(filePath.toPath())
|
||||
.findAll()
|
||||
.stream()
|
||||
.sorted(Comparator.comparing(ModuleReference::descriptor))
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new GradleException("module not found in " + filePath));
|
||||
}
|
||||
}
|
|
@ -4,6 +4,10 @@
|
|||
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
|
||||
|
||||
<module name="Checker">
|
||||
<module name="BeforeExecutionExclusionFileFilter">
|
||||
<property name="fileNamePattern" value="module\-info\.java$"/>
|
||||
</module>
|
||||
|
||||
<property name="charset" value="UTF-8" />
|
||||
|
||||
<module name="SuppressionFilter">
|
||||
|
|
|
@ -15,6 +15,8 @@ for %%I in ("%ES_HOME%..") do set ES_HOME=%%~dpfI
|
|||
|
||||
rem now set the classpath
|
||||
set ES_CLASSPATH=!ES_HOME!\lib\*
|
||||
set ES_MODULEPATH=!ES_HOME!\lib
|
||||
set LAUNCHERS_CLASSPATH=!ES_CLASSPATH!;!ES_HOME!\lib\launchers\*;!ES_HOME!\lib\java-version-checker\*
|
||||
set SERVER_CLI_CLASSPATH=!ES_CLASSPATH!;!ES_HOME!\lib\tools\server-cli\*
|
||||
|
||||
set HOSTNAME=%COMPUTERNAME%
|
||||
|
|
|
@ -9,5 +9,7 @@ call "%~dp0elasticsearch-cli.bat" ^
|
|||
%%* ^
|
||||
|| goto exit
|
||||
|
||||
endlocal
|
||||
endlocal
|
||||
:exit
|
||||
exit /b %ERRORLEVEL%
|
||||
|
|
|
@ -221,11 +221,10 @@ public class ServerProcess {
|
|||
boolean isWindows = processInfo.sysprops().get("os.name").startsWith("Windows");
|
||||
command.add(javaHome.resolve("bin").resolve("java" + (isWindows ? ".exe" : "")).toString());
|
||||
command.addAll(jvmOptions);
|
||||
command.add("-cp");
|
||||
// The '*' isn't allowed by the windows filesystem, so we need to force it into the classpath after converting to a string.
|
||||
// Thankfully this will all go away when switching to modules, which take the directory instead of a glob.
|
||||
command.add(esHome.resolve("lib") + (isWindows ? "\\" : "/") + "*");
|
||||
command.add("org.elasticsearch.bootstrap.Elasticsearch");
|
||||
command.add("--module-path");
|
||||
command.add(esHome.resolve("lib").toString());
|
||||
command.add("-m");
|
||||
command.add("org.elasticsearch.server/org.elasticsearch.bootstrap.Elasticsearch");
|
||||
|
||||
var builder = new ProcessBuilder(command);
|
||||
builder.environment().putAll(envVars);
|
||||
|
|
|
@ -346,21 +346,20 @@ public class ServerProcessTests extends ESTestCase {
|
|||
}
|
||||
|
||||
public void testCommandLine() throws Exception {
|
||||
String mainClass = "org.elasticsearch.bootstrap.Elasticsearch";
|
||||
String mainClass = "org.elasticsearch.server/org.elasticsearch.bootstrap.Elasticsearch";
|
||||
String distroSysprop = "-Des.distribution.type=testdistro";
|
||||
String modulePath = esHomeDir.resolve("lib").toString();
|
||||
Path javaBin = Paths.get("javahome").resolve("bin");
|
||||
sysprops.put("es.distribution.type", "testdistro");
|
||||
AtomicReference<String> expectedJava = new AtomicReference<>(javaBin.resolve("java").toString());
|
||||
AtomicReference<String> expectedClasspath = new AtomicReference<>(esHomeDir.resolve("lib") + "/*");
|
||||
processValidator = pb -> {
|
||||
assertThat(pb.command(), hasItems(expectedJava.get(), distroSysprop, "-cp", expectedClasspath.get(), mainClass));
|
||||
assertThat(pb.command(), hasItems(expectedJava.get(), distroSysprop, "--module-path", modulePath, "-m", mainClass));
|
||||
};
|
||||
runForeground();
|
||||
|
||||
sysprops.put("os.name", "Windows 10");
|
||||
sysprops.put("java.io.tmpdir", createTempDir().toString());
|
||||
expectedJava.set(javaBin.resolve("java.exe").toString());
|
||||
expectedClasspath.set(esHomeDir.resolve("lib") + "\\*");
|
||||
runForeground();
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
/** Elasticsearch Command Line Interface. */
|
||||
module org.elasticsearch.cli {
|
||||
requires jopt.simple;
|
||||
requires org.elasticsearch.base;
|
||||
|
||||
exports org.elasticsearch.cli;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
module org.elasticsearch.base {
|
||||
requires static jsr305;
|
||||
|
||||
exports org.elasticsearch.core;
|
||||
exports org.elasticsearch.jdk;
|
||||
exports org.elasticsearch.core.internal.provider to org.elasticsearch.xcontent;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
module org.elasticsearch.geo {
|
||||
exports org.elasticsearch.geometry;
|
||||
exports org.elasticsearch.geometry.utils;
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
module org.elasticsearch.lz4 {
|
||||
requires org.lz4.java;
|
||||
|
||||
exports org.elasticsearch.lz4;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
module org.elasticsearch.pluginclassloader {
|
||||
exports org.elasticsearch.plugins.loader;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
module org.elasticsearch.securesm {
|
||||
exports org.elasticsearch.secure_sm;
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
module org.elasticsearch.sslconfig {
|
||||
requires org.elasticsearch.base;
|
||||
|
||||
exports org.elasticsearch.common.ssl;
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
module org.elasticsearch.xcontent.impl {
|
||||
requires com.fasterxml.jackson.core;
|
||||
requires com.fasterxml.jackson.dataformat.cbor;
|
||||
requires com.fasterxml.jackson.dataformat.smile;
|
||||
requires com.fasterxml.jackson.dataformat.yaml;
|
||||
requires org.elasticsearch.base;
|
||||
requires org.elasticsearch.xcontent;
|
||||
|
||||
provides org.elasticsearch.xcontent.spi.XContentProvider with org.elasticsearch.xcontent.provider.XContentProviderImpl;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The X-Content module.
|
||||
*/
|
||||
module org.elasticsearch.xcontent {
|
||||
requires org.elasticsearch.base;
|
||||
|
||||
exports org.elasticsearch.xcontent;
|
||||
exports org.elasticsearch.xcontent.cbor;
|
||||
exports org.elasticsearch.xcontent.json;
|
||||
exports org.elasticsearch.xcontent.smile;
|
||||
exports org.elasticsearch.xcontent.spi;
|
||||
exports org.elasticsearch.xcontent.support;
|
||||
exports org.elasticsearch.xcontent.support.filtering;
|
||||
exports org.elasticsearch.xcontent.yaml;
|
||||
|
||||
uses org.elasticsearch.xcontent.ErrorOnUnknown;
|
||||
uses org.elasticsearch.xcontent.XContentBuilderExtension;
|
||||
uses org.elasticsearch.xcontent.spi.XContentProvider;
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
module org.elasticsearch.aggs.matrix {
|
||||
requires org.elasticsearch.base;
|
||||
requires org.elasticsearch.server;
|
||||
requires org.elasticsearch.xcontent;
|
||||
requires org.apache.logging.log4j;
|
||||
requires org.apache.lucene.core;
|
||||
|
||||
exports org.elasticsearch.search.aggregations.matrix;
|
||||
exports org.elasticsearch.search.aggregations.matrix.stats;
|
||||
|
||||
provides org.elasticsearch.plugins.spi.NamedXContentProvider
|
||||
with
|
||||
org.elasticsearch.search.aggregations.matrix.spi.MatrixStatsNamedXContentProvider;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
module org.elasticsearch.painless.spi {
|
||||
requires org.elasticsearch.server;
|
||||
|
||||
exports org.elasticsearch.painless.spi;
|
||||
exports org.elasticsearch.painless.spi.annotation;
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
module org.elasticsearch.painless {
|
||||
requires org.elasticsearch.base;
|
||||
requires org.elasticsearch.geo;
|
||||
requires org.elasticsearch.painless.spi;
|
||||
requires org.elasticsearch.server;
|
||||
requires org.elasticsearch.xcontent;
|
||||
|
||||
requires antlr4.runtime;
|
||||
requires org.apache.lucene.core;
|
||||
requires org.objectweb.asm;
|
||||
requires org.objectweb.asm.commons;
|
||||
requires org.objectweb.asm.util;
|
||||
|
||||
exports org.elasticsearch.painless;
|
||||
exports org.elasticsearch.painless.api;
|
||||
exports org.elasticsearch.painless.action;
|
||||
|
||||
opens org.elasticsearch.painless to org.elasticsearch.painless.spi; // whitelist access
|
||||
opens org.elasticsearch.painless.action to org.elasticsearch.server; // guice
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
module org.elasticsearch.percolator {
|
||||
requires org.elasticsearch.base;
|
||||
requires org.elasticsearch.server;
|
||||
requires org.elasticsearch.xcontent;
|
||||
requires org.apache.lucene.core;
|
||||
requires org.apache.lucene.join;
|
||||
requires org.apache.lucene.memory;
|
||||
requires org.apache.lucene.queries;
|
||||
requires org.apache.lucene.sandbox;
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
module org.elasticsearch.rankeval {
|
||||
requires org.elasticsearch.server;
|
||||
requires org.elasticsearch.xcontent;
|
||||
requires org.elasticsearch.base;
|
||||
requires java.naming;
|
||||
|
||||
exports org.elasticsearch.index.rankeval;
|
||||
|
||||
provides org.elasticsearch.plugins.spi.NamedXContentProvider with org.elasticsearch.index.rankeval.RankEvalNamedXContentProvider;
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
module org.elasticsearch.transport.netty4 {
|
||||
requires org.elasticsearch.base;
|
||||
requires org.elasticsearch.server;
|
||||
requires org.elasticsearch.xcontent;
|
||||
requires org.apache.logging.log4j;
|
||||
requires org.apache.lucene.core;
|
||||
requires io.netty.buffer;
|
||||
requires io.netty.codec;
|
||||
requires io.netty.common;
|
||||
requires io.netty.handler;
|
||||
requires io.netty.transport;
|
||||
requires io.netty.codec.http;
|
||||
|
||||
exports org.elasticsearch.http.netty4;
|
||||
exports org.elasticsearch.transport.netty4;
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
module org.elasticsearch.analysis.icu {
|
||||
requires org.elasticsearch.base;
|
||||
requires org.elasticsearch.server;
|
||||
requires org.elasticsearch.xcontent;
|
||||
requires com.ibm.icu;
|
||||
requires org.apache.lucene.core;
|
||||
requires org.apache.lucene.analysis.icu;
|
||||
|
||||
// exports nothing
|
||||
}
|
|
@ -0,0 +1,356 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
/** The Elasticsearch Server Module. */
|
||||
module org.elasticsearch.server {
|
||||
requires java.logging;
|
||||
requires java.security.jgss;
|
||||
requires java.sql;
|
||||
requires java.management;
|
||||
requires jdk.unsupported;
|
||||
|
||||
requires org.elasticsearch.cli;
|
||||
requires org.elasticsearch.base;
|
||||
requires org.elasticsearch.geo;
|
||||
requires org.elasticsearch.lz4;
|
||||
requires org.elasticsearch.pluginclassloader;
|
||||
requires org.elasticsearch.securesm;
|
||||
requires org.elasticsearch.xcontent;
|
||||
|
||||
requires com.sun.jna;
|
||||
requires hppc;
|
||||
requires HdrHistogram;
|
||||
requires jopt.simple;
|
||||
requires log4j2.ecs.layout;
|
||||
requires org.lz4.java;
|
||||
requires t.digest;
|
||||
|
||||
requires org.apache.logging.log4j;
|
||||
requires org.apache.logging.log4j.core;
|
||||
|
||||
requires org.apache.lucene.analysis.common;
|
||||
requires org.apache.lucene.backward_codecs;
|
||||
requires org.apache.lucene.core;
|
||||
requires org.apache.lucene.grouping;
|
||||
requires org.apache.lucene.highlighter;
|
||||
requires org.apache.lucene.join;
|
||||
requires org.apache.lucene.memory;
|
||||
requires org.apache.lucene.misc;
|
||||
requires org.apache.lucene.queries;
|
||||
requires org.apache.lucene.queryparser;
|
||||
requires org.apache.lucene.sandbox;
|
||||
requires org.apache.lucene.suggest;
|
||||
|
||||
exports org.elasticsearch;
|
||||
exports org.elasticsearch.action;
|
||||
exports org.elasticsearch.action.admin.cluster.allocation;
|
||||
exports org.elasticsearch.action.admin.cluster.configuration;
|
||||
exports org.elasticsearch.action.admin.cluster.health;
|
||||
exports org.elasticsearch.action.admin.cluster.migration;
|
||||
exports org.elasticsearch.action.admin.cluster.node.hotthreads;
|
||||
exports org.elasticsearch.action.admin.cluster.node.info;
|
||||
exports org.elasticsearch.action.admin.cluster.node.reload;
|
||||
exports org.elasticsearch.action.admin.cluster.node.stats;
|
||||
exports org.elasticsearch.action.admin.cluster.node.tasks.cancel;
|
||||
exports org.elasticsearch.action.admin.cluster.node.tasks.get;
|
||||
exports org.elasticsearch.action.admin.cluster.node.tasks.list;
|
||||
exports org.elasticsearch.action.admin.cluster.node.usage;
|
||||
exports org.elasticsearch.action.admin.cluster.remote;
|
||||
exports org.elasticsearch.action.admin.cluster.repositories.cleanup;
|
||||
exports org.elasticsearch.action.admin.cluster.repositories.delete;
|
||||
exports org.elasticsearch.action.admin.cluster.repositories.get;
|
||||
exports org.elasticsearch.action.admin.cluster.repositories.put;
|
||||
exports org.elasticsearch.action.admin.cluster.repositories.verify;
|
||||
exports org.elasticsearch.action.admin.cluster.reroute;
|
||||
exports org.elasticsearch.action.admin.cluster.settings;
|
||||
exports org.elasticsearch.action.admin.cluster.shards;
|
||||
exports org.elasticsearch.action.admin.cluster.snapshots.clone;
|
||||
exports org.elasticsearch.action.admin.cluster.snapshots.create;
|
||||
exports org.elasticsearch.action.admin.cluster.snapshots.delete;
|
||||
exports org.elasticsearch.action.admin.cluster.snapshots.features;
|
||||
exports org.elasticsearch.action.admin.cluster.snapshots.get;
|
||||
exports org.elasticsearch.action.admin.cluster.snapshots.get.shard;
|
||||
exports org.elasticsearch.action.admin.cluster.snapshots.restore;
|
||||
exports org.elasticsearch.action.admin.cluster.snapshots.status;
|
||||
exports org.elasticsearch.action.admin.cluster.state;
|
||||
exports org.elasticsearch.action.admin.cluster.stats;
|
||||
exports org.elasticsearch.action.admin.cluster.storedscripts;
|
||||
exports org.elasticsearch.action.admin.cluster.tasks;
|
||||
exports org.elasticsearch.action.admin.indices.alias;
|
||||
exports org.elasticsearch.action.admin.indices.alias.get;
|
||||
exports org.elasticsearch.action.admin.indices.analyze;
|
||||
exports org.elasticsearch.action.admin.indices.cache.clear;
|
||||
exports org.elasticsearch.action.admin.indices.close;
|
||||
exports org.elasticsearch.action.admin.indices.create;
|
||||
exports org.elasticsearch.action.admin.indices.dangling;
|
||||
exports org.elasticsearch.action.admin.indices.dangling.delete;
|
||||
exports org.elasticsearch.action.admin.indices.dangling.find;
|
||||
exports org.elasticsearch.action.admin.indices.dangling.import_index;
|
||||
exports org.elasticsearch.action.admin.indices.dangling.list;
|
||||
exports org.elasticsearch.action.admin.indices.delete;
|
||||
exports org.elasticsearch.action.admin.indices.diskusage;
|
||||
exports org.elasticsearch.action.admin.indices.flush;
|
||||
exports org.elasticsearch.action.admin.indices.forcemerge;
|
||||
exports org.elasticsearch.action.admin.indices.get;
|
||||
exports org.elasticsearch.action.admin.indices.mapping.get;
|
||||
exports org.elasticsearch.action.admin.indices.mapping.put;
|
||||
exports org.elasticsearch.action.admin.indices.open;
|
||||
exports org.elasticsearch.action.admin.indices.readonly;
|
||||
exports org.elasticsearch.action.admin.indices.recovery;
|
||||
exports org.elasticsearch.action.admin.indices.refresh;
|
||||
exports org.elasticsearch.action.admin.indices.resolve;
|
||||
exports org.elasticsearch.action.admin.indices.rollover;
|
||||
exports org.elasticsearch.action.admin.indices.segments;
|
||||
exports org.elasticsearch.action.admin.indices.settings.get;
|
||||
exports org.elasticsearch.action.admin.indices.settings.put;
|
||||
exports org.elasticsearch.action.admin.indices.shards;
|
||||
exports org.elasticsearch.action.admin.indices.shrink;
|
||||
exports org.elasticsearch.action.admin.indices.stats;
|
||||
exports org.elasticsearch.action.admin.indices.template.delete;
|
||||
exports org.elasticsearch.action.admin.indices.template.get;
|
||||
exports org.elasticsearch.action.admin.indices.template.post;
|
||||
exports org.elasticsearch.action.admin.indices.template.put;
|
||||
exports org.elasticsearch.action.admin.indices.validate.query;
|
||||
exports org.elasticsearch.action.bulk;
|
||||
exports org.elasticsearch.action.datastreams;
|
||||
exports org.elasticsearch.action.delete;
|
||||
exports org.elasticsearch.action.explain;
|
||||
exports org.elasticsearch.action.fieldcaps;
|
||||
exports org.elasticsearch.action.get;
|
||||
exports org.elasticsearch.action.index;
|
||||
exports org.elasticsearch.action.ingest;
|
||||
exports org.elasticsearch.action.main;
|
||||
exports org.elasticsearch.action.resync;
|
||||
exports org.elasticsearch.action.search;
|
||||
exports org.elasticsearch.action.support;
|
||||
exports org.elasticsearch.action.support.broadcast;
|
||||
exports org.elasticsearch.action.support.broadcast.node;
|
||||
exports org.elasticsearch.action.support.master;
|
||||
exports org.elasticsearch.action.support.master.info;
|
||||
exports org.elasticsearch.action.support.nodes;
|
||||
exports org.elasticsearch.action.support.replication;
|
||||
exports org.elasticsearch.action.support.single.instance;
|
||||
exports org.elasticsearch.action.support.single.shard;
|
||||
exports org.elasticsearch.action.support.tasks;
|
||||
exports org.elasticsearch.action.termvectors;
|
||||
exports org.elasticsearch.action.update;
|
||||
exports org.elasticsearch.bootstrap;
|
||||
exports org.elasticsearch.bootstrap.plugins;
|
||||
exports org.elasticsearch.client.internal;
|
||||
exports org.elasticsearch.client.internal.node;
|
||||
exports org.elasticsearch.client.internal.support;
|
||||
exports org.elasticsearch.client.internal.transport;
|
||||
exports org.elasticsearch.cluster;
|
||||
exports org.elasticsearch.cluster.ack;
|
||||
exports org.elasticsearch.cluster.action.index;
|
||||
exports org.elasticsearch.cluster.action.shard;
|
||||
exports org.elasticsearch.cluster.block;
|
||||
exports org.elasticsearch.cluster.coordination;
|
||||
exports org.elasticsearch.cluster.health;
|
||||
exports org.elasticsearch.cluster.metadata;
|
||||
exports org.elasticsearch.cluster.node;
|
||||
exports org.elasticsearch.cluster.routing;
|
||||
exports org.elasticsearch.cluster.routing.allocation;
|
||||
exports org.elasticsearch.cluster.routing.allocation.allocator;
|
||||
exports org.elasticsearch.cluster.routing.allocation.command;
|
||||
exports org.elasticsearch.cluster.routing.allocation.decider;
|
||||
exports org.elasticsearch.cluster.service;
|
||||
exports org.elasticsearch.common;
|
||||
exports org.elasticsearch.common.blobstore;
|
||||
exports org.elasticsearch.common.blobstore.fs;
|
||||
exports org.elasticsearch.common.blobstore.support;
|
||||
exports org.elasticsearch.common.breaker;
|
||||
exports org.elasticsearch.common.bytes;
|
||||
exports org.elasticsearch.common.cache;
|
||||
exports org.elasticsearch.common.cli;
|
||||
exports org.elasticsearch.common.collect;
|
||||
exports org.elasticsearch.common.component;
|
||||
exports org.elasticsearch.common.compress;
|
||||
exports org.elasticsearch.common.document;
|
||||
exports org.elasticsearch.common.filesystem;
|
||||
exports org.elasticsearch.common.geo;
|
||||
exports org.elasticsearch.common.hash;
|
||||
exports org.elasticsearch.common.inject;
|
||||
exports org.elasticsearch.common.inject.binder;
|
||||
exports org.elasticsearch.common.inject.internal;
|
||||
exports org.elasticsearch.common.inject.matcher;
|
||||
exports org.elasticsearch.common.inject.multibindings;
|
||||
exports org.elasticsearch.common.inject.name;
|
||||
exports org.elasticsearch.common.inject.spi;
|
||||
exports org.elasticsearch.common.inject.util;
|
||||
exports org.elasticsearch.common.io;
|
||||
exports org.elasticsearch.common.io.stream;
|
||||
exports org.elasticsearch.common.logging;
|
||||
exports org.elasticsearch.common.lucene;
|
||||
exports org.elasticsearch.common.lucene.index;
|
||||
exports org.elasticsearch.common.lucene.search;
|
||||
exports org.elasticsearch.common.lucene.search.function;
|
||||
exports org.elasticsearch.common.lucene.store;
|
||||
exports org.elasticsearch.common.lucene.uid;
|
||||
exports org.elasticsearch.common.metrics;
|
||||
exports org.elasticsearch.common.network;
|
||||
exports org.elasticsearch.common.path;
|
||||
exports org.elasticsearch.common.recycler;
|
||||
exports org.elasticsearch.common.regex;
|
||||
exports org.elasticsearch.common.settings;
|
||||
exports org.elasticsearch.common.text;
|
||||
exports org.elasticsearch.common.time;
|
||||
exports org.elasticsearch.common.transport;
|
||||
exports org.elasticsearch.common.unit;
|
||||
exports org.elasticsearch.common.util;
|
||||
exports org.elasticsearch.common.util.concurrent;
|
||||
exports org.elasticsearch.common.util.iterable;
|
||||
exports org.elasticsearch.common.util.set;
|
||||
exports org.elasticsearch.common.xcontent;
|
||||
exports org.elasticsearch.common.xcontent.support;
|
||||
exports org.elasticsearch.discovery;
|
||||
exports org.elasticsearch.env;
|
||||
exports org.elasticsearch.gateway;
|
||||
exports org.elasticsearch.health;
|
||||
exports org.elasticsearch.http;
|
||||
exports org.elasticsearch.index;
|
||||
exports org.elasticsearch.index.analysis;
|
||||
exports org.elasticsearch.index.bulk.stats;
|
||||
exports org.elasticsearch.index.cache;
|
||||
exports org.elasticsearch.index.cache.bitset;
|
||||
exports org.elasticsearch.index.cache.query;
|
||||
exports org.elasticsearch.index.cache.request;
|
||||
exports org.elasticsearch.index.codec;
|
||||
exports org.elasticsearch.index.engine;
|
||||
exports org.elasticsearch.index.fielddata;
|
||||
exports org.elasticsearch.index.fielddata.fieldcomparator;
|
||||
exports org.elasticsearch.index.fielddata.ordinals;
|
||||
exports org.elasticsearch.index.fielddata.plain;
|
||||
exports org.elasticsearch.index.fieldvisitor;
|
||||
exports org.elasticsearch.index.flush;
|
||||
exports org.elasticsearch.index.get;
|
||||
exports org.elasticsearch.index.mapper;
|
||||
exports org.elasticsearch.index.mapper.flattened;
|
||||
exports org.elasticsearch.index.merge;
|
||||
exports org.elasticsearch.index.query;
|
||||
exports org.elasticsearch.index.query.functionscore;
|
||||
exports org.elasticsearch.index.query.support;
|
||||
exports org.elasticsearch.index.recovery;
|
||||
exports org.elasticsearch.index.refresh;
|
||||
exports org.elasticsearch.index.reindex;
|
||||
exports org.elasticsearch.index.search;
|
||||
exports org.elasticsearch.index.search.stats;
|
||||
exports org.elasticsearch.index.seqno;
|
||||
exports org.elasticsearch.index.shard;
|
||||
exports org.elasticsearch.index.similarity;
|
||||
exports org.elasticsearch.index.snapshots;
|
||||
exports org.elasticsearch.index.snapshots.blobstore;
|
||||
exports org.elasticsearch.index.stats;
|
||||
exports org.elasticsearch.index.store;
|
||||
exports org.elasticsearch.index.termvectors;
|
||||
exports org.elasticsearch.index.translog;
|
||||
exports org.elasticsearch.index.warmer;
|
||||
exports org.elasticsearch.indices;
|
||||
exports org.elasticsearch.indices.analysis;
|
||||
exports org.elasticsearch.indices.breaker;
|
||||
exports org.elasticsearch.indices.cluster;
|
||||
exports org.elasticsearch.indices.fielddata.cache;
|
||||
exports org.elasticsearch.indices.recovery;
|
||||
exports org.elasticsearch.indices.recovery.plan;
|
||||
exports org.elasticsearch.indices.store;
|
||||
exports org.elasticsearch.ingest;
|
||||
exports org.elasticsearch.lucene.analysis.miscellaneous;
|
||||
exports org.elasticsearch.lucene.grouping;
|
||||
exports org.elasticsearch.lucene.queries;
|
||||
exports org.elasticsearch.lucene.search.uhighlight;
|
||||
exports org.elasticsearch.lucene.search.vectorhighlight;
|
||||
exports org.elasticsearch.lucene.similarity;
|
||||
exports org.elasticsearch.lucene.util;
|
||||
exports org.elasticsearch.monitor;
|
||||
exports org.elasticsearch.monitor.fs;
|
||||
exports org.elasticsearch.monitor.jvm;
|
||||
exports org.elasticsearch.monitor.os;
|
||||
exports org.elasticsearch.monitor.process;
|
||||
exports org.elasticsearch.node;
|
||||
exports org.elasticsearch.persistent;
|
||||
exports org.elasticsearch.persistent.decider;
|
||||
exports org.elasticsearch.plugins;
|
||||
exports org.elasticsearch.plugins.interceptor to org.elasticsearch.security;
|
||||
exports org.elasticsearch.plugins.spi;
|
||||
exports org.elasticsearch.repositories;
|
||||
exports org.elasticsearch.repositories.blobstore;
|
||||
exports org.elasticsearch.repositories.fs;
|
||||
exports org.elasticsearch.rest;
|
||||
exports org.elasticsearch.rest.action;
|
||||
exports org.elasticsearch.rest.action.admin.cluster;
|
||||
exports org.elasticsearch.rest.action.admin.cluster.dangling;
|
||||
exports org.elasticsearch.rest.action.admin.indices;
|
||||
exports org.elasticsearch.rest.action.cat;
|
||||
exports org.elasticsearch.rest.action.document;
|
||||
exports org.elasticsearch.rest.action.ingest;
|
||||
exports org.elasticsearch.rest.action.search;
|
||||
exports org.elasticsearch.rollup;
|
||||
exports org.elasticsearch.script;
|
||||
exports org.elasticsearch.script.field;
|
||||
exports org.elasticsearch.search;
|
||||
exports org.elasticsearch.search.aggregations;
|
||||
exports org.elasticsearch.search.aggregations.bucket;
|
||||
exports org.elasticsearch.search.aggregations.bucket.adjacency;
|
||||
exports org.elasticsearch.search.aggregations.bucket.composite;
|
||||
exports org.elasticsearch.search.aggregations.bucket.filter;
|
||||
exports org.elasticsearch.search.aggregations.bucket.geogrid;
|
||||
exports org.elasticsearch.search.aggregations.bucket.global;
|
||||
exports org.elasticsearch.search.aggregations.bucket.histogram;
|
||||
exports org.elasticsearch.search.aggregations.bucket.missing;
|
||||
exports org.elasticsearch.search.aggregations.bucket.nested;
|
||||
exports org.elasticsearch.search.aggregations.bucket.range;
|
||||
exports org.elasticsearch.search.aggregations.bucket.sampler;
|
||||
exports org.elasticsearch.search.aggregations.bucket.terms;
|
||||
exports org.elasticsearch.search.aggregations.bucket.terms.heuristic;
|
||||
exports org.elasticsearch.search.aggregations.metrics;
|
||||
exports org.elasticsearch.search.aggregations.pipeline;
|
||||
exports org.elasticsearch.search.aggregations.support;
|
||||
exports org.elasticsearch.search.aggregations.support.values;
|
||||
exports org.elasticsearch.search.aggregations.timeseries;
|
||||
exports org.elasticsearch.search.builder;
|
||||
exports org.elasticsearch.search.collapse;
|
||||
exports org.elasticsearch.search.dfs;
|
||||
exports org.elasticsearch.search.fetch;
|
||||
exports org.elasticsearch.search.fetch.subphase;
|
||||
exports org.elasticsearch.search.fetch.subphase.highlight;
|
||||
exports org.elasticsearch.search.internal;
|
||||
exports org.elasticsearch.search.lookup;
|
||||
exports org.elasticsearch.search.profile;
|
||||
exports org.elasticsearch.search.profile.aggregation;
|
||||
exports org.elasticsearch.search.profile.query;
|
||||
exports org.elasticsearch.search.query;
|
||||
exports org.elasticsearch.search.rescore;
|
||||
exports org.elasticsearch.search.runtime;
|
||||
exports org.elasticsearch.search.searchafter;
|
||||
exports org.elasticsearch.search.slice;
|
||||
exports org.elasticsearch.search.sort;
|
||||
exports org.elasticsearch.search.suggest;
|
||||
exports org.elasticsearch.search.suggest.completion;
|
||||
exports org.elasticsearch.search.suggest.completion.context;
|
||||
exports org.elasticsearch.search.suggest.phrase;
|
||||
exports org.elasticsearch.search.suggest.term;
|
||||
exports org.elasticsearch.shutdown;
|
||||
exports org.elasticsearch.snapshots;
|
||||
exports org.elasticsearch.tasks;
|
||||
exports org.elasticsearch.threadpool;
|
||||
exports org.elasticsearch.timeseries.support;
|
||||
exports org.elasticsearch.transport;
|
||||
exports org.elasticsearch.upgrades;
|
||||
exports org.elasticsearch.usage;
|
||||
exports org.elasticsearch.watcher;
|
||||
|
||||
opens org.elasticsearch.common.logging to org.apache.logging.log4j.core;
|
||||
|
||||
provides java.util.spi.CalendarDataProvider with org.elasticsearch.common.time.IsoCalendarDataProvider;
|
||||
provides org.elasticsearch.xcontent.ErrorOnUnknown with org.elasticsearch.common.xcontent.SuggestingErrorOnUnknown;
|
||||
provides org.elasticsearch.xcontent.XContentBuilderExtension with org.elasticsearch.common.xcontent.XContentElasticsearchExtension;
|
||||
provides org.elasticsearch.cli.CliToolProvider
|
||||
with
|
||||
org.elasticsearch.cluster.coordination.NodeToolCliProvider,
|
||||
org.elasticsearch.index.shard.ShardToolCliProvider;
|
||||
}
|
|
@ -112,7 +112,7 @@ final class Security {
|
|||
static void configure(Environment environment, boolean filterBadDefaults) throws IOException, NoSuchAlgorithmException {
|
||||
|
||||
// enable security policy: union of template and environment-based paths, and possibly plugin permissions
|
||||
Map<String, URL> codebases = PolicyUtil.getCodebaseJarMap(JarHell.parseClassPath());
|
||||
Map<String, URL> codebases = PolicyUtil.getCodebaseJarMap(JarHell.parseModulesAndClassPath());
|
||||
Policy.setPolicy(
|
||||
new ESPolicy(
|
||||
codebases,
|
||||
|
|
|
@ -55,6 +55,10 @@ class PluginBundle {
|
|||
return urls;
|
||||
}
|
||||
|
||||
boolean hasSPI() {
|
||||
return spiUrls != null;
|
||||
}
|
||||
|
||||
Set<URL> getExtensionUrls() {
|
||||
if (spiUrls != null) {
|
||||
return spiUrls;
|
||||
|
|
|
@ -20,13 +20,21 @@ import org.elasticsearch.common.settings.Setting;
|
|||
import org.elasticsearch.common.settings.Setting.Property;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.util.set.Sets;
|
||||
import org.elasticsearch.core.PathUtils;
|
||||
import org.elasticsearch.core.SuppressForbidden;
|
||||
import org.elasticsearch.core.Tuple;
|
||||
import org.elasticsearch.jdk.JarHell;
|
||||
import org.elasticsearch.node.ReportingService;
|
||||
import org.elasticsearch.plugins.spi.SPIClassIterator;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.ModuleLayer.Controller;
|
||||
import java.lang.module.Configuration;
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import java.lang.module.ModuleFinder;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.nio.file.Path;
|
||||
|
@ -41,6 +49,7 @@ import java.util.LinkedHashSet;
|
|||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
@ -56,8 +65,25 @@ public class PluginsService implements ReportingService<PluginsAndModules> {
|
|||
* @param info Metadata about the plugin, usually loaded from plugin properties
|
||||
* @param instance The constructed instance of the plugin's main class
|
||||
* @param loader The classloader for the plugin
|
||||
* @param layer The module layer for the plugin
|
||||
*/
|
||||
record LoadedPlugin(PluginInfo info, Plugin instance, ClassLoader loader) {}
|
||||
record LoadedPlugin(PluginInfo info, Plugin instance, ClassLoader loader, ModuleLayer layer) {
|
||||
|
||||
LoadedPlugin {
|
||||
Objects.requireNonNull(info);
|
||||
Objects.requireNonNull(instance);
|
||||
Objects.requireNonNull(loader);
|
||||
Objects.requireNonNull(layer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a loaded <i>classpath plugin</i>. A <i>classpath plugin</i> is a plugin loaded
|
||||
* by the system classloader and defined to the unnamed module of the boot layer.
|
||||
*/
|
||||
LoadedPlugin(PluginInfo info, Plugin instance) {
|
||||
this(info, instance, PluginsService.class.getClassLoader(), ModuleLayer.boot());
|
||||
}
|
||||
}
|
||||
|
||||
private static final Logger logger = LogManager.getLogger(PluginsService.class);
|
||||
|
||||
|
@ -119,7 +145,7 @@ public class PluginsService implements ReportingService<PluginsAndModules> {
|
|||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("plugin loaded from classpath [{}]", pluginInfo);
|
||||
}
|
||||
pluginsLoaded.add(new LoadedPlugin(pluginInfo, plugin, null));
|
||||
pluginsLoaded.add(new LoadedPlugin(pluginInfo, plugin));
|
||||
pluginsList.add(pluginInfo);
|
||||
pluginsNames.add(pluginInfo.getName());
|
||||
}
|
||||
|
@ -354,11 +380,12 @@ public class PluginsService implements ReportingService<PluginsAndModules> {
|
|||
|
||||
private Plugin loadBundle(PluginBundle bundle, Map<String, LoadedPlugin> loaded) {
|
||||
String name = bundle.plugin.getName();
|
||||
logger.debug(() -> "Loading bundle: " + name);
|
||||
|
||||
PluginsUtils.verifyCompatibility(bundle.plugin);
|
||||
|
||||
// collect loaders of extended plugins
|
||||
List<ClassLoader> extendedLoaders = new ArrayList<>();
|
||||
// collect the list of extended plugins
|
||||
List<LoadedPlugin> extendedPlugins = new ArrayList<>();
|
||||
for (String extendedPluginName : bundle.plugin.getExtendedPlugins()) {
|
||||
LoadedPlugin extendedPlugin = loaded.get(extendedPluginName);
|
||||
assert extendedPlugin != null;
|
||||
|
@ -366,36 +393,42 @@ public class PluginsService implements ReportingService<PluginsAndModules> {
|
|||
throw new IllegalStateException("Plugin [" + name + "] cannot extend non-extensible plugin [" + extendedPluginName + "]");
|
||||
}
|
||||
assert extendedPlugin.loader() != null : "All non-classpath plugins should be loaded with a classloader";
|
||||
extendedLoaders.add(extendedPlugin.loader());
|
||||
extendedPlugins.add(extendedPlugin);
|
||||
logger.debug(
|
||||
() -> "Loading bundle: " + name + ", ext plugins: " + extendedPlugins.stream().map(lp -> lp.info().getName()).toList()
|
||||
);
|
||||
}
|
||||
|
||||
ClassLoader parentLoader = PluginLoaderIndirection.createLoader(getClass().getClassLoader(), extendedLoaders);
|
||||
ClassLoader spiLoader = null;
|
||||
if (bundle.spiUrls != null) {
|
||||
spiLoader = URLClassLoader.newInstance(bundle.spiUrls.toArray(new URL[0]), parentLoader);
|
||||
final ClassLoader parentLoader = PluginLoaderIndirection.createLoader(
|
||||
getClass().getClassLoader(),
|
||||
extendedPlugins.stream().map(LoadedPlugin::loader).toList()
|
||||
);
|
||||
LayerAndLoader spiLayerAndLoader = null;
|
||||
if (bundle.hasSPI()) {
|
||||
spiLayerAndLoader = createSPI(bundle, parentLoader, extendedPlugins);
|
||||
}
|
||||
|
||||
ClassLoader loader = URLClassLoader.newInstance(bundle.urls.toArray(new URL[0]), spiLoader == null ? parentLoader : spiLoader);
|
||||
if (spiLoader == null) {
|
||||
final ClassLoader pluginParentLoader = spiLayerAndLoader == null ? parentLoader : spiLayerAndLoader.loader();
|
||||
final LayerAndLoader pluginLayerAndLoader = createPlugin(bundle, pluginParentLoader, extendedPlugins, spiLayerAndLoader);
|
||||
final ClassLoader pluginClassLoader = pluginLayerAndLoader.loader();
|
||||
|
||||
if (spiLayerAndLoader == null) {
|
||||
// use full implementation for plugins extending this one
|
||||
spiLoader = loader;
|
||||
spiLayerAndLoader = pluginLayerAndLoader;
|
||||
}
|
||||
|
||||
// reload SPI with any new services from the plugin
|
||||
reloadLuceneSPI(loader);
|
||||
reloadLuceneSPI(pluginClassLoader);
|
||||
|
||||
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
||||
try {
|
||||
// Set context class loader to plugin's class loader so that plugins
|
||||
// that have dependencies with their own SPI endpoints have a chance to load
|
||||
// and initialize them appropriately.
|
||||
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
|
||||
Thread.currentThread().setContextClassLoader(loader);
|
||||
return null;
|
||||
});
|
||||
privilegedSetContextClassLoader(pluginClassLoader);
|
||||
|
||||
Class<? extends Plugin> pluginClass = loadPluginClass(bundle.plugin.getClassname(), loader);
|
||||
if (loader != pluginClass.getClassLoader()) {
|
||||
Class<? extends Plugin> pluginClass = loadPluginClass(bundle.plugin.getClassname(), pluginClassLoader);
|
||||
if (pluginClassLoader != pluginClass.getClassLoader()) {
|
||||
throw new IllegalStateException(
|
||||
"Plugin ["
|
||||
+ name
|
||||
|
@ -407,13 +440,41 @@ public class PluginsService implements ReportingService<PluginsAndModules> {
|
|||
);
|
||||
}
|
||||
Plugin plugin = loadPlugin(pluginClass, settings, configPath);
|
||||
loaded.put(name, new LoadedPlugin(bundle.plugin, plugin, spiLoader));
|
||||
loaded.put(name, new LoadedPlugin(bundle.plugin, plugin, spiLayerAndLoader.loader(), spiLayerAndLoader.layer()));
|
||||
return plugin;
|
||||
} finally {
|
||||
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
|
||||
Thread.currentThread().setContextClassLoader(cl);
|
||||
return null;
|
||||
});
|
||||
privilegedSetContextClassLoader(cl);
|
||||
}
|
||||
}
|
||||
|
||||
static LayerAndLoader createSPI(PluginBundle bundle, ClassLoader parentLoader, List<LoadedPlugin> extendedPlugins) {
|
||||
final PluginInfo plugin = bundle.plugin;
|
||||
if (plugin.getModuleName().isPresent()) {
|
||||
logger.debug(() -> "Loading bundle: " + plugin.getName() + ", creating spi, modular");
|
||||
return createSpiModuleLayer(bundle.spiUrls, parentLoader, extendedPlugins.stream().map(LoadedPlugin::layer).toList());
|
||||
} else {
|
||||
logger.debug(() -> "Loading bundle: " + plugin.getName() + ", creating spi, non-modular");
|
||||
return LayerAndLoader.ofLoader(URLClassLoader.newInstance(bundle.spiUrls.toArray(new URL[0]), parentLoader));
|
||||
}
|
||||
}
|
||||
|
||||
static LayerAndLoader createPlugin(
|
||||
PluginBundle bundle,
|
||||
ClassLoader pluginParentLoader,
|
||||
List<LoadedPlugin> extendedPlugins,
|
||||
LayerAndLoader spiLayerAndLoader
|
||||
) {
|
||||
final PluginInfo plugin = bundle.plugin;
|
||||
if (plugin.getModuleName().isPresent()) {
|
||||
logger.debug(() -> "Loading bundle: " + plugin.getName() + ", modular");
|
||||
var parentLayers = Stream.concat(
|
||||
Stream.ofNullable(spiLayerAndLoader != null ? spiLayerAndLoader.layer() : null),
|
||||
extendedPlugins.stream().map(LoadedPlugin::layer)
|
||||
).toList();
|
||||
return createPluginModuleLayer(bundle, pluginParentLoader, parentLayers);
|
||||
} else {
|
||||
logger.debug(() -> "Loading bundle: " + plugin.getName() + ", non-modular");
|
||||
return LayerAndLoader.ofLoader(URLClassLoader.newInstance(bundle.urls.toArray(URL[]::new), pluginParentLoader));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -485,4 +546,171 @@ public class PluginsService implements ReportingService<PluginsAndModules> {
|
|||
public <T> List<T> filterPlugins(Class<T> type) {
|
||||
return plugins.stream().filter(x -> type.isAssignableFrom(x.instance().getClass())).map(p -> ((T) p.instance())).toList();
|
||||
}
|
||||
|
||||
static final LayerAndLoader createPluginModuleLayer(PluginBundle bundle, ClassLoader parentLoader, List<ModuleLayer> parentLayers) {
|
||||
assert bundle.plugin.getModuleName().isPresent();
|
||||
return createModuleLayer(
|
||||
bundle.plugin.getClassname(),
|
||||
bundle.plugin.getModuleName().get(),
|
||||
urlsToPaths(bundle.urls),
|
||||
parentLoader,
|
||||
parentLayers
|
||||
);
|
||||
}
|
||||
|
||||
static final LayerAndLoader createSpiModuleLayer(Set<URL> urls, ClassLoader parentLoader, List<ModuleLayer> parentLayers) {
|
||||
// assert bundle.plugin.getModuleName().isPresent();
|
||||
return createModuleLayer(
|
||||
null, // no entry point
|
||||
spiModuleName(urls),
|
||||
urlsToPaths(urls),
|
||||
parentLoader,
|
||||
parentLayers
|
||||
);
|
||||
}
|
||||
|
||||
private static final Module serverModule = PluginsService.class.getModule();
|
||||
|
||||
static final LayerAndLoader createModuleLayer(
|
||||
String className,
|
||||
String moduleName,
|
||||
Path[] paths,
|
||||
ClassLoader parentLoader,
|
||||
List<ModuleLayer> parentLayers
|
||||
) {
|
||||
logger.debug(() -> "Loading bundle: creating module layer and loader for module " + moduleName);
|
||||
var finder = ModuleFinder.of(paths);
|
||||
|
||||
var configuration = Configuration.resolveAndBind(
|
||||
ModuleFinder.of(),
|
||||
parentConfigurationOrBoot(parentLayers),
|
||||
finder,
|
||||
Set.of(moduleName)
|
||||
);
|
||||
var controller = privilegedDefineModulesWithOneLoader(configuration, parentLayersOrBoot(parentLayers), parentLoader);
|
||||
var pluginModule = controller.layer().findModule(moduleName).get();
|
||||
ensureEntryPointAccessible(controller, pluginModule, className);
|
||||
addQualifiedExports(pluginModule);
|
||||
addQualifiedOpens(pluginModule);
|
||||
logger.debug(() -> "Loading bundle: created module layer and loader for module " + moduleName);
|
||||
return new LayerAndLoader(controller.layer(), privilegedFindLoader(controller.layer(), moduleName));
|
||||
}
|
||||
|
||||
private static List<ModuleLayer> parentLayersOrBoot(List<ModuleLayer> parentLayers) {
|
||||
if (parentLayers == null || parentLayers.isEmpty()) {
|
||||
return List.of(ModuleLayer.boot());
|
||||
} else {
|
||||
return parentLayers;
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Configuration> parentConfigurationOrBoot(List<ModuleLayer> parentLayers) {
|
||||
if (parentLayers == null || parentLayers.isEmpty()) {
|
||||
return List.of(ModuleLayer.boot().configuration());
|
||||
} else {
|
||||
return parentLayers.stream().map(ModuleLayer::configuration).toList();
|
||||
}
|
||||
}
|
||||
|
||||
/** Ensures that the plugins main class (its entry point), if any, is accessible to the server. */
|
||||
private static void ensureEntryPointAccessible(Controller controller, Module pluginModule, String className) {
|
||||
if (className != null) {
|
||||
controller.addOpens(pluginModule, toPackageName(className), serverModule);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds qualified exports declared in the server module descriptor to the target module.
|
||||
* This is required since qualified exports targeting yet-to-be-created modules, i.e. plugins,
|
||||
* are silently dropped when the boot layer is created.
|
||||
*/
|
||||
private static void addQualifiedExports(Module target) {
|
||||
serverModule.getDescriptor()
|
||||
.exports()
|
||||
.stream()
|
||||
.filter(ModuleDescriptor.Exports::isQualified)
|
||||
.filter(exports -> exports.targets().contains(target.getName()))
|
||||
.forEach(exports -> serverModule.addExports(exports.source(), target));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds qualified opens declared in the server module descriptor to the target module.
|
||||
* This is required since qualified opens targeting yet-to-be-created modules, i.e. plugins,
|
||||
* are silently dropped when the boot layer is created.
|
||||
*/
|
||||
private static void addQualifiedOpens(Module target) {
|
||||
serverModule.getDescriptor()
|
||||
.opens()
|
||||
.stream()
|
||||
.filter(ModuleDescriptor.Opens::isQualified)
|
||||
.filter(opens -> opens.targets().contains(target.getName()))
|
||||
.forEach(opens -> serverModule.addExports(opens.source(), target));
|
||||
}
|
||||
|
||||
/** Determines the module name of the SPI module, given its URL. */
|
||||
static String spiModuleName(Set<URL> spiURLS) {
|
||||
ModuleFinder finder = ModuleFinder.of(urlsToPaths(spiURLS));
|
||||
var mrefs = finder.findAll();
|
||||
assert mrefs.size() == 1 : "Expected a single module, got:" + mrefs;
|
||||
return mrefs.stream().findFirst().get().descriptor().name();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tuple of module layer and loader.
|
||||
* Modular Plugins have a plugin specific loader and layer.
|
||||
* Non-Modular plugins have a plugin specific loader and the boot layer.
|
||||
*/
|
||||
record LayerAndLoader(ModuleLayer layer, ClassLoader loader) {
|
||||
|
||||
LayerAndLoader {
|
||||
Objects.requireNonNull(layer);
|
||||
Objects.requireNonNull(loader);
|
||||
}
|
||||
|
||||
static LayerAndLoader ofLoader(ClassLoader loader) {
|
||||
return new LayerAndLoader(ModuleLayer.boot(), loader);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressForbidden(reason = "I need to convert URL's to Paths")
|
||||
static final Path[] urlsToPaths(Set<URL> urls) {
|
||||
return urls.stream().map(PluginsService::uncheckedToURI).map(PathUtils::get).toArray(Path[]::new);
|
||||
}
|
||||
|
||||
static final URI uncheckedToURI(URL url) {
|
||||
try {
|
||||
return url.toURI();
|
||||
} catch (URISyntaxException e) {
|
||||
throw new AssertionError(new IOException(e));
|
||||
}
|
||||
}
|
||||
|
||||
static final String toPackageName(String className) {
|
||||
assert className.endsWith(".") == false;
|
||||
int index = className.lastIndexOf(".");
|
||||
if (index == -1) {
|
||||
throw new IllegalStateException("invalid class name:" + className);
|
||||
}
|
||||
return className.substring(0, index);
|
||||
}
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
private static void privilegedSetContextClassLoader(ClassLoader loader) {
|
||||
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
|
||||
Thread.currentThread().setContextClassLoader(loader);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
static Controller privilegedDefineModulesWithOneLoader(Configuration cf, List<ModuleLayer> parentLayers, ClassLoader parentLoader) {
|
||||
return AccessController.doPrivileged(
|
||||
(PrivilegedAction<Controller>) () -> ModuleLayer.defineModulesWithOneLoader(cf, parentLayers, parentLoader)
|
||||
);
|
||||
}
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
static ClassLoader privilegedFindLoader(ModuleLayer layer, String name) {
|
||||
return AccessController.doPrivileged((PrivilegedAction<ClassLoader>) () -> layer.findLoader(name));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,10 @@ grant codeBase "${codebase.elasticsearch}" {
|
|||
permission java.net.SocketPermission "127.0.0.1", "listen, accept";
|
||||
// required if started with -Djava.net.preferIPv6Addresses=true
|
||||
permission java.net.SocketPermission "0:0:0:0:0:0:0:1", "listen, accept";
|
||||
|
||||
// for module layer
|
||||
permission java.lang.RuntimePermission "createClassLoader";
|
||||
permission java.lang.RuntimePermission "getClassLoader";
|
||||
};
|
||||
|
||||
//// Very special jar permissions:
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.module;
|
||||
|
||||
import org.elasticsearch.core.PathUtils;
|
||||
import org.elasticsearch.core.SuppressForbidden;
|
||||
import org.elasticsearch.jdk.JarHell;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import java.lang.module.ModuleFinder;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.util.function.Predicate.not;
|
||||
import static org.elasticsearch.test.hamcrest.ModuleDescriptorMatchers.exportsOf;
|
||||
import static org.elasticsearch.test.hamcrest.ModuleDescriptorMatchers.opensOf;
|
||||
import static org.elasticsearch.test.hamcrest.OptionalMatchers.isPresent;
|
||||
import static org.hamcrest.Matchers.empty;
|
||||
import static org.hamcrest.Matchers.hasItem;
|
||||
|
||||
public class BasicServerModuleTests extends ESTestCase {
|
||||
|
||||
private static final String SERVER_MODULE_NAME = "org.elasticsearch.server";
|
||||
|
||||
public void testQualifiedExports() {
|
||||
var md = getServerDescriptor();
|
||||
|
||||
// The package containing the RestInterceptor type, org.elasticsearch.plugins.interceptor,
|
||||
// should only be exported to security.
|
||||
assertThat(md.exports(), hasItem(exportsOf("org.elasticsearch.plugins.interceptor", Set.of("org.elasticsearch.security"))));
|
||||
|
||||
// additional qualified export constraint go here
|
||||
}
|
||||
|
||||
// Ensures that there are no unqualified opens - too dangerous
|
||||
public void testEnsureNoUnqualifiedOpens() {
|
||||
var md = getServerDescriptor();
|
||||
assertThat(md.opens().stream().filter(not(ModuleDescriptor.Opens::isQualified)).collect(Collectors.toSet()), empty());
|
||||
}
|
||||
|
||||
public void testQualifiedOpens() {
|
||||
var md = getServerDescriptor();
|
||||
|
||||
// We tolerate introspection by log4j, for Plugins, e.g. ECSJsonLayout
|
||||
assertThat(md.opens(), hasItem(opensOf("org.elasticsearch.common.logging", Set.of("org.apache.logging.log4j.core"))));
|
||||
|
||||
// additional qualified opens constraint go here
|
||||
}
|
||||
|
||||
private static ModuleDescriptor getServerDescriptor() {
|
||||
var finder = ModuleFinder.of(urlsToPaths(JarHell.parseClassPath()));
|
||||
var omref = finder.find(SERVER_MODULE_NAME);
|
||||
assertThat(omref, isPresent());
|
||||
return omref.get().descriptor();
|
||||
}
|
||||
|
||||
@SuppressForbidden(reason = "I need to convert URL's to Paths")
|
||||
private static Path[] urlsToPaths(Set<URL> urls) {
|
||||
return urls.stream().map(BasicServerModuleTests::uncheckedToURI).map(PathUtils::get).toArray(Path[]::new);
|
||||
}
|
||||
|
||||
private static URI uncheckedToURI(URL url) {
|
||||
try {
|
||||
return url.toURI();
|
||||
} catch (URISyntaxException e) {
|
||||
throw new UncheckedIOException(new IOException(e));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -460,8 +460,7 @@ public class PluginsServiceTests extends ESTestCase {
|
|||
List.of(
|
||||
new PluginsService.LoadedPlugin(
|
||||
new PluginInfo("extensible", null, null, null, null, null, null, List.of(), false, PluginType.ISOLATED, "", false),
|
||||
extensiblePlugin,
|
||||
null
|
||||
extensiblePlugin
|
||||
)
|
||||
)
|
||||
);
|
||||
|
@ -475,8 +474,7 @@ public class PluginsServiceTests extends ESTestCase {
|
|||
List.of(
|
||||
new PluginsService.LoadedPlugin(
|
||||
new PluginInfo("extensible", null, null, null, null, null, null, List.of(), false, PluginType.ISOLATED, "", false),
|
||||
extensiblePlugin,
|
||||
null
|
||||
extensiblePlugin
|
||||
),
|
||||
new PluginsService.LoadedPlugin(
|
||||
new PluginInfo(
|
||||
|
@ -493,8 +491,7 @@ public class PluginsServiceTests extends ESTestCase {
|
|||
"",
|
||||
false
|
||||
),
|
||||
testPlugin,
|
||||
null
|
||||
testPlugin
|
||||
)
|
||||
)
|
||||
);
|
||||
|
|
|
@ -110,7 +110,7 @@ public class DieWithDignityIT extends ESRestTestCase {
|
|||
String jvmArgs = null;
|
||||
String line;
|
||||
while ((line = in.readLine()) != null) {
|
||||
if (line.equals("java_command: org.elasticsearch.bootstrap.Elasticsearch")) {
|
||||
if (line.equals("java_command: org.elasticsearch.server/org.elasticsearch.bootstrap.Elasticsearch")) {
|
||||
isElasticsearch = true;
|
||||
}
|
||||
if (line.startsWith("jvm_args")) {
|
||||
|
|
|
@ -0,0 +1,213 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
module org.elasticsearch.xcore {
|
||||
requires org.elasticsearch.cli;
|
||||
requires org.elasticsearch.base;
|
||||
requires org.elasticsearch.server;
|
||||
requires org.elasticsearch.sslconfig;
|
||||
requires org.elasticsearch.xcontent;
|
||||
requires org.apache.httpcomponents.httpcore;
|
||||
requires org.apache.httpcomponents.httpclient;
|
||||
requires org.apache.httpcomponents.httpasyncclient;
|
||||
requires org.apache.httpcomponents.httpcore.nio;
|
||||
requires org.apache.logging.log4j;
|
||||
requires org.apache.lucene.core;
|
||||
requires org.apache.lucene.join;
|
||||
requires unboundid.ldapsdk;
|
||||
|
||||
exports org.elasticsearch.index.engine.frozen;
|
||||
exports org.elasticsearch.license;
|
||||
exports org.elasticsearch.protocol.xpack.common;
|
||||
exports org.elasticsearch.protocol.xpack.frozen;
|
||||
exports org.elasticsearch.protocol.xpack.graph;
|
||||
exports org.elasticsearch.protocol.xpack.license;
|
||||
exports org.elasticsearch.protocol.xpack.watcher;
|
||||
exports org.elasticsearch.protocol.xpack;
|
||||
exports org.elasticsearch.snapshots.sourceonly;
|
||||
exports org.elasticsearch.xpack.cluster.action;
|
||||
exports org.elasticsearch.xpack.cluster.routing.allocation.mapper;
|
||||
exports org.elasticsearch.xpack.cluster.routing.allocation;
|
||||
exports org.elasticsearch.xpack.core;
|
||||
exports org.elasticsearch.xpack.core.action.util;
|
||||
exports org.elasticsearch.xpack.core.action;
|
||||
exports org.elasticsearch.xpack.core.aggregatemetric;
|
||||
exports org.elasticsearch.xpack.core.analytics.action;
|
||||
exports org.elasticsearch.xpack.core.analytics;
|
||||
exports org.elasticsearch.xpack.core.archive;
|
||||
exports org.elasticsearch.xpack.core.async;
|
||||
exports org.elasticsearch.xpack.core.ccr.action;
|
||||
exports org.elasticsearch.xpack.core.ccr;
|
||||
exports org.elasticsearch.xpack.core.common.notifications;
|
||||
exports org.elasticsearch.xpack.core.common.search.aggregations;
|
||||
exports org.elasticsearch.xpack.core.common.socket;
|
||||
exports org.elasticsearch.xpack.core.common.stats;
|
||||
exports org.elasticsearch.xpack.core.common.table;
|
||||
exports org.elasticsearch.xpack.core.common.time;
|
||||
exports org.elasticsearch.xpack.core.common.validation;
|
||||
exports org.elasticsearch.xpack.core.common;
|
||||
exports org.elasticsearch.xpack.core.datastreams;
|
||||
exports org.elasticsearch.xpack.core.deprecation;
|
||||
exports org.elasticsearch.xpack.core.enrich.action;
|
||||
exports org.elasticsearch.xpack.core.enrich;
|
||||
exports org.elasticsearch.xpack.core.eql;
|
||||
exports org.elasticsearch.xpack.core.frozen.action;
|
||||
exports org.elasticsearch.xpack.core.frozen;
|
||||
exports org.elasticsearch.xpack.core.graph.action;
|
||||
exports org.elasticsearch.xpack.core.graph;
|
||||
exports org.elasticsearch.xpack.core.ilm.action;
|
||||
exports org.elasticsearch.xpack.core.ilm.step.info;
|
||||
exports org.elasticsearch.xpack.core.ilm;
|
||||
exports org.elasticsearch.xpack.core.index.query;
|
||||
exports org.elasticsearch.xpack.core.indexing;
|
||||
exports org.elasticsearch.xpack.core.logstash;
|
||||
exports org.elasticsearch.xpack.core.ml.action;
|
||||
exports org.elasticsearch.xpack.core.ml.annotations;
|
||||
exports org.elasticsearch.xpack.core.ml.calendars;
|
||||
exports org.elasticsearch.xpack.core.ml.datafeed.extractor;
|
||||
exports org.elasticsearch.xpack.core.ml.datafeed;
|
||||
exports org.elasticsearch.xpack.core.ml.dataframe.analyses;
|
||||
exports org.elasticsearch.xpack.core.ml.dataframe.evaluation.classification;
|
||||
exports org.elasticsearch.xpack.core.ml.dataframe.evaluation.common;
|
||||
exports org.elasticsearch.xpack.core.ml.dataframe.evaluation.outlierdetection;
|
||||
exports org.elasticsearch.xpack.core.ml.dataframe.evaluation.regression;
|
||||
exports org.elasticsearch.xpack.core.ml.dataframe.evaluation;
|
||||
exports org.elasticsearch.xpack.core.ml.dataframe.explain;
|
||||
exports org.elasticsearch.xpack.core.ml.dataframe.stats.classification;
|
||||
exports org.elasticsearch.xpack.core.ml.dataframe.stats.common;
|
||||
exports org.elasticsearch.xpack.core.ml.dataframe.stats.outlierdetection;
|
||||
exports org.elasticsearch.xpack.core.ml.dataframe.stats.regression;
|
||||
exports org.elasticsearch.xpack.core.ml.dataframe.stats;
|
||||
exports org.elasticsearch.xpack.core.ml.dataframe;
|
||||
exports org.elasticsearch.xpack.core.ml.inference.assignment;
|
||||
exports org.elasticsearch.xpack.core.ml.inference.persistence;
|
||||
exports org.elasticsearch.xpack.core.ml.inference.preprocessing.customwordembedding;
|
||||
exports org.elasticsearch.xpack.core.ml.inference.preprocessing;
|
||||
exports org.elasticsearch.xpack.core.ml.inference.results;
|
||||
exports org.elasticsearch.xpack.core.ml.inference.trainedmodel.ensemble;
|
||||
exports org.elasticsearch.xpack.core.ml.inference.trainedmodel.inference;
|
||||
exports org.elasticsearch.xpack.core.ml.inference.trainedmodel.langident;
|
||||
exports org.elasticsearch.xpack.core.ml.inference.trainedmodel.metadata;
|
||||
exports org.elasticsearch.xpack.core.ml.inference.trainedmodel.tree;
|
||||
exports org.elasticsearch.xpack.core.ml.inference.trainedmodel;
|
||||
exports org.elasticsearch.xpack.core.ml.inference.utils;
|
||||
exports org.elasticsearch.xpack.core.ml.inference;
|
||||
exports org.elasticsearch.xpack.core.ml.job.config;
|
||||
exports org.elasticsearch.xpack.core.ml.job.groups;
|
||||
exports org.elasticsearch.xpack.core.ml.job.messages;
|
||||
exports org.elasticsearch.xpack.core.ml.job.persistence;
|
||||
exports org.elasticsearch.xpack.core.ml.job.process.autodetect.output;
|
||||
exports org.elasticsearch.xpack.core.ml.job.process.autodetect.state;
|
||||
exports org.elasticsearch.xpack.core.ml.job.results;
|
||||
exports org.elasticsearch.xpack.core.ml.job.snapshot.upgrade;
|
||||
exports org.elasticsearch.xpack.core.ml.notifications;
|
||||
exports org.elasticsearch.xpack.core.ml.process.writer;
|
||||
exports org.elasticsearch.xpack.core.ml.stats;
|
||||
exports org.elasticsearch.xpack.core.ml.utils.time;
|
||||
exports org.elasticsearch.xpack.core.ml.utils;
|
||||
exports org.elasticsearch.xpack.core.ml;
|
||||
exports org.elasticsearch.xpack.core.monitoring.action;
|
||||
exports org.elasticsearch.xpack.core.monitoring.exporter;
|
||||
exports org.elasticsearch.xpack.core.monitoring;
|
||||
exports org.elasticsearch.xpack.core.rest.action;
|
||||
exports org.elasticsearch.xpack.core.rollup.action;
|
||||
exports org.elasticsearch.xpack.core.rollup.job;
|
||||
exports org.elasticsearch.xpack.core.rollup;
|
||||
exports org.elasticsearch.xpack.core.scheduler;
|
||||
exports org.elasticsearch.xpack.core.search.action;
|
||||
exports org.elasticsearch.xpack.core.searchablesnapshots;
|
||||
exports org.elasticsearch.xpack.core.security.action.apikey;
|
||||
exports org.elasticsearch.xpack.core.security.action.enrollment;
|
||||
exports org.elasticsearch.xpack.core.security.action.oidc;
|
||||
exports org.elasticsearch.xpack.core.security.action.privilege;
|
||||
exports org.elasticsearch.xpack.core.security.action.profile;
|
||||
exports org.elasticsearch.xpack.core.security.action.realm;
|
||||
exports org.elasticsearch.xpack.core.security.action.role;
|
||||
exports org.elasticsearch.xpack.core.security.action.rolemapping;
|
||||
exports org.elasticsearch.xpack.core.security.action.saml;
|
||||
exports org.elasticsearch.xpack.core.security.action.service;
|
||||
exports org.elasticsearch.xpack.core.security.action.token;
|
||||
exports org.elasticsearch.xpack.core.security.action.user;
|
||||
exports org.elasticsearch.xpack.core.security.action;
|
||||
exports org.elasticsearch.xpack.core.security.authc.esnative;
|
||||
exports org.elasticsearch.xpack.core.security.authc.file;
|
||||
exports org.elasticsearch.xpack.core.security.authc.jwt;
|
||||
exports org.elasticsearch.xpack.core.security.authc.kerberos;
|
||||
exports org.elasticsearch.xpack.core.security.authc.ldap.support;
|
||||
exports org.elasticsearch.xpack.core.security.authc.ldap;
|
||||
exports org.elasticsearch.xpack.core.security.authc.oidc;
|
||||
exports org.elasticsearch.xpack.core.security.authc.pki;
|
||||
exports org.elasticsearch.xpack.core.security.authc.saml;
|
||||
exports org.elasticsearch.xpack.core.security.authc.service;
|
||||
exports org.elasticsearch.xpack.core.security.authc.support.mapper.expressiondsl;
|
||||
exports org.elasticsearch.xpack.core.security.authc.support.mapper;
|
||||
exports org.elasticsearch.xpack.core.security.authc.support;
|
||||
exports org.elasticsearch.xpack.core.security.authc;
|
||||
exports org.elasticsearch.xpack.core.security.authz.accesscontrol;
|
||||
exports org.elasticsearch.xpack.core.security.authz.permission;
|
||||
exports org.elasticsearch.xpack.core.security.authz.privilege;
|
||||
exports org.elasticsearch.xpack.core.security.authz.store;
|
||||
exports org.elasticsearch.xpack.core.security.authz.support;
|
||||
exports org.elasticsearch.xpack.core.security.authz;
|
||||
exports org.elasticsearch.xpack.core.security.index;
|
||||
exports org.elasticsearch.xpack.core.security.support;
|
||||
exports org.elasticsearch.xpack.core.security.user;
|
||||
exports org.elasticsearch.xpack.core.security.xcontent;
|
||||
exports org.elasticsearch.xpack.core.security;
|
||||
exports org.elasticsearch.xpack.core.slm.action;
|
||||
exports org.elasticsearch.xpack.core.slm;
|
||||
exports org.elasticsearch.xpack.core.spatial.action;
|
||||
exports org.elasticsearch.xpack.core.spatial.search.aggregations;
|
||||
exports org.elasticsearch.xpack.core.spatial;
|
||||
exports org.elasticsearch.xpack.core.sql;
|
||||
exports org.elasticsearch.xpack.core.ssl.action;
|
||||
exports org.elasticsearch.xpack.core.ssl.cert;
|
||||
exports org.elasticsearch.xpack.core.ssl.rest;
|
||||
exports org.elasticsearch.xpack.core.ssl;
|
||||
exports org.elasticsearch.xpack.core.template;
|
||||
exports org.elasticsearch.xpack.core.termsenum.action;
|
||||
exports org.elasticsearch.xpack.core.termsenum.rest;
|
||||
exports org.elasticsearch.xpack.core.textstructure.action;
|
||||
exports org.elasticsearch.xpack.core.textstructure.structurefinder;
|
||||
exports org.elasticsearch.xpack.core.transform.action;
|
||||
exports org.elasticsearch.xpack.core.transform.notifications;
|
||||
exports org.elasticsearch.xpack.core.transform.transforms.latest;
|
||||
exports org.elasticsearch.xpack.core.transform.transforms.persistence;
|
||||
exports org.elasticsearch.xpack.core.transform.transforms.pivot;
|
||||
exports org.elasticsearch.xpack.core.transform.transforms;
|
||||
exports org.elasticsearch.xpack.core.transform.utils;
|
||||
exports org.elasticsearch.xpack.core.transform;
|
||||
exports org.elasticsearch.xpack.core.upgrade;
|
||||
exports org.elasticsearch.xpack.core.votingonly;
|
||||
exports org.elasticsearch.xpack.core.watcher.actions.throttler;
|
||||
exports org.elasticsearch.xpack.core.watcher.actions;
|
||||
exports org.elasticsearch.xpack.core.watcher.client;
|
||||
exports org.elasticsearch.xpack.core.watcher.common.secret;
|
||||
exports org.elasticsearch.xpack.core.watcher.common.stats;
|
||||
exports org.elasticsearch.xpack.core.watcher.condition;
|
||||
exports org.elasticsearch.xpack.core.watcher.crypto;
|
||||
exports org.elasticsearch.xpack.core.watcher.execution;
|
||||
exports org.elasticsearch.xpack.core.watcher.history;
|
||||
exports org.elasticsearch.xpack.core.watcher.input.none;
|
||||
exports org.elasticsearch.xpack.core.watcher.input;
|
||||
exports org.elasticsearch.xpack.core.watcher.support.xcontent;
|
||||
exports org.elasticsearch.xpack.core.watcher.support;
|
||||
exports org.elasticsearch.xpack.core.watcher.transform.chain;
|
||||
exports org.elasticsearch.xpack.core.watcher.transform;
|
||||
exports org.elasticsearch.xpack.core.watcher.transport.actions.ack;
|
||||
exports org.elasticsearch.xpack.core.watcher.transport.actions.activate;
|
||||
exports org.elasticsearch.xpack.core.watcher.transport.actions.delete;
|
||||
exports org.elasticsearch.xpack.core.watcher.transport.actions.execute;
|
||||
exports org.elasticsearch.xpack.core.watcher.transport.actions.get;
|
||||
exports org.elasticsearch.xpack.core.watcher.transport.actions.put;
|
||||
exports org.elasticsearch.xpack.core.watcher.transport.actions.service;
|
||||
exports org.elasticsearch.xpack.core.watcher.transport.actions.stats;
|
||||
exports org.elasticsearch.xpack.core.watcher.transport.actions;
|
||||
exports org.elasticsearch.xpack.core.watcher.trigger;
|
||||
exports org.elasticsearch.xpack.core.watcher.watch;
|
||||
exports org.elasticsearch.xpack.core.watcher;
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
module org.elasticsearch.mapper.unsignedlong {
|
||||
requires org.apache.lucene.core;
|
||||
requires org.elasticsearch.server;
|
||||
requires org.apache.lucene.sandbox;
|
||||
requires org.elasticsearch.xcontent;
|
||||
requires org.elasticsearch.painless.spi;
|
||||
|
||||
exports org.elasticsearch.xpack.unsignedlong; // for the painless script engine
|
||||
|
||||
opens org.elasticsearch.xpack.unsignedlong to org.elasticsearch.painless.spi; // whitelist resource access
|
||||
|
||||
provides org.elasticsearch.painless.spi.PainlessExtension with org.elasticsearch.xpack.unsignedlong.DocValuesWhitelistExtension;
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
module org.elasticsearch.security {
|
||||
requires java.naming;
|
||||
requires java.security.jgss;
|
||||
requires java.xml;
|
||||
|
||||
requires org.elasticsearch.base;
|
||||
requires org.elasticsearch.cli;
|
||||
requires org.elasticsearch.server;
|
||||
requires org.elasticsearch.sslconfig;
|
||||
requires org.elasticsearch.transport.netty4;
|
||||
requires org.elasticsearch.xcontent;
|
||||
requires org.elasticsearch.xcore;
|
||||
|
||||
requires org.apache.commons.codec;
|
||||
requires org.apache.httpcomponents.httpcore;
|
||||
requires org.apache.httpcomponents.httpclient;
|
||||
requires org.apache.httpcomponents.httpasyncclient;
|
||||
requires org.apache.httpcomponents.httpcore.nio;
|
||||
requires org.apache.log4j;
|
||||
requires org.apache.logging.log4j;
|
||||
requires org.apache.lucene.core;
|
||||
requires org.apache.lucene.queries;
|
||||
requires org.apache.lucene.sandbox;
|
||||
|
||||
requires org.opensaml.core;
|
||||
requires org.opensaml.saml;
|
||||
requires org.opensaml.saml.impl;
|
||||
requires org.opensaml.security.impl;
|
||||
requires org.opensaml.security;
|
||||
requires org.opensaml.xmlsec.impl;
|
||||
requires org.opensaml.xmlsec;
|
||||
|
||||
requires com.nimbusds.jose.jwt;
|
||||
requires io.netty.handler;
|
||||
requires io.netty.transport;
|
||||
requires jopt.simple;
|
||||
requires json.smart;
|
||||
requires net.shibboleth.utilities.java.support;
|
||||
requires oauth2.oidc.sdk;
|
||||
requires slf4j.api;
|
||||
requires unboundid.ldapsdk;
|
||||
|
||||
exports org.elasticsearch.xpack.security.action to org.elasticsearch.server;
|
||||
exports org.elasticsearch.xpack.security.action.apikey to org.elasticsearch.server;
|
||||
exports org.elasticsearch.xpack.security.action.enrollment to org.elasticsearch.server;
|
||||
exports org.elasticsearch.xpack.security.action.oidc to org.elasticsearch.server;
|
||||
exports org.elasticsearch.xpack.security.action.privilege to org.elasticsearch.server;
|
||||
exports org.elasticsearch.xpack.security.action.profile to org.elasticsearch.server;
|
||||
exports org.elasticsearch.xpack.security.action.realm to org.elasticsearch.server;
|
||||
exports org.elasticsearch.xpack.security.action.role to org.elasticsearch.server;
|
||||
exports org.elasticsearch.xpack.security.action.rolemapping to org.elasticsearch.server;
|
||||
exports org.elasticsearch.xpack.security.action.saml to org.elasticsearch.server;
|
||||
exports org.elasticsearch.xpack.security.action.service to org.elasticsearch.server;
|
||||
exports org.elasticsearch.xpack.security.action.token to org.elasticsearch.server;
|
||||
exports org.elasticsearch.xpack.security.action.user to org.elasticsearch.server;
|
||||
|
||||
exports org.elasticsearch.xpack.security.authc to org.elasticsearch.xcontent;
|
||||
|
||||
provides org.elasticsearch.cli.CliToolProvider
|
||||
with
|
||||
org.elasticsearch.xpack.security.enrollment.tool.CreateEnrollmentTokenToolProvider,
|
||||
org.elasticsearch.xpack.security.authc.esnative.tool.ResetPasswordToolProvider,
|
||||
org.elasticsearch.xpack.security.authc.esnative.tool.SetupPasswordToolProvider,
|
||||
org.elasticsearch.xpack.security.authc.saml.SamlMetadataToolProvider,
|
||||
org.elasticsearch.xpack.security.authc.service.FileTokensToolProvider,
|
||||
org.elasticsearch.xpack.security.crypto.tool.SystemKeyToolProvider,
|
||||
org.elasticsearch.xpack.security.authc.file.tool.UsersToolProvider,
|
||||
org.elasticsearch.xpack.security.enrollment.tool.AutoConfigGenerateElasticPasswordHashToolProvider;
|
||||
}
|
Loading…
Reference in New Issue