Skip to content

Commit 3ee6633

Browse files
committed
Fix defining duplicated modules.
1 parent 5fb3f01 commit 3ee6633

File tree

14 files changed

+128
-112
lines changed

14 files changed

+128
-112
lines changed

.github/workflows/publication.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ jobs:
2020
env:
2121
IS_PUBLICATION: true
2222
run: |
23+
git clone -b maven https://github.com/ZekerZhayard/ForgeWrapper.git ./build/maven
24+
rm -rf ./build/maven/.git/*
2325
chmod +x ./gradlew
2426
./gradlew publish -iS
2527
- uses: actions/upload-artifact@v2

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Allow [MultiMC](https://github.com/MultiMC/MultiMC5) to launch Minecraft 1.13+ w
1919
3. Since ForgeWrapper 1.5.1, it no longer includes the json converter, so you need to build it by yourself:
2020
- [Download](https://github.com/ZekerZhayard/ForgeWrapper/archive/refs/heads/master.zip) ForgeWrapper sources.
2121
- Extract the zip and open terminal in the extracted folder.
22-
- Run `./gradlew build` command in terminal and get the jar from `./converter/build/libs`
22+
- Run `./gradlew converter:build` command in terminal and get the jar from `./converter/build/libs`
2323
3. Run the below command in terminal:
2424
```
2525
java -jar <ForgeWrapper.jar> --installer=<forge-installer.jar> [--instance=<instance-path>]

build.gradle

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ archivesBaseName = rootProject.name
1616

1717
configurations {
1818
provided {
19-
compileOnly.extendsFrom provided
19+
implementation.extendsFrom provided
2020
}
2121
multirelase {
22-
compileOnly.extendsFrom multirelase
22+
implementation.extendsFrom multirelase
2323
}
2424
}
2525

@@ -37,6 +37,7 @@ dependencies {
3737
compileOnly "net.minecraftforge:installer:2.1.4"
3838
compileOnly "net.sf.jopt-simple:jopt-simple:5.0.4"
3939

40+
provided project(":common")
4041
provided project(":legacy")
4142
multirelase project(":jigsaw")
4243
}
@@ -56,7 +57,6 @@ jar {
5657
"Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
5758
"Automatic-Module-Name": "${project.group}.${project.archivesBaseName}".toString().toLowerCase(),
5859
"Multi-Release": "true",
59-
"Main-Class": "io.github.zekerzhayard.forgewrapper.converter.Main",
6060
"GitCommit": String.valueOf(System.getenv("GITHUB_SHA"))
6161
])
6262

@@ -87,7 +87,6 @@ publishing {
8787
url = layout.buildDirectory.dir("maven")
8888
}
8989
}
90-
9190
}
9291
tasks.publish.dependsOn build
9392

common/build.gradle

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
2+
plugins {
3+
id "java"
4+
id "eclipse"
5+
id "maven-publish"
6+
}
7+
8+
sourceCompatibility = targetCompatibility = 1.8
9+
compileJava {
10+
sourceCompatibility = targetCompatibility = 1.8
11+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package io.github.zekerzhayard.forgewrapper.util;
2+
3+
import java.util.function.BiConsumer;
4+
import java.util.function.Consumer;
5+
6+
public class CheckedLambdaUtil {
7+
public static <T> Consumer<T> wrapConsumer(CheckedConsumer<T> consumer) {
8+
return consumer;
9+
}
10+
11+
public static <T, U> BiConsumer<T, U> wrapBiConsumer(CheckedBiConsumer<T, U> biconsumer) {
12+
return biconsumer;
13+
}
14+
15+
public interface CheckedConsumer<T> extends Consumer<T> {
16+
void checkedAccept(T t) throws Throwable;
17+
18+
@Override
19+
default void accept(T t) {
20+
try {
21+
this.checkedAccept(t);
22+
} catch (Throwable th) {
23+
throw new RuntimeException(th);
24+
}
25+
}
26+
}
27+
28+
public interface CheckedBiConsumer<T, U> extends BiConsumer<T, U> {
29+
void checkedAccept(T t, U u) throws Throwable;
30+
31+
@Override
32+
default void accept(T t, U u) {
33+
try {
34+
this.checkedAccept(t, u);
35+
} catch (Throwable th) {
36+
throw new RuntimeException(th);
37+
}
38+
}
39+
}
40+
}

converter/build.gradle

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,14 @@ version = "${rootProject.fw_version}${-> getVersionSuffix()}"
88
group = "io.github.zekerzhayard"
99
archivesBaseName = rootProject.name + "Converter"
1010

11+
sourceCompatibility = targetCompatibility = 1.8
12+
compileJava {
13+
sourceCompatibility = targetCompatibility = 1.8
14+
}
15+
1116
configurations {
1217
provided {
13-
compileOnly.extendsFrom provided
18+
implementation.extendsFrom provided
1419
}
1520
}
1621

@@ -30,6 +35,7 @@ jar {
3035
])
3136

3237
from configurations.provided.files.collect {
38+
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
3339
zipTree(it)
3440
}
3541
}

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11

22
org.gradle.daemon = false
33

4-
fw_version = 1.5.1
4+
fw_version = 1.5.2

jigsaw/build.gradle

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,7 @@ configurations {
2626
}
2727
}
2828
}
29+
30+
dependencies {
31+
compileOnly project(":common")
32+
}

jigsaw/src/main/java/io/github/zekerzhayard/forgewrapper/installer/util/ModuleUtil.java

Lines changed: 50 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,23 @@
55
import java.lang.invoke.MethodHandles;
66
import java.lang.invoke.MethodType;
77
import java.lang.module.Configuration;
8-
import java.lang.module.ModuleDescriptor;
98
import java.lang.module.ModuleFinder;
109
import java.lang.module.ModuleReference;
1110
import java.lang.module.ResolvedModule;
1211
import java.lang.reflect.Field;
1312
import java.nio.file.Path;
1413
import java.nio.file.Paths;
15-
import java.util.Arrays;
1614
import java.util.HashMap;
1715
import java.util.HashSet;
1816
import java.util.List;
1917
import java.util.Map;
18+
import java.util.Optional;
2019
import java.util.Set;
2120
import java.util.function.Function;
2221
import java.util.stream.Collectors;
22+
import java.util.stream.Stream;
2323

24+
import io.github.zekerzhayard.forgewrapper.util.CheckedLambdaUtil;
2425
import sun.misc.Unsafe;
2526

2627
public class ModuleUtil {
@@ -46,39 +47,22 @@ private static MethodHandles.Lookup getImplLookup() {
4647
*/
4748
@SuppressWarnings("unchecked")
4849
public static void addModules(String modulePath) throws Throwable {
49-
// Find all extra modules
50-
ModuleFinder finder = ModuleFinder.of(Arrays.stream(modulePath.split(File.pathSeparator)).map(Paths::get).toArray(Path[]::new));
50+
// Find all extra modules, exclude all existing modules
51+
ModuleFinder finder = ModuleFinder.of(Stream.of(modulePath.split(File.pathSeparator)).map(Paths::get).filter(p -> ModuleFinder.of(p).findAll().stream().noneMatch(mref -> ModuleLayer.boot().findModule(mref.descriptor().name()).isPresent())).toArray(Path[]::new));
5152
MethodHandle loadModuleMH = IMPL_LOOKUP.findVirtual(Class.forName("jdk.internal.loader.BuiltinClassLoader"), "loadModule", MethodType.methodType(void.class, ModuleReference.class));
5253

53-
// Resolve modules to a new config
54-
Configuration config = Configuration.resolveAndBind(finder, List.of(ModuleLayer.boot().configuration()), finder, finder.findAll().stream().peek(mref -> {
55-
try {
56-
// Load all extra modules in system class loader (unnamed modules for now)
57-
loadModuleMH.invokeWithArguments(ClassLoader.getSystemClassLoader(), mref);
58-
} catch (Throwable throwable) {
59-
throw new RuntimeException(throwable);
60-
}
61-
}).map(ModuleReference::descriptor).map(ModuleDescriptor::name).collect(Collectors.toList()));
54+
// Resolve modules to a new config and load all extra modules in system class loader (unnamed modules for now)
55+
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()));
6256

6357
// Copy the new config graph to boot module layer config
6458
MethodHandle graphGetter = IMPL_LOOKUP.findGetter(Configuration.class, "graph", Map.class);
6559
HashMap<ResolvedModule, Set<ResolvedModule>> graphMap = new HashMap<>((Map<ResolvedModule, Set<ResolvedModule>>) graphGetter.invokeWithArguments(config));
6660
MethodHandle cfSetter = IMPL_LOOKUP.findSetter(ResolvedModule.class, "cf", Configuration.class);
6761
// Reset all extra resolved modules config to boot module layer config
68-
graphMap.forEach((k, v) -> {
69-
try {
70-
cfSetter.invokeWithArguments(k, ModuleLayer.boot().configuration());
71-
v.forEach(m -> {
72-
try {
73-
cfSetter.invokeWithArguments(m, ModuleLayer.boot().configuration());
74-
} catch (Throwable throwable) {
75-
throw new RuntimeException(throwable);
76-
}
77-
});
78-
} catch (Throwable throwable) {
79-
throw new RuntimeException(throwable);
80-
}
81-
});
62+
graphMap.forEach(CheckedLambdaUtil.wrapBiConsumer((k, v) -> {
63+
cfSetter.invokeWithArguments(k, ModuleLayer.boot().configuration());
64+
v.forEach(CheckedLambdaUtil.wrapConsumer(m -> cfSetter.invokeWithArguments(m, ModuleLayer.boot().configuration())));
65+
}));
8266
graphMap.putAll((Map<ResolvedModule, Set<ResolvedModule>>) graphGetter.invokeWithArguments(ModuleLayer.boot().configuration()));
8367
IMPL_LOOKUP.findSetter(Configuration.class, "graph", Map.class).invokeWithArguments(ModuleLayer.boot().configuration(), new HashMap<>(graphMap));
8468

@@ -88,13 +72,13 @@ public static void addModules(String modulePath) throws Throwable {
8872
HashSet<ResolvedModule> modulesSet = new HashSet<>(config.modules());
8973
modulesSetter.invokeWithArguments(ModuleLayer.boot().configuration(), new HashSet<>(modulesSet));
9074

91-
// Prepare to add all of the new config "nameToModule" to boot module layer config
75+
// Prepare to add all the new config "nameToModule" to boot module layer config
9276
MethodHandle nameToModuleGetter = IMPL_LOOKUP.findGetter(Configuration.class, "nameToModule", Map.class);
9377
HashMap<String, ResolvedModule> nameToModuleMap = new HashMap<>((Map<String, ResolvedModule>) nameToModuleGetter.invokeWithArguments(ModuleLayer.boot().configuration()));
9478
nameToModuleMap.putAll((Map<String, ResolvedModule>) nameToModuleGetter.invokeWithArguments(config));
9579
IMPL_LOOKUP.findSetter(Configuration.class, "nameToModule", Map.class).invokeWithArguments(ModuleLayer.boot().configuration(), new HashMap<>(nameToModuleMap));
9680

97-
// Define all extra modules and add all of the new config "nameToModule" to boot module layer config
81+
// Define all extra modules and add all the new config "nameToModule" to boot module layer config
9882
((Map<String, Module>) IMPL_LOOKUP.findGetter(ModuleLayer.class, "nameToModule", Map.class).invokeWithArguments(ModuleLayer.boot())).putAll((Map<String, Module>) IMPL_LOOKUP.findStatic(Module.class, "defineModules", MethodType.methodType(Map.class, Configuration.class, Function.class, ModuleLayer.class)).invokeWithArguments(ModuleLayer.boot().configuration(), (Function<String, ClassLoader>) name -> ClassLoader.getSystemClassLoader(), ModuleLayer.boot()));
9983

10084
// Add all of resolved modules
@@ -107,66 +91,56 @@ public static void addModules(String modulePath) throws Throwable {
10791

10892
// Add reads from extra modules to jdk modules
10993
MethodHandle implAddReadsMH = IMPL_LOOKUP.findVirtual(Module.class, "implAddReads", MethodType.methodType(void.class, Module.class));
110-
config.modules().forEach(rm -> ModuleLayer.boot().findModule(rm.name()).ifPresent(m -> oldBootModules.forEach(brm -> ModuleLayer.boot().findModule(brm.name()).ifPresent(bm -> {
111-
try {
112-
implAddReadsMH.invokeWithArguments(m, bm);
113-
} catch (Throwable throwable) {
114-
throw new RuntimeException(throwable);
115-
}
116-
}))));
94+
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))))));
11795
}
11896

119-
public static void addExports(List<String> exports) throws Throwable {
120-
MethodHandle implAddExportsMH = IMPL_LOOKUP.findVirtual(Module.class, "implAddExports", MethodType.methodType(void.class, String.class, Module.class));
121-
MethodHandle implAddExportsToAllUnnamedMH = IMPL_LOOKUP.findVirtual(Module.class, "implAddExportsToAllUnnamed", MethodType.methodType(void.class, String.class));
97+
public static void addExports(List<String> exports) {
98+
TypeToAdd.EXPORTS.implAdd(exports);
99+
}
122100

123-
addExtra(exports, implAddExportsMH, implAddExportsToAllUnnamedMH);
101+
public static void addOpens(List<String> opens) {
102+
TypeToAdd.OPENS.implAdd(opens);
124103
}
125104

126-
public static void addOpens(List<String> opens) throws Throwable {
127-
MethodHandle implAddOpensMH = IMPL_LOOKUP.findVirtual(Module.class, "implAddOpens", MethodType.methodType(void.class, String.class, Module.class));
128-
MethodHandle implAddOpensToAllUnnamedMH = IMPL_LOOKUP.findVirtual(Module.class, "implAddOpensToAllUnnamed", MethodType.methodType(void.class, String.class));
105+
private enum TypeToAdd {
106+
EXPORTS("Exports"),
107+
OPENS("Opens");
129108

130-
addExtra(opens, implAddOpensMH, implAddOpensToAllUnnamedMH);
131-
}
109+
private final MethodHandle implAddMH;
110+
private final MethodHandle implAddToAllUnnamedMH;
132111

133-
private static void addExtra(List<String> extras, MethodHandle implAddExtraMH, MethodHandle implAddExtraToAllUnnamedMH) {
134-
extras.forEach(extra -> {
135-
ParserData data = parseModuleExtra(extra);
136-
if (data != null) {
137-
ModuleLayer.boot().findModule(data.module).ifPresent(m -> {
138-
try {
139-
if ("ALL-UNNAMED".equals(data.target)) {
140-
implAddExtraToAllUnnamedMH.invokeWithArguments(m, data.packages);
141-
} else {
142-
ModuleLayer.boot().findModule(data.target).ifPresent(tm -> {
143-
try {
144-
implAddExtraMH.invokeWithArguments(m, data.packages, tm);
145-
} catch (Throwable t) {
146-
throw new RuntimeException(t);
147-
}
148-
});
149-
}
150-
} catch (Throwable t) {
151-
throw new RuntimeException(t);
152-
}
153-
});
112+
TypeToAdd(String name) {
113+
try {
114+
this.implAddMH = IMPL_LOOKUP.findVirtual(Module.class, "implAdd" + name, MethodType.methodType(void.class, String.class, Module.class));
115+
this.implAddToAllUnnamedMH = IMPL_LOOKUP.findVirtual(Module.class, "implAdd" + name + "ToAllUnnamed", MethodType.methodType(void.class, String.class));
116+
} catch (Throwable t) {
117+
throw new RuntimeException(t);
154118
}
155-
});
119+
}
120+
121+
void implAdd(List<String> extras) {
122+
extras.stream().map(ModuleUtil::parseModuleExtra).filter(Optional::isPresent).map(Optional::get).forEach(CheckedLambdaUtil.wrapConsumer(data -> ModuleLayer.boot().findModule(data.module).ifPresent(CheckedLambdaUtil.wrapConsumer(m -> {
123+
if ("ALL-UNNAMED".equals(data.target)) {
124+
this.implAddToAllUnnamedMH.invokeWithArguments(m, data.packages);
125+
} else {
126+
ModuleLayer.boot().findModule(data.target).ifPresent(CheckedLambdaUtil.wrapConsumer(tm -> this.implAddMH.invokeWithArguments(m, data.packages, tm)));
127+
}
128+
}))));
129+
}
156130
}
157131

158132
// <module>/<package>=<target>
159-
private static ParserData parseModuleExtra(String extra) {
133+
private static Optional<ParserData> parseModuleExtra(String extra) {
160134
String[] all = extra.split("=", 2);
161135
if (all.length < 2) {
162-
return null;
136+
return Optional.empty();
163137
}
164138

165139
String[] source = all[0].split("/", 2);
166140
if (source.length < 2) {
167-
return null;
141+
return Optional.empty();
168142
}
169-
return new ParserData(source[0], source[1], all[1]);
143+
return Optional.of(new ParserData(source[0], source[1], all[1]));
170144
}
171145

172146
private static class ParserData {
@@ -182,14 +156,10 @@ private static class ParserData {
182156
}
183157

184158
// ForgeWrapper need some extra settings to invoke BootstrapLauncher.
185-
public static void setupBootstrapLauncher() throws Throwable {
186-
MethodHandle implAddOpensMH = IMPL_LOOKUP.findVirtual(Module.class, "implAddOpens", MethodType.methodType(void.class, String.class, Module.class));
187-
ModuleLayer.boot().findModule("cpw.mods.bootstraplauncher").ifPresent(m -> {
188-
try {
189-
implAddOpensMH.invokeWithArguments(m, "cpw.mods.bootstraplauncher", ModuleUtil.class.getModule());
190-
} catch (Throwable t) {
191-
throw new RuntimeException(t);
192-
}
193-
});
159+
public static Class<?> setupBootstrapLauncher(Class<?> mainClass) throws Throwable {
160+
if (!mainClass.getModule().isOpen(mainClass.getPackageName(), ModuleUtil.class.getModule())) {
161+
TypeToAdd.OPENS.implAddMH.invokeWithArguments(mainClass.getModule(), mainClass.getPackageName(), ModuleUtil.class.getModule());
162+
}
163+
return mainClass;
194164
}
195165
}

settings.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
rootProject.name = 'ForgeWrapper'
22

3+
include 'common'
34
include 'converter'
45
include 'jigsaw'
56
include 'legacy'

0 commit comments

Comments
 (0)