Minecraftforge: Lambda functions referencing access-transformed classes crash on OpenJ9

Created on 27 Nov 2018  路  8Comments  路  Source: MinecraftForge/MinecraftForge

Came across this while investigating https://github.com/TeamTwilight/twilightforest/issues/660, see this gist for a minimal reproduction of the crash.

The code causing the crash is the lambdas used for the removeIf calls in initEntityAI here:
https://github.com/TeamTwilight/twilightforest/blob/3375a143c91d0c5f51c6aac21c55ab4cb76d0deb/src/main/java/twilightforest/entity/EntityTFHedgeSpider.java#L28-L48

Forge ATs EntityAITaskEntry to be public here
https://github.com/MinecraftForge/MinecraftForge/blob/5771c8ffea9a4b31043358a26ec456218a724ac0/src/main/resources/forge_at.cfg#L187

but for whatever reason, this is not effective/sufficient for OpenJ9.

Bug

Most helpful comment

https://www.eclipse.org/openj9/

Not java 9, but an alternate confusingly named VM

All 8 comments

i'd suggest reporting this to openj9. They might have done something before actual classloading.

@liach The referenced class is _package-private_ (aka default) and net.minecraft.entity.ai != twilightforest.entity therefore I think this is forge's fault.

Unless I'm misunderstanding the JVMS for 9.

A class or interface C is accessible to a class or interface D if and only if one of the following is true:

  • C is public, and a member of the same run-time module as D.
  • C is public, and a member of a different run-time module than D, and C's run-time module is read by D's run-time module, and C's run-time module exports C's run-time package to D's run-time module.
  • C is not public, and C and D are members of the same run-time package.

Java 8 vs 9 may have gotten around this dilemma because of lambda's behaviors: dynamic sites instead of synthetic bridge methods.

Either way - it's likely not a load-time error but link-time.

@bs2609 I theorize making the inner class public in source (not via a transformer) might fix the issue... Going about this might be hard...

May have to change forge's ClassLoader semantics which I wouldn't attempt, they're a mess. Every time I've tried, I've broken more than I've fixed. (But I suck... Sooooooo, good luck?)

This is not the difference between java 8 and java 9. This is between oracle jvm and ibm jvm (openj9 is from ibm jdk). The game is run with ibm jvm for java 8.

What's worse, openj9 has a very special way to compile its code (like #ifdef in c), rendering the line numbers in the stack trace obsolete. The only clue is that the error is thrown at https://github.com/eclipse/openj9/blob/82d9955f5b161cc1fb90742ca6d23272d929cbfe/jcl/src/java.base/share/classes/java/lang/invoke/MethodHandles.java#L549

Forge runs in openj9?!

https://www.eclipse.org/openj9/

Not java 9, but an alternate confusingly named VM

Should probably also mention here that this crash does not occur in a dev environment, only in a normal runtime environment.

Was this page helpful?
0 / 5 - 0 ratings