Remix.run Logo
pron a day ago

Ah, that's a great question, and the answer is in the JEP (https://openjdk.org/jeps/500#Mutating-final-fields-from-nati...).

When running with -Xcheck:jni, you'll get a warning when trying to mutate a final field with JNI.

Now, enabling this check by default without harming JNI performance proved to be too much of an effort. However, mutating final fields with JNI even today can already lead to undefined behaviour, including horrible miscompilation, where different Java methods can read different values of the field, for final fields that the JVM already trusts to be immutable, such as static finals, record components, or a few other cases (indeed, there are non-final fields that the JVM trusts to be assigned only once, and mutating those with JNI is also undefined behaviour). As the compiler starts trusting more final fields after this change, mutating almost all final fields will lead to undefined behaviour. Then again, using JNI can lead to undefined behaviour in many ways.

So to make sure your JNI code isn't mutating finals, test with -Xcheck:jni (as of JDK 26).

gorset a day ago | parent [-]

This brings back memories debugging an azul zing bug where an effectively final optimization ended up doing the wrong thing with zstd-jni. It was painful enough that I couldn’t convince the team to enable the optimization again for years after it was fixed.