Created
February 11, 2022 17:56
-
-
Save nik9000/53ad7b1efb188dd76b5f3957e555b821 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
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