gson: Error reflection JDK 17 and gson

Hi.

I’m using gson (version 2.8.8), and only with JDK 17 this code:

JsonReader configFileReader = new JsonReader(new FileReader(new File("C:\test.txt"));
result = gson.fromJson(configFileReader, clazz);

throws this exception:

Exception in thread "main" java.lang.reflect.InaccessibleObjectException: Unable to make field private final java.lang.String java.security.KeyFactory.algorithm accessible: module java.base does not "opens java.security" to unnamed module @4445629
	at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
	at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
	at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:178)
	at java.base/java.lang.reflect.Field.setAccessible(Field.java:172)
	at com.google.gson.internal.reflect.UnsafeReflectionAccessor.makeAccessible(UnsafeReflectionAccessor.java:44)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:159)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:102)
	at com.google.gson.Gson.getAdapter(Gson.java:458)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:117)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:166)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:102)
	at com.google.gson.Gson.getAdapter(Gson.java:458)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:117)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:166)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:102)
	at com.google.gson.Gson.getAdapter(Gson.java:458)
	at com.google.gson.internal.bind.CollectionTypeAdapterFactory.create(CollectionTypeAdapterFactory.java:53)
	at com.google.gson.Gson.getAdapter(Gson.java:458)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:117)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:166)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:102)
	at com.google.gson.Gson.getAdapter(Gson.java:458)
	at com.google.gson.Gson.fromJson(Gson.java:931)

The same code works with previous JDK’s.

About this issue

  • Original URL
  • State: open
  • Created 3 years ago
  • Reactions: 12
  • Comments: 19 (3 by maintainers)

Commits related to this issue

Most upvoted comments

Similar to #1963 and other existing reports. Apparently you are deserializing a JDK class (java.security.KeyFactory) without having specified a custom type adapter for it. Gson will then by default use a reflection based type adapter. You have to write a custom type adapter to solve this issue.

The reason why this is causing an exception for JDK 17 is because JDK internals are now strongly encapsulated (see JEP 403). In general you should avoid using reflection based serialization and deserialization for classes which you do not control because you rely on their implementation details which could change at any point. (Unfortunately Gson currently does not have a setting for easily blocking such undesired reflective access.)


Note that I am not a maintainer of this project.

It may be a good idea to include java.time adapters in the library by default.

It might make sense for us to have a separate artifact that includes TypeAdapters for java.time, Optional, and the like. Or perhaps just a single TypeAdapterFactory for those.

It may be a good idea to include java.time adapters in the library by default. I find myself having to copy the same adapters across multiple projects and use a static utility to construct the Gson object. I understand you guys want to also support Java 7, but this really is a pain point.

@yexiaobin909090 The specific error that you are running into is the one that is and fixed here: https://github.com/googleapis/java-spanner/pull/1426

Upgrading your Spanner client to at least version 6.12.4 should fix this problem.