google / gson

A Java serialization/deserialization library to convert Java Objects into JSON and back
Apache License 2.0
23.23k stars 4.27k forks source link

`.fromJson()` throws exception #2413

Closed Sombian closed 1 year ago

Sombian commented 1 year ago

Gson version

2.9.1

Java / Android version

corretto-17 (17.0.7)

Used tools

Description

invoking .fromJson() method against record class throws exception.

Expected behavior

no exceptions.

Actual behavior

exceptions.

Reproduction steps

record Person(String name, Integer age) {}

...

Gson gson = new GsonBuilder().create();

var person = new Person("person", 0);

var personString = gson.toJson(person);

System.out.println(personString); // {"name":"person","age":0}

var personBack = gson.fromJson(personString, Person.class); // exception

System.out.println(personBack);

Exception stack trace

Exception in thread "main" java.lang.RuntimeException: Unexpected IllegalAccessException occurred (Gson 2.9.1). 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:69)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:272)
    at com.google.gson.Gson.fromJson(Gson.java:1058)
    at com.google.gson.Gson.fromJson(Gson.java:1016)
    at com.google.gson.Gson.fromJson(Gson.java:959)
    at com.google.gson.Gson.fromJson(Gson.java:927)
    at me.sombian.konosuba.Server.main(Server.java:42)
Caused by: java.lang.IllegalAccessException: Can not set final java.lang.String field me.sombian.konosuba.Server$Person.name to java.lang.String
    at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwFinalFieldIllegalAccessException(UnsafeFieldAccessorImpl.java:76)
    at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwFinalFieldIllegalAccessException(UnsafeFieldAccessorImpl.java:80)
    at java.base/jdk.internal.reflect.UnsafeQualifiedObjectFieldAccessorImpl.set(UnsafeQualifiedObjectFieldAccessorImpl.java:79)
Caused by: java.lang.IllegalAccessException: Can not set final java.lang.String field me.sombian.konosuba.Server$Person.name to java.lang.String

    at java.base/java.lang.reflect.Field.set(Field.java:799)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:166)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:266)
    ... 5 more
eamonnmcmanus commented 1 year ago

Support for serializing and deserializing Java records was added in Gson 2.10. I think your example works there.