Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calling RegionFolder.save() can cause Gson to throw an unhandled java.lang.reflect.InaccessibleObjectException in certain cases when attempting to serialise a Collection in SavedRegionHelper. #86

Open
akemin-dayo opened this issue Aug 30, 2022 · 1 comment

Comments

@akemin-dayo
Copy link

Calling RegionFolder.save() can cause Gson to throw an unhandled java.lang.reflect.InaccessibleObjectException in certain cases when attempting to serialise a Collection in SavedRegionHelper.

This is directly related to google/gson#1979 (comment) and the JEP 403: Strongly Encapsulate JDK Internals change made in Java 17.

As seen in that thread, using the JRE argument --add-opens java.base/java.lang=ALL-UNNAMED does indeed work around the issue, resulting in BlockMap working correctly again. (※ If you're a normal user coming across this thread since you're experiencing this issue, here's the "solution" you're looking for.)

When this exception is thrown, rendered.json becomes a 0-length file, resulting in all data being lost (well, more like not ever having been successfully serialised, let alone written to the disk to begin with).

It also results in the termination of BlockMap entirely, meaning that any actions that take place after a RegionFolder.save() call will also not occur. Most notably, this includes the merging of all rendered images via --create-big-image.

Finally, here's the full stacktrace:

java.lang.reflect.InaccessibleObjectException: Unable to make field private java.lang.String java.lang.Throwable.detailMessage accessible: module java.base does not "opens java.lang" to unnamed module @21213b92
       	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.getDelegateAdapter(Gson.java:572)
       	at io.gsonfire.gson.HooksTypeAdapterFactory.create(HooksTypeAdapterFactory.java:23)
       	at com.google.gson.Gson.getDelegateAdapter(Gson.java:572)
       	at io.gsonfire.gson.WrapTypeAdapterFactory.create(WrapTypeAdapterFactory.java:26)
       	at com.google.gson.Gson.getAdapter(Gson.java:489)
       	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.getDelegateAdapter(Gson.java:572)
       	at io.gsonfire.gson.HooksTypeAdapterFactory.create(HooksTypeAdapterFactory.java:23)
       	at com.google.gson.Gson.getDelegateAdapter(Gson.java:572)
       	at io.gsonfire.gson.TypeSelectorTypeAdapterFactory$TypeSelectorTypeAdapter.write(TypeSelectorTypeAdapterFactory.java:58)
       	at io.gsonfire.gson.NullableTypeAdapter.write(NullableTypeAdapter.java:26)
       	at io.gsonfire.util.JsonUtils.toJsonTree(JsonUtils.java:54)
       	at io.gsonfire.gson.HooksTypeAdapter.write(HooksTypeAdapter.java:42)
       	at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:69)
       	at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:97)
       	at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:61)
       	at io.gsonfire.util.JsonUtils.toJsonTree(JsonUtils.java:54)
       	at io.gsonfire.gson.HooksTypeAdapter.write(HooksTypeAdapter.java:42)
       	at com.google.gson.Gson.toJson(Gson.java:735)
       	at com.google.gson.Gson.toJsonTree(Gson.java:628)
       	at com.google.gson.Gson.toJsonTree(Gson.java:607)
       	at io.gsonfire.postprocessors.methodinvoker.MethodInvokerPostProcessor.postSerialize(MethodInvokerPostProcessor.java:82)
       	at io.gsonfire.gson.HooksTypeAdapter.runPostSerialize(HooksTypeAdapter.java:72)
       	at io.gsonfire.gson.HooksTypeAdapter.write(HooksTypeAdapter.java:49)
       	at io.gsonfire.util.JsonUtils.toJsonTree(JsonUtils.java:54)
       	at io.gsonfire.gson.HooksTypeAdapter.write(HooksTypeAdapter.java:42)
       	at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:69)
       	at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:97)
       	at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:61)
       	at io.gsonfire.util.JsonUtils.toJsonTree(JsonUtils.java:54)
       	at io.gsonfire.gson.HooksTypeAdapter.write(HooksTypeAdapter.java:42)
       	at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:69)
       	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:127)
       	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:245)
       	at io.gsonfire.util.JsonUtils.toJsonTree(JsonUtils.java:54)
       	at io.gsonfire.gson.HooksTypeAdapter.write(HooksTypeAdapter.java:42)
       	at com.google.gson.Gson.toJson(Gson.java:735)
       	at com.google.gson.Gson.toJson(Gson.java:714)
       	at com.google.gson.Gson.toJson(Gson.java:689)
       	at de.piegames.blockmap.world.RegionFolder$CachedRegionFolder.save(RegionFolder.java:536)
       	at de.piegames.blockmap.standalone.CommandLineMain$CommandRender.call(CommandLineMain.java:262)
       	at de.piegames.blockmap.standalone.CommandLineMain$CommandRender.call(CommandLineMain.java:113)
       	at picocli.CommandLine.executeUserObject(CommandLine.java:1953)
       	at picocli.CommandLine.access$1300(CommandLine.java:145)
       	at picocli.CommandLine$RunLast.executeUserObjectOfLastSubcommandWithSameParent(CommandLine.java:2358)
       	at picocli.CommandLine$RunLast.handle(CommandLine.java:2352)
       	at picocli.CommandLine$RunLast.handle(CommandLine.java:2314)
       	at picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:2179)
       	at picocli.CommandLine$RunLast.execute(CommandLine.java:2316)
       	at picocli.CommandLine.execute(CommandLine.java:2078)
       	at de.piegames.blockmap.standalone.CommandLineMain.mainWithoutQuit(CommandLineMain.java:399)
       	at de.piegames.blockmap.standalone.CommandLineMain.main(CommandLineMain.java:403)
@piegamesde
Copy link
Owner

Thanks for the detailed report. What do you think is the best way going forward? In the issue they mention using type adapters as a workaround, but I don't know of any. (There is a repository that added type adapters for Optional and other Java 8 types, but it has long been abandoned.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants