Prepare for final field mutation warning under Java 26
- Dominant language
- Java
- Stars
- 24.2k
- Forks
- 4.5k
- Avg merge
- 6d 4h
- Merged PRs (30d)
- 12
Description
# 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
- [ ] Maven; version:
- [ ] Gradle; version:
- [ ] ProGuard (attach the configuration file please); version:
- [ ] ...
# Description
A final field mutation warning appears when running under Java 26.
## Expected behavior
No warnings expected.
## Actual behavior
Warning appears.
# Reproduction steps
```java
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();
}
```
1. Run with Java 25; no warnings, mutation works.
2. 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](https://openjdk.org/jeps/500)
Contributor guide
Assessment
This issue has not been assessed yet.