Skip to content

Commit 656b5f9

Browse files
authored
Refactor PluginsLoader to better support tests (#117522)
This refactors the way PluginsLoader is created to better support various types of testing.
1 parent c2e4afc commit 656b5f9

File tree

6 files changed

+61
-44
lines changed

6 files changed

+61
-44
lines changed

benchmarks/src/main/java/org/elasticsearch/benchmark/script/ScriptScoreBenchmark.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public class ScriptScoreBenchmark {
7777
private final PluginsService pluginsService = new PluginsService(
7878
Settings.EMPTY,
7979
null,
80-
new PluginsLoader(null, Path.of(System.getProperty("plugins.dir")))
80+
PluginsLoader.createPluginsLoader(null, Path.of(System.getProperty("plugins.dir")))
8181
);
8282
private final ScriptModule scriptModule = new ScriptModule(Settings.EMPTY, pluginsService.filterPlugins(ScriptPlugin.class).toList());
8383

server/src/main/java/org/elasticsearch/bootstrap/Elasticsearch.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ private static void initPhase2(Bootstrap bootstrap) throws IOException {
206206
);
207207

208208
// load the plugin Java modules and layers now for use in entitlements
209-
var pluginsLoader = new PluginsLoader(nodeEnv.modulesFile(), nodeEnv.pluginsFile());
209+
var pluginsLoader = PluginsLoader.createPluginsLoader(nodeEnv.modulesFile(), nodeEnv.pluginsFile());
210210
bootstrap.setPluginsLoader(pluginsLoader);
211211

212212
if (Boolean.parseBoolean(System.getProperty("es.entitlements.enabled"))) {

server/src/main/java/org/elasticsearch/plugins/PluginsLoader.java

Lines changed: 45 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -118,15 +118,30 @@ public static LayerAndLoader ofLoader(ClassLoader loader) {
118118
* @param modulesDirectory The directory modules exist in, or null if modules should not be loaded from the filesystem
119119
* @param pluginsDirectory The directory plugins exist in, or null if plugins should not be loaded from the filesystem
120120
*/
121-
@SuppressWarnings("this-escape")
122-
public PluginsLoader(Path modulesDirectory, Path pluginsDirectory) {
121+
public static PluginsLoader createPluginsLoader(Path modulesDirectory, Path pluginsDirectory) {
122+
return createPluginsLoader(modulesDirectory, pluginsDirectory, true);
123+
}
123124

124-
Map<String, List<ModuleQualifiedExportsService>> qualifiedExports = new HashMap<>(ModuleQualifiedExportsService.getBootServices());
125-
addServerExportsService(qualifiedExports);
125+
/**
126+
* Constructs a new PluginsLoader
127+
*
128+
* @param modulesDirectory The directory modules exist in, or null if modules should not be loaded from the filesystem
129+
* @param pluginsDirectory The directory plugins exist in, or null if plugins should not be loaded from the filesystem
130+
* @param withServerExports {@code true} to add server module exports
131+
*/
132+
public static PluginsLoader createPluginsLoader(Path modulesDirectory, Path pluginsDirectory, boolean withServerExports) {
133+
Map<String, List<ModuleQualifiedExportsService>> qualifiedExports;
134+
if (withServerExports) {
135+
qualifiedExports = new HashMap<>(ModuleQualifiedExportsService.getBootServices());
136+
addServerExportsService(qualifiedExports);
137+
} else {
138+
qualifiedExports = Collections.emptyMap();
139+
}
126140

127141
Set<PluginBundle> seenBundles = new LinkedHashSet<>();
128142

129143
// load (elasticsearch) module layers
144+
List<PluginDescriptor> moduleDescriptors;
130145
if (modulesDirectory != null) {
131146
try {
132147
Set<PluginBundle> modules = PluginsUtils.getModuleBundles(modulesDirectory);
@@ -140,6 +155,7 @@ public PluginsLoader(Path modulesDirectory, Path pluginsDirectory) {
140155
}
141156

142157
// load plugin layers
158+
List<PluginDescriptor> pluginDescriptors;
143159
if (pluginsDirectory != null) {
144160
try {
145161
// TODO: remove this leniency, but tests bogusly rely on it
@@ -158,7 +174,28 @@ public PluginsLoader(Path modulesDirectory, Path pluginsDirectory) {
158174
pluginDescriptors = Collections.emptyList();
159175
}
160176

161-
this.loadedPluginLayers = Collections.unmodifiableMap(loadPluginLayers(seenBundles, qualifiedExports));
177+
Map<String, LoadedPluginLayer> loadedPluginLayers = new LinkedHashMap<>();
178+
Map<String, Set<URL>> transitiveUrls = new HashMap<>();
179+
List<PluginBundle> sortedBundles = PluginsUtils.sortBundles(seenBundles);
180+
if (sortedBundles.isEmpty() == false) {
181+
Set<URL> systemLoaderURLs = JarHell.parseModulesAndClassPath();
182+
for (PluginBundle bundle : sortedBundles) {
183+
PluginsUtils.checkBundleJarHell(systemLoaderURLs, bundle, transitiveUrls);
184+
loadPluginLayer(bundle, loadedPluginLayers, qualifiedExports);
185+
}
186+
}
187+
188+
return new PluginsLoader(moduleDescriptors, pluginDescriptors, loadedPluginLayers);
189+
}
190+
191+
PluginsLoader(
192+
List<PluginDescriptor> moduleDescriptors,
193+
List<PluginDescriptor> pluginDescriptors,
194+
Map<String, LoadedPluginLayer> loadedPluginLayers
195+
) {
196+
this.moduleDescriptors = moduleDescriptors;
197+
this.pluginDescriptors = pluginDescriptors;
198+
this.loadedPluginLayers = loadedPluginLayers;
162199
}
163200

164201
public List<PluginDescriptor> moduleDescriptors() {
@@ -173,25 +210,7 @@ public Stream<PluginLayer> pluginLayers() {
173210
return loadedPluginLayers.values().stream().map(Function.identity());
174211
}
175212

176-
private Map<String, LoadedPluginLayer> loadPluginLayers(
177-
Set<PluginBundle> bundles,
178-
Map<String, List<ModuleQualifiedExportsService>> qualifiedExports
179-
) {
180-
Map<String, LoadedPluginLayer> loaded = new LinkedHashMap<>();
181-
Map<String, Set<URL>> transitiveUrls = new HashMap<>();
182-
List<PluginBundle> sortedBundles = PluginsUtils.sortBundles(bundles);
183-
if (sortedBundles.isEmpty() == false) {
184-
Set<URL> systemLoaderURLs = JarHell.parseModulesAndClassPath();
185-
for (PluginBundle bundle : sortedBundles) {
186-
PluginsUtils.checkBundleJarHell(systemLoaderURLs, bundle, transitiveUrls);
187-
loadPluginLayer(bundle, loaded, qualifiedExports);
188-
}
189-
}
190-
191-
return loaded;
192-
}
193-
194-
private void loadPluginLayer(
213+
private static void loadPluginLayer(
195214
PluginBundle bundle,
196215
Map<String, LoadedPluginLayer> loaded,
197216
Map<String, List<ModuleQualifiedExportsService>> qualifiedExports
@@ -211,7 +230,7 @@ private void loadPluginLayer(
211230
}
212231

213232
final ClassLoader parentLoader = ExtendedPluginsClassLoader.create(
214-
getClass().getClassLoader(),
233+
PluginsLoader.class.getClassLoader(),
215234
extendedPlugins.stream().map(LoadedPluginLayer::spiClassLoader).toList()
216235
);
217236
LayerAndLoader spiLayerAndLoader = null;
@@ -427,7 +446,7 @@ private static List<ModuleLayer> parentLayersOrBoot(List<ModuleLayer> parentLaye
427446
}
428447
}
429448

430-
protected void addServerExportsService(Map<String, List<ModuleQualifiedExportsService>> qualifiedExports) {
449+
private static void addServerExportsService(Map<String, List<ModuleQualifiedExportsService>> qualifiedExports) {
431450
var exportsService = new ModuleQualifiedExportsService(serverModule) {
432451
@Override
433452
protected void addExports(String pkg, Module target) {

server/src/test/java/org/elasticsearch/plugins/PluginsServiceTests.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
import org.elasticsearch.env.Environment;
1919
import org.elasticsearch.env.TestEnvironment;
2020
import org.elasticsearch.index.IndexModule;
21-
import org.elasticsearch.jdk.ModuleQualifiedExportsService;
2221
import org.elasticsearch.plugin.analysis.CharFilterFactory;
2322
import org.elasticsearch.plugins.scanners.PluginInfo;
2423
import org.elasticsearch.plugins.spi.BarPlugin;
@@ -66,12 +65,11 @@ public class PluginsServiceTests extends ESTestCase {
6665
public static class FilterablePlugin extends Plugin implements ScriptPlugin {}
6766

6867
static PluginsService newPluginsService(Settings settings) {
69-
return new PluginsService(settings, null, new PluginsLoader(null, TestEnvironment.newEnvironment(settings).pluginsFile()) {
70-
@Override
71-
protected void addServerExportsService(Map<String, List<ModuleQualifiedExportsService>> qualifiedExports) {
72-
// tests don't run modular
73-
}
74-
});
68+
return new PluginsService(
69+
settings,
70+
null,
71+
PluginsLoader.createPluginsLoader(null, TestEnvironment.newEnvironment(settings).pluginsFile(), false)
72+
);
7573
}
7674

7775
static PluginsService newMockPluginsService(List<Class<? extends Plugin>> classpathPlugins) {

test/framework/src/main/java/org/elasticsearch/plugins/MockPluginsService.java

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
import org.elasticsearch.common.settings.Settings;
1717
import org.elasticsearch.common.util.concurrent.ConcurrentCollections;
1818
import org.elasticsearch.env.Environment;
19-
import org.elasticsearch.jdk.ModuleQualifiedExportsService;
2019
import org.elasticsearch.plugins.spi.SPIClassIterator;
2120

2221
import java.lang.reflect.Constructor;
@@ -43,13 +42,11 @@ public class MockPluginsService extends PluginsService {
4342
* @param classpathPlugins Plugins that exist in the classpath which should be loaded
4443
*/
4544
public MockPluginsService(Settings settings, Environment environment, Collection<Class<? extends Plugin>> classpathPlugins) {
46-
super(settings, environment.configFile(), new PluginsLoader(environment.modulesFile(), environment.pluginsFile()) {
47-
48-
@Override
49-
protected void addServerExportsService(Map<String, List<ModuleQualifiedExportsService>> qualifiedExports) {
50-
// tests don't run modular
51-
}
52-
});
45+
super(
46+
settings,
47+
environment.configFile(),
48+
new PluginsLoader(Collections.emptyList(), Collections.emptyList(), Collections.emptyMap())
49+
);
5350

5451
List<LoadedPlugin> pluginsLoaded = new ArrayList<>();
5552

x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/bench/WatcherScheduleEngineBenchmark.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,10 @@ public static void main(String[] args) throws Exception {
109109

110110
// First clean everything and index the watcher (but not via put alert api!)
111111
try (
112-
Node node = new Node(internalNodeEnv, new PluginsLoader(internalNodeEnv.modulesFile(), internalNodeEnv.pluginsFile())).start()
112+
Node node = new Node(
113+
internalNodeEnv,
114+
PluginsLoader.createPluginsLoader(internalNodeEnv.modulesFile(), internalNodeEnv.pluginsFile())
115+
).start()
113116
) {
114117
final Client client = node.client();
115118
ClusterHealthResponse response = client.admin().cluster().prepareHealth(TimeValue.THIRTY_SECONDS).setWaitForNodes("2").get();

0 commit comments

Comments
 (0)