WTHIT Forge Edition

WTHIT Forge Edition

3M Downloads

Build question, Java 16 compatibility

Fourmisain opened this issue ยท 9 comments

commented

When I build this project by setting MOD_VERSION=2.10.1 and running gradlew build using either Java 8 or 11 (it does not build with 16 probably because it's using loom 0.6), the resulting fabric jar will not run with Java 16:

java.lang.IllegalAccessError: class mcp.mobius.waila.fabric.FabricWailaClient$$Lambda$2577/0x0000000801318840 tried to access protected method 'void mcp.mobius.waila.WailaClient.onItemTooltip(net.minecraft.class_1799, net.minecraft.class_1836, java.util.List)' (mcp.mobius.waila.fabric.FabricWailaClient$$Lambda$2577/0x0000000801318840 and mcp.mobius.waila.WailaClient are in unnamed module of loader net.fabricmc.loader.launch.knot.KnotClassLoader @290222c1)

This error is actually really easy to fix by making this method public:

protected static void onItemTooltip(ItemStack stack, TooltipContext context, List<Text> tooltip) {

But, confusingly, the official release works just fine with Java 16, so I wonder how it was built?

commented

I'm using Java 15 to build the 2.x jar, maybe that's why it works with Java 16? I'm not really sure. The compiler definitely didn't complain about any illegal access when I built the 1.17 branch (which use Java 16) though.

commented

The compiler definitely didn't complain about any illegal access when I built the 1.17 branch

No, not the compiler, I get this error when running the game.

I just tried building the 1.16 branch with Java 15 and this did indeed work, the error does not occur!

For sake of completeness I tried building the 1.17 branch with Java 16 too and first I got a ton of

unknown invokedynamic bsm: java/lang/invoke/StringConcatFactory/makeConcatWithConstants(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite; (tag=6 iif=false)

while building (0 idea what that's about) - it did build however.
But, when starting the game (21w20a) with Java 16 I do get the same IllegalAccessError again.
Does this not happen for you?

Summarized, at least for me, building the 1.16 branch with Java 8, 11 or 16, I get the IllegalAccessError when starting the game with Java 16 and only when building with Java 15 does it not occur.
I can only compile the 1.17 branch and run it with Java 16, which'll produce the same error again.

I do wonder what's going on, though it seems it's the safest option to make onItemTooltip public, since that'll eliminate the error in all cases.

commented

It runs fine here. Do you able to run the official 3.5.0 or the latest action jar?

Those both run fine for me too!

Actually, it doesn't even need to be static there. I wonder making it not fixes it...

Nah, being static or not won't affect this, this is about access rights and if a method can be static it always should be static.

This is the strangest issue I've encounter.

It really is strange.
Thing is, it's not just me, oliwoli over at minepkg built it too and it has the same issue.

What platform are you on? We both built it on Windows using AdoptOpenJDK, so maybe it's a platform related bug.

I wonder what's going on since there's also onCientTick (oh no typo) method that gets called from a lambda.

ClientTickEvents.END_CLIENT_TICK.register(client -> onCientTick());
ItemTooltipCallback.EVENT.register(WailaClient::onItemTooltip);

Indeed! Both methods are protected, but one of them is called in a lambda, the other is a method reference.
I did some digging and found some bugs related to method references and access rights: JDK-8227415 JDK-8138667 JDK-8139836
Those are all old and fixed, but it makes me think that we are experiencing an OpenJDK bug, possibly platform related.

commented

What platform are you on? We both built it on Windows using AdoptOpenJDK, so maybe it's a platform related bug.

Right now I'm using Windows, Java 16.0.1 from AdaptOpenJDK, but the released jar is built on GitHub actions that run Ubuntu.

but one of them is called in a lambda, the other is a method reference.

It's just syntactic sugar, it does the same as (stack, ctx, tooltips) -> WailaClient.onItemTooltip(stack, ctx, tooltips)

commented

Ah, I'm able to reproduce the crash. Running gradlew build is indeed resulting in that illegal access error but jar built from IDEA works just fine :/

commented

For sake of completeness I tried building the 1.17 branch with Java 16 too and first I got a ton of

unknown invokedynamic bsm: java/lang/invoke/StringConcatFactory/makeConcatWithConstants(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite; (tag=6 iif=false)

while building (0 idea what that's about) - it did build, however.

It's a known loom bug, shouldn't affect things.

But, when starting the game (21w20a) with Java 16 I do get the same IllegalAccessError again.
Does this not happen for you?

It runs fine here. Do you able to run the official 3.5.0 or the latest action jar?

This is the strangest issue I've encounter ๐Ÿ˜…. I wonder what's going on since there's also onCientTick (oh no typo) method that gets called from a lambda.

It seems it's the safest option to make onItemTooltip public, since that'll eliminate the error in all cases.

Actually, it doesn't even need to be static there. I wonder making it not fixes it...

commented

Ah, I'm able to reproduce the crash. Running gradlew build is indeed resulting in that illegal access error but jar built from IDEA works just fine :/

I think what happened here is that IDEA is using a different JDK. You can check by going to File -> Settings -> Build, Execution, ... -> Build Tools -> Gradle and at the bottom check "Gradle JVM".
That was with the 1.16 branch, right?

It's just syntactic sugar, it does the same as (stack, ctx, tooltips) -> WailaClient.onItemTooltip(stack, ctx, tooltips)

I know, but it's still a language feature that's subject to potential bugs in the compiler implementation as the OpenJDK bug reports indicate.
Actually, if I replace the method reference with the exact lambda from above, I can compile the 1.16 branch with Java 11 and have it run with Java 16 without any issues!
So I assume somewhere down the line from Java 11 to Java 15 a method reference related bug was fixed, it's a little weird that Java 11 has that bug, since it's an LTS version though.

Compiling the 1.16 branch with Java 16 is actually wrong, both gradle and loom don't support that version, so we should not expect it to work, so I'm just gonna say that's not an issue and at least it works when compiling with Java 15.

I also tried reproducing the issue for the 1.17 branch and ran all kinds of different build issues that are probably loom related but in the end I was able to build and run it without issues now!
I'm not sure what happened before, I thought 1.17 was broken too, but I might have been mistaken.

So in summary:

Building 1.16 with Java 15 works fine, building 1.17 with Java 16 works fine enough.
1.16 could be made more compatible (able to be compiled without Java 15) by replacing the method reference with a lambda, but I'm personally fine to have found a way to compile it.

So I actually tend to close this issue now, since I got the answer that I wanted, except there are any objections from your side?

commented

I think what happened here is that IDEA is using a different JDK. You can check by going to File -> Settings -> Build, Execution, ... -> Build Tools -> Gradle and at the bottom check "Gradle JVM".
That was with the 1.16 branch, right?

Yes, 1.16 branch, both of them even use the same JDK 15 and one of them didn't work.

Anyway, yeah I think I'll just replace it with the lambda version. Thanks for going into such detail about this issue!

commented

Yes, 1.16 branch, both of them even use the same JDK 15 and one of them didn't work.

I don't actually wanna think about what happened there, let's just hope we don't run into this issue anymore... ๐Ÿ˜