Created
March 1, 2022 16:40
-
-
Save nik9000/efb7369fab5914b407a0fe7e9c2e35f2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
commit d3b9d0f11cdaf9d21a08fcad85d43fe2ffcb72ab | |
Author: Nik Everett <[email protected]> | |
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