Skip to content

Instantly share code, notes, and snippets.

@nik9000
Created February 11, 2022 17:56
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/53ad7b1efb188dd76b5f3957e555b821 to your computer and use it in GitHub Desktop.
Save nik9000/53ad7b1efb188dd76b5f3957e555b821 to your computer and use it in GitHub Desktop.
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 07839e6d815..8a8a8db1ae7 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
@@ -26,12 +26,16 @@ import java.nio.file.Path;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List;
+import java.util.Optional;
import java.util.ServiceLoader;
import java.util.Set;
+import java.util.function.Predicate;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
/**
* A provider locator for finding the {@link XContentProvider}.
@@ -86,20 +90,53 @@ public final class ProviderLocator {
private static XContentProvider provider() {
try {
+ {
+ Optional<Path> impl = classpathDirMatching(s -> s.endsWith("libs/x-content/impl/out/eclipse/0")).findAny();
+ if (impl.isPresent()) {
+ PrivilegedExceptionAction<XContentProvider> pa = () -> loadAsNonModule(pathsToUrls(List.of(impl.get())));
+ return AccessController.doPrivileged(pa);
+ }
+ }
+ {
+ Optional<Path> iface = classpathDirMatching(s -> s.endsWith("libs/x-content/out/eclipse/0")).findAny();
+ if (iface.isPresent()) {
+ Path impl = iface.get().getParent().getParent().getParent().resolve("impl");
+ Path eclipse = impl.resolve("eclipse").resolve("out");
+ Path classes = eclipse.resolve("0");
+ Path resources = eclipse.resolve("1");
+ Path providers = impl.resolve("build").resolve("providers");
+ if (Files.exists(providers) == false) {
+ throw new IllegalStateException("providers not found - build :libs:x-content:impl");
+ }
+ List<Path> loadMe = new ArrayList<>();
+ loadMe.add(classes);
+ loadMe.add(resources);
+ Files.walk(providers).filter(Files::isRegularFile).forEach(loadMe::add);
+ URL[] urls = pathsToUrls(loadMe);
+ PrivilegedExceptionAction<XContentProvider> pa = () -> loadAsNonModule(urls);
+ return AccessController.doPrivileged(pa);
+ }
+ }
PrivilegedExceptionAction<XContentProvider> pa = () -> loadAsNonModule(gatherUrls(providerPath()));
return AccessController.doPrivileged(pa);
- } catch (PrivilegedActionException e) {
+ } catch (PrivilegedActionException | IOException e) {
throw new UncheckedIOException((IOException) e.getCause());
}
}
+ private static Stream<Path> classpathDirMatching(Predicate<String> pred) {
+ String classpath = System.getProperty("java.class.path");
+ return Arrays.stream(classpath.split(ProviderLocator.pathSeparator())).filter(pred).map(Path::of).filter(Files::isDirectory);
+ }
+
private static XContentProvider loadAsNonModule(URL[] urls) {
+ Arrays.stream(urls).forEach(u -> System.err.println(u));
URLClassLoader loader = URLClassLoader.newInstance(urls, XContentProvider.class.getClassLoader());
ServiceLoader<XContentProvider> sl = ServiceLoader.load(XContentProvider.class, loader);
return sl.findFirst().orElseThrow(() -> new RuntimeException("cannot locate x-content provider"));
}
- private static URL[] gatherUrls(Path providerPath) throws IOException {
+ private static URL[] gatherUrls(Path providerPath) {
final InputStream is = ProviderLocator.class.getResourceAsStream("provider-jars.txt");
if (is == null) {
throw new IllegalStateException("missing x-content provider jars list");
@@ -111,10 +148,18 @@ public final class ProviderLocator {
} catch (IOException e) {
throw new UncheckedIOException(e);
}
+ return pathsToUrls(paths);
+ }
+ private static URL[] pathsToUrls(List<Path> paths) {
final Set<URL> urls = new LinkedHashSet<>();
for (Path path : paths) {
- URL url = path.toRealPath().toUri().toURL();
+ URL url;
+ try {
+ url = path.toRealPath().toUri().toURL();
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
if (urls.add(url) == false) {
throw new IllegalStateException("duplicate codebase: " + url);
}
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 22da8c67132..3e0f2bba285 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,33 @@ public class BootstrapForTesting {
// initialize paths the same exact way as bootstrap
Permissions perms = new Permissions();
Security.addClasspathPermissions(perms);
+ boolean needsXContentImpl = JarHell.parseClassPath()
+ .stream()
+ .filter(url -> url.getPath().endsWith("libs/x-content/impl/out/eclipse/0/"))
+ .findAny()
+ .isEmpty();
+ if (needsXContentImpl) {
+ 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(iface.get().toURI());
+ } catch (URISyntaxException e) {
+ throw new RuntimeException(e);
+ }
+ Path impl = path.getParent().getParent().getParent().resolve("impl");
+ Path eclipse = impl.resolve("eclipse").resolve("out");
+ Path classes = eclipse.resolve("0");
+ Path resources = eclipse.resolve("1");
+ Path providers = impl.resolve("build").resolve("providers");
+ FilePermissionUtils.addDirectoryPath(perms, "class.path", classes, "read,readlink", false);
+ FilePermissionUtils.addDirectoryPath(perms, "class.path", resources, "read,readlink", false);
+ FilePermissionUtils.addDirectoryPath(perms, "class.path", providers, "read,readlink", false);
+ }
+ }
// java.io.tmpdir
FilePermissionUtils.addDirectoryPath(perms, "java.io.tmpdir", javaTmpDir, "read,readlink,write,delete", false);
// custom test config file
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment