Gson version
2.13.2
Java / Android version
openjdk version "26" 2026-03-17
OpenJDK Runtime Environment (build 26+35-2893)
OpenJDK 64-Bit Server VM (build 26+35-2893, mixed mode, sharing)
Used tools
Description
A final field mutation warning appears when running under Java 26.
Expected behavior
No warnings expected.
Actual behavior
Warning appears.
Reproduction steps
import com.google.gson.Gson;
class ClassWithFinalField {
final String finalField;
ClassWithFinalField(String s) {
finalField = s;
}
void print() {
IO.println(finalField);
}
}
void main() {
new Gson().fromJson(
"""
{"finalField":"Hello, world!"}
"""
, ClassWithFinalField.class).print();
}
- Run with Java 25; no warnings, mutation works.
- Run with Java 26; warnings emitted, mutation still works but is going to be disallowed in a future release.
To run, download gson 2.13.2 jar from maven central, save the code above to a file named TestFinalFieldModification.java, and run the following:
java -cp gson-2.13.2.jar TestFinalFieldModification.java
For Java 26, replace java with the path to java 26 binary, like ./jdk-26/bin/java
*Java 26 is still in early access but is going to reach general availability in approx. 1 week from now on so I wanted to create the issue in advance.
Exception stack trace
WARNING: Final field finalField in class TestFinalFieldModification$ClassWithFinalField has been mutated reflectively by class com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$2 in unnamed module @59fd97a8 (file:/home/mustafa/%c4%b0ndirilenler/gson-2.13.2.jar)
WARNING: Use --enable-final-field-mutation=ALL-UNNAMED to avoid a warning
WARNING: Mutating final fields will be blocked in a future release unless final field mutation is enabled
When using --illegal-final-field-mutation=debug:
Final field finalField in class TestFinalFieldModification$ClassWithFinalField has been mutated reflectively by class com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$2 in unnamed module @795cd85e (file:/home/mustafa/%c4%b0ndirilenler/gson-2.13.2.jar)
at java.base/java.lang.reflect.Field.postSetFinal(Field.java:1534)
at java.base/java.lang.reflect.Field.setFinal(Field.java:1449)
at java.base/java.lang.reflect.Field.set(Field.java:909)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$2.readIntoField(ReflectiveTypeAdapterFactory.java:282)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$FieldReflectionAdapter.readField(ReflectiveTypeAdapterFactory.java:559)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:517)
at com.google.gson.Gson.fromJson(Gson.java:1358)
at com.google.gson.Gson.fromJson(Gson.java:1259)
at com.google.gson.Gson.fromJson(Gson.java:1169)
at com.google.gson.Gson.fromJson(Gson.java:1106)
at TestFinalFieldModification.main(TestFinalFieldModification.java:16)
at jdk.compiler/com.sun.tools.javac.launcher.SourceLauncher.execute(SourceLauncher.java:262)
at jdk.compiler/com.sun.tools.javac.launcher.SourceLauncher.run(SourceLauncher.java:138)
at jdk.compiler/com.sun.tools.javac.launcher.SourceLauncher.main(SourceLauncher.java:76)
When using --illegal-final-field-mutation=deny (going to be the default behaviour in a later release):
Exception in thread "main" java.lang.RuntimeException: Unexpected IllegalAccessException occurred (Gson 2.13.2). Certain ReflectionAccessFilter features require Java >= 9 to work correctly. If you are not using ReflectionAccessFilter, report this to the Gson maintainers.
at com.google.gson.internal.reflect.ReflectionHelper.createExceptionForUnexpectedIllegalAccess(ReflectionHelper.java:201)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:523)
at com.google.gson.Gson.fromJson(Gson.java:1358)
at com.google.gson.Gson.fromJson(Gson.java:1259)
at com.google.gson.Gson.fromJson(Gson.java:1169)
at com.google.gson.Gson.fromJson(Gson.java:1106)
at TestFinalFieldModification.main(TestFinalFieldModification.java:16)
Caused by: java.lang.IllegalAccessException: class com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$2 (in unnamed module @59fd97a8) cannot set final field TestFinalFieldModification$ClassWithFinalField.finalField (in unnamed module @f5ac9e4), unnamed module @59fd97a8 is not allowed to mutate final fields
at java.base/java.lang.reflect.Field.preSetFinal(Field.java:1504)
at java.base/java.lang.reflect.Field.setFinal(Field.java:1447)
at java.base/java.lang.reflect.Field.set(Field.java:909)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$2.readIntoField(ReflectiveTypeAdapterFactory.java:282)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$FieldReflectionAdapter.readField(ReflectiveTypeAdapterFactory.java:559)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:517)
at com.google.gson.Gson.fromJson(Gson.java:1358)
at com.google.gson.Gson.fromJson(Gson.java:1259)
at com.google.gson.Gson.fromJson(Gson.java:1169)
at com.google.gson.Gson.fromJson(Gson.java:1106)
at TestFinalFieldModification.main(TestFinalFieldModification.java:16)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
at java.base/java.lang.reflect.Method.invoke(Method.java:565)
at jdk.compiler/com.sun.tools.javac.launcher.SourceLauncher.execute(SourceLauncher.java:262)
at jdk.compiler/com.sun.tools.javac.launcher.SourceLauncher.run(SourceLauncher.java:138)
at jdk.compiler/com.sun.tools.javac.launcher.SourceLauncher.main(SourceLauncher.java:76)
References
JEP 500: Prepare to Make Final Mean Final
Gson version
2.13.2
Java / Android version
Used tools
Description
A final field mutation warning appears when running under Java 26.
Expected behavior
No warnings expected.
Actual behavior
Warning appears.
Reproduction steps
To run, download gson 2.13.2 jar from maven central, save the code above to a file named TestFinalFieldModification.java, and run the following:
For Java 26, replace java with the path to java 26 binary, like ./jdk-26/bin/java
*Java 26 is still in early access but is going to reach general availability in approx. 1 week from now on so I wanted to create the issue in advance.
Exception stack trace
When using --illegal-final-field-mutation=debug:
When using --illegal-final-field-mutation=deny (going to be the default behaviour in a later release):
References
JEP 500: Prepare to Make Final Mean Final