|
1 | 1 | package cpw.mods.cl; |
2 | 2 |
|
3 | 3 | import cpw.mods.util.LambdaExceptionUtils; |
| 4 | +import org.jetbrains.annotations.Nullable; |
| 5 | +import org.jetbrains.annotations.VisibleForTesting; |
4 | 6 |
|
5 | 7 | import java.io.IOException; |
6 | 8 | import java.io.InputStream; |
@@ -64,10 +66,29 @@ private static void bindToLayer(ModuleClassLoader classLoader, ModuleLayer layer |
64 | 66 | private final Map<String, JarModuleFinder.JarModuleReference> resolvedRoots; |
65 | 67 | private final Map<String, ResolvedModule> packageLookup; |
66 | 68 | private final Map<String, ClassLoader> parentLoaders; |
67 | | - private ClassLoader fallbackClassLoader = ClassLoader.getPlatformClassLoader(); |
| 69 | + private ClassLoader fallbackClassLoader; |
68 | 70 |
|
69 | 71 | public ModuleClassLoader(final String name, final Configuration configuration, final List<ModuleLayer> parentLayers) { |
70 | | - super(name, null); |
| 72 | + this(name, configuration, parentLayers, null); |
| 73 | + } |
| 74 | + |
| 75 | + /** |
| 76 | + * This constructor allows setting the parent {@linkplain ClassLoader classloader}. Use this with caution since |
| 77 | + * it will allow loading of classes from the classpath directly if the {@linkplain ClassLoader#getSystemClassLoader() system classloader} |
| 78 | + * is reachable from the given parent classloader. |
| 79 | + * <p> |
| 80 | + * Generally classes that are in packages covered by reachable modules are preferably loaded from these modules. |
| 81 | + * If a class-path entry is not shadowed by a module, specifying a parent class-loader may lead to those |
| 82 | + * classes now being loadable instead of throwing a {@link ClassNotFoundException}. |
| 83 | + * <p> |
| 84 | + * This relaxed classloader isolation is used in unit-testing, where testing libraries are loaded on the |
| 85 | + * system class-loader outside our control (by the Gradle test runner). We must not reload these classes |
| 86 | + * inside the module layers again, otherwise tests throw incompatible exceptions or may not be found at all. |
| 87 | + */ |
| 88 | + @VisibleForTesting |
| 89 | + public ModuleClassLoader(final String name, final Configuration configuration, final List<ModuleLayer> parentLayers, @Nullable ClassLoader parentLoader) { |
| 90 | + super(name, parentLoader); |
| 91 | + this.fallbackClassLoader = Objects.requireNonNullElse(parentLoader, ClassLoader.getPlatformClassLoader()); |
71 | 92 | this.configuration = configuration; |
72 | 93 | this.packageLookup = new HashMap<>(); |
73 | 94 | this.resolvedRoots = configuration.modules().stream() |
|
0 commit comments