|
12 | 12 | import java.net.URL;
|
13 | 13 | import java.nio.file.Path;
|
14 | 14 | import java.nio.file.Paths;
|
| 15 | +import java.util.ArrayList; |
15 | 16 | import java.util.HashMap;
|
16 | 17 | import java.util.HashSet;
|
17 | 18 | import java.util.List;
|
18 | 19 | import java.util.Map;
|
19 | 20 | import java.util.Optional;
|
20 | 21 | import java.util.Set;
|
21 | 22 | import java.util.function.Function;
|
22 |
| -import java.util.stream.Collectors; |
23 | 23 | import java.util.stream.Stream;
|
24 | 24 |
|
25 |
| -import io.github.zekerzhayard.forgewrapper.util.CheckedLambdaUtil; |
26 | 25 | import sun.misc.Unsafe;
|
27 | 26 |
|
28 | 27 | public class ModuleUtil {
|
@@ -53,17 +52,27 @@ public static void addModules(String modulePath) throws Throwable {
|
53 | 52 | MethodHandle loadModuleMH = IMPL_LOOKUP.findVirtual(Class.forName("jdk.internal.loader.BuiltinClassLoader"), "loadModule", MethodType.methodType(void.class, ModuleReference.class));
|
54 | 53 |
|
55 | 54 | // Resolve modules to a new config and load all extra modules in system class loader (unnamed modules for now)
|
56 |
| - Configuration config = Configuration.resolveAndBind(finder, List.of(ModuleLayer.boot().configuration()), finder, finder.findAll().stream().filter(mref -> !ModuleLayer.boot().findModule(mref.descriptor().name()).isPresent()).peek(CheckedLambdaUtil.wrapConsumer(mref -> loadModuleMH.invokeWithArguments(ClassLoader.getSystemClassLoader(), mref))).map(mref -> mref.descriptor().name()).collect(Collectors.toList())); |
| 55 | + List<String> roots = new ArrayList<>(); |
| 56 | + for (ModuleReference mref : finder.findAll()) { |
| 57 | + String name = mref.descriptor().name(); |
| 58 | + if (!ModuleLayer.boot().findModule(name).isPresent()) { |
| 59 | + loadModuleMH.invokeWithArguments(ClassLoader.getSystemClassLoader(), mref); |
| 60 | + roots.add(name); |
| 61 | + } |
| 62 | + } |
| 63 | + Configuration config = Configuration.resolveAndBind(finder, List.of(ModuleLayer.boot().configuration()), finder, roots); |
57 | 64 |
|
58 | 65 | // Copy the new config graph to boot module layer config
|
59 | 66 | MethodHandle graphGetter = IMPL_LOOKUP.findGetter(Configuration.class, "graph", Map.class);
|
60 | 67 | HashMap<ResolvedModule, Set<ResolvedModule>> graphMap = new HashMap<>((Map<ResolvedModule, Set<ResolvedModule>>) graphGetter.invokeWithArguments(config));
|
61 | 68 | MethodHandle cfSetter = IMPL_LOOKUP.findSetter(ResolvedModule.class, "cf", Configuration.class);
|
62 | 69 | // Reset all extra resolved modules config to boot module layer config
|
63 |
| - graphMap.forEach(CheckedLambdaUtil.wrapBiConsumer((k, v) -> { |
64 |
| - cfSetter.invokeWithArguments(k, ModuleLayer.boot().configuration()); |
65 |
| - v.forEach(CheckedLambdaUtil.wrapConsumer(m -> cfSetter.invokeWithArguments(m, ModuleLayer.boot().configuration()))); |
66 |
| - })); |
| 70 | + for (Map.Entry<ResolvedModule, Set<ResolvedModule>> entry : graphMap.entrySet()) { |
| 71 | + cfSetter.invokeWithArguments(entry.getKey(), ModuleLayer.boot().configuration()); |
| 72 | + for (ResolvedModule resolvedModule : entry.getValue()) { |
| 73 | + cfSetter.invokeWithArguments(resolvedModule, ModuleLayer.boot().configuration()); |
| 74 | + } |
| 75 | + } |
67 | 76 | graphMap.putAll((Map<ResolvedModule, Set<ResolvedModule>>) graphGetter.invokeWithArguments(ModuleLayer.boot().configuration()));
|
68 | 77 | IMPL_LOOKUP.findSetter(Configuration.class, "graph", Map.class).invokeWithArguments(ModuleLayer.boot().configuration(), new HashMap<>(graphMap));
|
69 | 78 |
|
@@ -92,7 +101,17 @@ public static void addModules(String modulePath) throws Throwable {
|
92 | 101 |
|
93 | 102 | // Add reads from extra modules to jdk modules
|
94 | 103 | MethodHandle implAddReadsMH = IMPL_LOOKUP.findVirtual(Module.class, "implAddReads", MethodType.methodType(void.class, Module.class));
|
95 |
| - config.modules().forEach(rm -> ModuleLayer.boot().findModule(rm.name()).ifPresent(m -> oldBootModules.forEach(brm -> ModuleLayer.boot().findModule(brm.name()).ifPresent(CheckedLambdaUtil.wrapConsumer(bm -> implAddReadsMH.invokeWithArguments(m, bm)))))); |
| 104 | + for (ResolvedModule resolvedModule : config.modules()) { |
| 105 | + Module module = ModuleLayer.boot().findModule(resolvedModule.name()).orElse(null); |
| 106 | + if (module != null) { |
| 107 | + for (ResolvedModule bootResolvedModule : oldBootModules) { |
| 108 | + Module bootModule = ModuleLayer.boot().findModule(bootResolvedModule.name()).orElse(null); |
| 109 | + if (bootModule != null) { |
| 110 | + implAddReadsMH.invokeWithArguments(module, bootModule); |
| 111 | + } |
| 112 | + } |
| 113 | + } |
| 114 | + } |
96 | 115 | }
|
97 | 116 |
|
98 | 117 | public static void addExports(List<String> exports) {
|
@@ -124,13 +143,26 @@ private enum TypeToAdd {
|
124 | 143 | }
|
125 | 144 |
|
126 | 145 | void implAdd(List<String> extras) {
|
127 |
| - extras.stream().map(ModuleUtil::parseModuleExtra).filter(Optional::isPresent).map(Optional::get).forEach(CheckedLambdaUtil.wrapConsumer(data -> ModuleLayer.boot().findModule(data.module).ifPresent(CheckedLambdaUtil.wrapConsumer(m -> { |
128 |
| - if ("ALL-UNNAMED".equals(data.target)) { |
129 |
| - this.implAddToAllUnnamedMH.invokeWithArguments(m, data.packages); |
130 |
| - } else { |
131 |
| - ModuleLayer.boot().findModule(data.target).ifPresent(CheckedLambdaUtil.wrapConsumer(tm -> this.implAddMH.invokeWithArguments(m, data.packages, tm))); |
| 146 | + for (String extra : extras) { |
| 147 | + ParserData data = ModuleUtil.parseModuleExtra(extra).orElse(null); |
| 148 | + if (data != null) { |
| 149 | + Module module = ModuleLayer.boot().findModule(data.module).orElse(null); |
| 150 | + if (module != null) { |
| 151 | + try { |
| 152 | + if ("ALL-UNNAMED".equals(data.target)) { |
| 153 | + this.implAddToAllUnnamedMH.invokeWithArguments(module, data.packages); |
| 154 | + } else { |
| 155 | + Module targetModule = ModuleLayer.boot().findModule(data.target).orElse(null); |
| 156 | + if (targetModule != null) { |
| 157 | + this.implAddMH.invokeWithArguments(module, data.packages, targetModule); |
| 158 | + } |
| 159 | + } |
| 160 | + } catch (Throwable t) { |
| 161 | + throw new RuntimeException(t); |
| 162 | + } |
| 163 | + } |
132 | 164 | }
|
133 |
| - })))); |
| 165 | + } |
134 | 166 | }
|
135 | 167 | }
|
136 | 168 |
|
|
0 commit comments