Skip to content

Instantly share code, notes, and snippets.

@nik9000
Created March 1, 2022 16:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nik9000/efb7369fab5914b407a0fe7e9c2e35f2 to your computer and use it in GitHub Desktop.
Save nik9000/efb7369fab5914b407a0fe7e9c2e35f2 to your computer and use it in GitHub Desktop.
commit d3b9d0f11cdaf9d21a08fcad85d43fe2ffcb72ab
Author: Nik Everett <nik9000@gmail.com>
Date: Mon Feb 28 14:45:33 2022 -0500
Hack?
diff --git a/libs/x-content/impl/.gitignore b/libs/x-content/impl/.gitignore
new file mode 100644
index 00000000000..39a06683b73
--- /dev/null
+++ b/libs/x-content/impl/.gitignore
@@ -0,0 +1 @@
+.deps
diff --git a/libs/x-content/impl/build.gradle b/libs/x-content/impl/build.gradle
index 2e5c3bc85b1..13068ce9cf4 100644
--- a/libs/x-content/impl/build.gradle
+++ b/libs/x-content/impl/build.gradle
@@ -44,3 +44,14 @@ tasks.named("thirdPartyAudit").configure {
'com.fasterxml.jackson.databind.cfg.MapperBuilder'
)
}
+
+/*
+ * Copy the dependencies some place where our funny sub-classloader
+ * that we use for unit testing in Eclipse. We'l run it when we import
+ * the project into Eclipse.
+ */
+def copyProvidersDeps = tasks.register("copyProviderDeps", Copy) {
+ destinationDir = new File(projectDir, ".deps")
+ from(configurations.runtimeClasspath)
+}
+eclipse.synchronizationTasks copyProvidersDeps
diff --git a/libs/x-content/src/main/java/org/elasticsearch/xcontent/internal/ProviderLocator.java b/libs/x-content/src/main/java/org/elasticsearch/xcontent/internal/ProviderLocator.java
index afff71d0d80..87664357a3e 100644
--- a/libs/x-content/src/main/java/org/elasticsearch/xcontent/internal/ProviderLocator.java
+++ b/libs/x-content/src/main/java/org/elasticsearch/xcontent/internal/ProviderLocator.java
@@ -28,17 +28,17 @@ public final class ProviderLocator {
public static final XContentProvider INSTANCE = provider();
private static XContentProvider provider() {
+ ProviderLocatorLoader loader = ServiceLoader.load(ProviderLocatorLoader.class)
+ .stream()
+ .map(ServiceLoader.Provider::get)
+ .filter(ProviderLocatorLoader::okToRun)
+ .findFirst()
+ .orElseGet(ProviderLocatorLoader.Production::new);
try {
- PrivilegedExceptionAction<XContentProvider> pa = ProviderLocator::loadAsNonModule;
+ PrivilegedExceptionAction<XContentProvider> pa = loader::load;
return AccessController.doPrivileged(pa);
} catch (PrivilegedActionException e) {
throw new UncheckedIOException((IOException) e.getCause());
}
}
-
- private static XContentProvider loadAsNonModule() {
- ClassLoader loader = EmbeddedImplClassLoader.getInstance(ProviderLocator.class.getClassLoader(), "x-content");
- ServiceLoader<XContentProvider> sl = ServiceLoader.load(XContentProvider.class, loader);
- return sl.findFirst().orElseThrow(() -> new RuntimeException("cannot locate x-content provider"));
- }
}
diff --git a/libs/x-content/src/main/java/org/elasticsearch/xcontent/internal/ProviderLocatorLoader.java b/libs/x-content/src/main/java/org/elasticsearch/xcontent/internal/ProviderLocatorLoader.java
new file mode 100644
index 00000000000..bde4627e939
--- /dev/null
+++ b/libs/x-content/src/main/java/org/elasticsearch/xcontent/internal/ProviderLocatorLoader.java
@@ -0,0 +1,33 @@
+/*
+ * 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.xcontent.internal;
+
+import org.elasticsearch.xcontent.spi.XContentProvider;
+
+import java.util.ServiceLoader;
+
+public interface ProviderLocatorLoader {
+ boolean okToRun();
+
+ XContentProvider load();
+
+ class Production implements ProviderLocatorLoader {
+ @Override
+ public boolean okToRun() {
+ return true;
+ }
+
+ @Override
+ public XContentProvider load() {
+ ClassLoader loader = EmbeddedImplClassLoader.getInstance(ProviderLocator.class.getClassLoader(), "x-content");
+ ServiceLoader<XContentProvider> sl = ServiceLoader.load(XContentProvider.class, loader);
+ return sl.findFirst().orElseThrow(() -> new RuntimeException("cannot locate x-content provider"));
+ }
+ }
+}
diff --git a/libs/x-content/src/test/java/org/elasticsearch/xcontent/internal/EclipseProviderLocatorLoader.java b/libs/x-content/src/test/java/org/elasticsearch/xcontent/internal/EclipseProviderLocatorLoader.java
new file mode 100644
index 00000000000..52463833c1b
--- /dev/null
+++ b/libs/x-content/src/test/java/org/elasticsearch/xcontent/internal/EclipseProviderLocatorLoader.java
@@ -0,0 +1,65 @@
+/*
+ * 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.xcontent.internal;
+
+import org.elasticsearch.core.PathUtils;
+import org.elasticsearch.xcontent.spi.XContentProvider;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ServiceLoader;
+import java.util.stream.Stream;
+
+public class EclipseProviderLocatorLoader implements ProviderLocatorLoader {
+ @Override
+ public boolean okToRun() {
+ try {
+ Class.forName("org.eclipse.jdt.internal.junit.runner.RemoteTestRunner");
+ return true;
+ } catch (ClassNotFoundException e) {
+ return false;
+ }
+ }
+
+ @Override
+ public XContentProvider load() {
+ try {
+ Path thisLocation = PathUtils.get(getClass().getProtectionDomain().getCodeSource().getLocation().toURI());
+ Path implRoot = thisLocation.resolve("../../../impl").toAbsolutePath();
+
+ List<URL> implDirs = new ArrayList<>();
+ implDirs.addAll(subDirUrls(implRoot.resolve("out/eclipse")));
+ implDirs.addAll(subDirUrls(implRoot.resolve(".deps")));
+ URLClassLoader loader = new URLClassLoader(implDirs.toArray(URL[]::new));
+ ServiceLoader<XContentProvider> sl = ServiceLoader.load(XContentProvider.class, loader);
+ return sl.findFirst().orElseThrow(() -> new RuntimeException("cannot locate x-content provider"));
+ } catch (IOException | URISyntaxException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private List<URL> subDirUrls(Path parent) throws IOException {
+ try (Stream<Path> subs = Files.list(parent)) {
+ return subs.map(sub -> {
+ try {
+ return sub.toUri().toURL();
+ } catch (MalformedURLException e) {
+ throw new RuntimeException(e);
+ }
+ }).toList();
+ }
+ }
+}
diff --git a/libs/x-content/src/test/resources/META-INF/services/org.elasticsearch.xcontent.internal.ProviderLocatorLoader b/libs/x-content/src/test/resources/META-INF/services/org.elasticsearch.xcontent.internal.ProviderLocatorLoader
new file mode 100644
index 00000000000..242e339e4c5
--- /dev/null
+++ b/libs/x-content/src/test/resources/META-INF/services/org.elasticsearch.xcontent.internal.ProviderLocatorLoader
@@ -0,0 +1 @@
+org.elasticsearch.xcontent.internal.EclipseProviderLocatorLoader
diff --git a/server/src/test/resources/META-INF/services/org.elasticsearch.xcontent.internal.ProviderLocatorLoader b/server/src/test/resources/META-INF/services/org.elasticsearch.xcontent.internal.ProviderLocatorLoader
new file mode 100644
index 00000000000..242e339e4c5
--- /dev/null
+++ b/server/src/test/resources/META-INF/services/org.elasticsearch.xcontent.internal.ProviderLocatorLoader
@@ -0,0 +1 @@
+org.elasticsearch.xcontent.internal.EclipseProviderLocatorLoader
diff --git a/test/framework/src/main/java/org/elasticsearch/bootstrap/BootstrapForTesting.java b/test/framework/src/main/java/org/elasticsearch/bootstrap/BootstrapForTesting.java
index 61a79a6ded4..175d00a7528 100644
--- a/test/framework/src/main/java/org/elasticsearch/bootstrap/BootstrapForTesting.java
+++ b/test/framework/src/main/java/org/elasticsearch/bootstrap/BootstrapForTesting.java
@@ -29,6 +29,7 @@ import org.junit.Assert;
import java.io.InputStream;
import java.net.SocketPermission;
+import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -44,6 +45,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
import java.util.Properties;
import java.util.Set;
import java.util.stream.Collectors;
@@ -111,6 +113,22 @@ public class BootstrapForTesting {
// initialize paths the same exact way as bootstrap
Permissions perms = new Permissions();
Security.addClasspathPermissions(perms);
+ if (inEclipse()) {
+ Optional<URL> iface = JarHell.parseClassPath()
+ .stream()
+ .filter(url -> url.getPath().endsWith("libs/x-content/out/eclipse/0/"))
+ .findAny();
+ if (iface.isPresent()) {
+ Path path;
+ try {
+ path = PathUtils.get(new URL(iface.get(), "../../../impl/").toURI());
+ } catch (URISyntaxException e) {
+ throw new RuntimeException(e);
+ }
+ FilePermissionUtils.addDirectoryPath(perms, "class.path", path, "read,readlink", false);
+ perms.add(new RuntimePermission("createClassLoader"));
+ }
+ }
// java.io.tmpdir
FilePermissionUtils.addDirectoryPath(perms, "java.io.tmpdir", javaTmpDir, "read,readlink,write,delete", false);
// custom test config file
@@ -321,4 +339,13 @@ public class BootstrapForTesting {
// does nothing, just easy way to make sure the class is loaded.
public static void ensureInitialized() {}
+
+ private static boolean inEclipse() {
+ try {
+ Class.forName("org.eclipse.jdt.internal.junit.runner.RemoteTestRunner");
+ return true;
+ } catch (ClassNotFoundException e) {
+ return false;
+ }
+ }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment