Fix PluginClassLoader for Java 9
Packages such as java.sql are only available in the platform class loader.
@@ -17,6 +17,8 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Enumeration;
@@ -27,6 +29,8 @@ import static java.util.Objects.requireNonNull;
class PluginClassLoader
extends URLClassLoader
{
+ private static final ClassLoader PLATFORM_CLASS_LOADER = findPlatformClassLoader();
+
private final ClassLoader spiClassLoader;
private final List<String> spiPackages;
private final List<String> spiResources;
@@ -48,8 +52,8 @@ class PluginClassLoader
Iterable<String> spiPackages,
Iterable<String> spiResources)
{
- // use a null parent to prevent delegation to the system class loader
- super(urls.toArray(new URL[urls.size()]), null);
+ // plugins should not have access to the system (application) class loader
+ super(urls.toArray(new URL[urls.size()]), PLATFORM_CLASS_LOADER);
this.spiClassLoader = requireNonNull(spiClassLoader, "spiClassLoader is null");
this.spiPackages = ImmutableList.copyOf(spiPackages);
this.spiResources = ImmutableList.copyOf(spiResources);
@@ -126,4 +130,21 @@ class PluginClassLoader
{
return className.replace('.', '/');
}
+
+ @SuppressWarnings("JavaReflectionMemberAccess")
+ private static ClassLoader findPlatformClassLoader()
+ {
+ try {
+ // use platform class loader on Java 9
+ Method method = ClassLoader.class.getMethod("getPlatformClassLoader");
+ return (ClassLoader) method.invoke(null);
+ }
+ catch (NoSuchMethodException ignored) {
+ // use null class loader on Java 8
+ return null;
+ }
+ catch (IllegalAccessException | InvocationTargetException e) {
+ throw new AssertionError(e);
+ }
+ }
}
