소스 검색

Refactor UberModuleClassLoader ctor signature (#90172)

The PluginBundle class will provide a Set<URL> rather than a List<Path>,
so the UberModuleClassLoader should expect that in its constructor.
William Brafford 3 년 전
부모
커밋
e1343308c0

+ 22 - 19
server/src/main/java/org/elasticsearch/plugins/UberModuleClassLoader.java

@@ -16,7 +16,6 @@ import java.io.InputStream;
 import java.io.UncheckedIOException;
 import java.lang.module.Configuration;
 import java.lang.module.ModuleFinder;
-import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
 import java.net.URLClassLoader;
@@ -26,7 +25,6 @@ import java.security.CodeSigner;
 import java.security.CodeSource;
 import java.security.PrivilegedAction;
 import java.security.SecureClassLoader;
-import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.HashSet;
 import java.util.List;
@@ -59,29 +57,21 @@ public class UberModuleClassLoader extends SecureClassLoader implements AutoClos
     private final ModuleLayer.Controller moduleController;
     private final Set<String> packageNames;
 
-    static UberModuleClassLoader getInstance(ClassLoader parent, String moduleName, List<Path> jarPaths) {
-        return getInstance(parent, moduleName, jarPaths, Set.of());
+    static UberModuleClassLoader getInstance(ClassLoader parent, String moduleName, Set<URL> jarUrls) {
+        return getInstance(parent, moduleName, jarUrls, Set.of());
     }
 
     @SuppressForbidden(reason = "need access to the jar file")
     @SuppressWarnings("removal")
-    static UberModuleClassLoader getInstance(ClassLoader parent, String moduleName, List<Path> jarPaths, Set<String> moduleDenyList) {
-        ModuleFinder finder = ModuleSupport.ofSyntheticPluginModule(moduleName, jarPaths.toArray(new Path[0]), Set.of());
-        List<URL> jarURLs = new ArrayList<>();
-        try {
-            for (Path jarPath : jarPaths) {
-                URI toUri = jarPath.toUri();
-                URL toURL = toUri.toURL();
-                jarURLs.add(toURL);
-            }
-        } catch (IOException e) {
-            throw new IllegalArgumentException(e);
-        }
+    static UberModuleClassLoader getInstance(ClassLoader parent, String moduleName, Set<URL> jarUrls, Set<String> moduleDenyList) {
+        Path[] jarPaths = jarUrls.stream().map(UberModuleClassLoader::urlToPathUnchecked).toArray(Path[]::new);
+
+        ModuleFinder finder = ModuleSupport.ofSyntheticPluginModule(moduleName, jarPaths, Set.of());
         ModuleLayer mparent = ModuleLayer.boot();
-        Configuration cf = mparent.configuration().resolve(finder, ModuleFinder.of(), Set.of(moduleName));
+        Configuration cf = mparent.configuration().resolveAndBind(finder, ModuleFinder.of(), Set.of(moduleName));
 
         Set<String> packageNames = new HashSet<>();
-        for (URL url : jarURLs) {
+        for (URL url : jarUrls) {
             try (JarFile jarFile = new JarFile(new File(url.toURI()))) {
                 Set<String> jarPackages = ModuleSupport.scan(jarFile)
                     .classFiles()
@@ -100,7 +90,7 @@ public class UberModuleClassLoader extends SecureClassLoader implements AutoClos
         PrivilegedAction<UberModuleClassLoader> pa = () -> new UberModuleClassLoader(
             parent,
             moduleName,
-            jarURLs.toArray(new URL[0]),
+            jarUrls.toArray(new URL[0]),
             cf,
             mparent,
             moduleDenyList,
@@ -144,6 +134,10 @@ public class UberModuleClassLoader extends SecureClassLoader implements AutoClos
         this.packageNames = packageNames;
     }
 
+    public ModuleLayer getLayer() {
+        return moduleController.layer();
+    }
+
     /**
      * @param moduleName
      *         The module name; or {@code null} to find the class in the
@@ -266,6 +260,15 @@ public class UberModuleClassLoader extends SecureClassLoader implements AutoClos
         return (pos < 0) ? "" : cn.substring(0, pos);
     }
 
+    @SuppressForbidden(reason = "plugin infrastructure provides URLs but module layer uses Paths")
+    static Path urlToPathUnchecked(URL url) {
+        try {
+            return Path.of(url.toURI());
+        } catch (URISyntaxException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
     @Override
     @SuppressWarnings("removal")
     public void close() throws Exception {

+ 18 - 4
server/src/test/java/org/elasticsearch/plugins/UberModuleClassLoaderTests.java

@@ -14,6 +14,7 @@ import org.elasticsearch.test.compiler.InMemoryJavaCompiler;
 import org.elasticsearch.test.jar.JarUtils;
 
 import java.io.IOException;
+import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLClassLoader;
 import java.nio.charset.StandardCharsets;
@@ -24,6 +25,7 @@ import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import static java.util.Arrays.stream;
 import static org.hamcrest.Matchers.containsString;
@@ -152,7 +154,7 @@ public class UberModuleClassLoaderTests extends ESTestCase {
 
         try (
             URLClassLoader parent = URLClassLoader.newInstance(urls, UberModuleClassLoaderTests.class.getClassLoader());
-            UberModuleClassLoader loader = UberModuleClassLoader.getInstance(parent, "synthetic", List.of(jar))
+            UberModuleClassLoader loader = UberModuleClassLoader.getInstance(parent, "synthetic", Set.of(jar.toUri().toURL()))
         ) {
             // stable plugin loader gives us the good class...
             Class<?> c = loader.loadClass("p.MyClassInPackageP");
@@ -188,7 +190,7 @@ public class UberModuleClassLoaderTests extends ESTestCase {
 
         try (
             URLClassLoader parent = URLClassLoader.newInstance(urls, UberModuleClassLoaderTests.class.getClassLoader());
-            UberModuleClassLoader loader = UberModuleClassLoader.getInstance(parent, "synthetic", List.of(jar))
+            UberModuleClassLoader loader = UberModuleClassLoader.getInstance(parent, "synthetic", Set.of(jar.toUri().toURL()))
         ) {
             // stable plugin loader gives us the good class...
             Class<?> c = loader.loadClass("p.MyClass");
@@ -300,7 +302,7 @@ public class UberModuleClassLoaderTests extends ESTestCase {
             UberModuleClassLoader denyListLoader = UberModuleClassLoader.getInstance(
                 UberModuleClassLoaderTests.class.getClassLoader(),
                 "synthetic",
-                List.of(jar),
+                Set.of(jar.toUri().toURL()),
                 Set.of("java.sql")
             )
         ) {
@@ -336,7 +338,19 @@ public class UberModuleClassLoaderTests extends ESTestCase {
     }
 
     private static UberModuleClassLoader getLoader(List<Path> jars) {
-        return UberModuleClassLoader.getInstance(UberModuleClassLoaderTests.class.getClassLoader(), "synthetic", jars);
+        return UberModuleClassLoader.getInstance(
+            UberModuleClassLoaderTests.class.getClassLoader(),
+            "synthetic",
+            jars.stream().map(UberModuleClassLoaderTests::pathToUrlUnchecked).collect(Collectors.toSet())
+        );
+    }
+
+    private static URL pathToUrlUnchecked(Path path) {
+        try {
+            return path.toUri().toURL();
+        } catch (MalformedURLException e) {
+            throw new IllegalArgumentException(e);
+        }
     }
 
     /*