Hey,
I’m developing a project (A Minecraft fabric mod) that has multiple submodules, each with their own implementation of the mod and each using different version of the Minecraft api (basically a library, this should also apply to project that has multiple implementations for each version of another library, I think you can ignore the Minecraft-part here).
Currently I have multiple files that are identical between the implementations, because the underlying Minecraft api interfaces haven’t changed between the versions. I have tried to move this logic into its own submodule called “common”, and the idea was that the common code would use one version of the Minecraft api (1.19, in compile time I guess?) to get autocompletion and satisfy the compiler, but then when it’s required as a dependency in each mod implementation, it would use the implementation’s version instead. The code would still work since the files are identical in each version anyways.
So the question is: Is it possible to somehow copy the common code to each implementation when building the project, without modifying the implementation classpath, so that for example import net.minecraft.item.Item;
would resolve into the corresponding Minecraft api used in the current implementation. I know this would be unsafe since the compiler would only check against 1.19 api when developing the common code, but to me this still seems better than copying the changes between each implementation by hand.
In case the explanation is as confusing as I assume, here is an example of how the project currently looks: https://github.com/aleksilassila/litematica-printer/tree/subprojects-example.
An example of an identical file between the implementations would be the Printer.java file:
implementation/v1_19/src/main/java/me/aleksilassila/litematica/printer/v1_19/printer/Printer.java
Currently I tried to just include the common code in the 1.19 implementation’s build.gradle like this:
implementation(project(":common")) {
transitive = false // Not sure what is this for but it runs into runtime error instead of compile error
}
And then call the common code here:
me/aleksilassila/litematica/printer/v1_19/LitematicaMixinMod.java:60
System.out.println(CommonCode.ping("PING"));
MinecraftClient c = MinecraftClient.getInstance();
System.out.println("GAME VERSION FROM COMMON CODE: " + CommonCode.getVersion(c));
CommonCode looks like this:
me/aleksilassila/litematica/printer/common/CommonCode.java:5
public static String getVersion(MinecraftClient client) {
return client.getGameVersion();
}
public static String ping(String string) {
return string;
}
However, calling the getVersion(MinecraftClient) produces the following error:
Caused by: java.lang.NoSuchMethodError: 'java.lang.String me.aleksilassila.litematica.printer.common.CommonCode.getVersion(net.minecraft.client.MinecraftClient)'
Because the ping(String) can be called just fine, the runtime issues arise only when using the Minecraft api.
So: can i somehow configure the CommonCode to use the same Minecraft api version as the implementation it is being used in? Or just copy the CommonCode over to each implementation? Or is there a better way to do this?
Any help is greatly appreciated.