Gson: serializing java.nio.Path raises a StackOverflowError

Serializing this causes a StackOverFlowError:

import java.nio.file.Path; import java.nio.file.Paths; public class Tmp{ private Path path=null; public Tmp() { path=Paths.get("c:\\temp\\"); } } 

This seems like a mistake! Or am I doing something wrong? Is there a workaround (expect to write some kind of custom serializer that converts the path to String)

 java.lang.StackOverflowError at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:372) at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:381) at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:376) ... at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:128) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:75) at com.google.gson.Gson.getAdapter(Gson.java:358) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getFieldAdapter(ReflectiveTypeAdapterFactory.java:109) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.access$100(ReflectiveTypeAdapterFactory.java:46) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.<init>(ReflectiveTypeAdapterFactory.java:84) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:83) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:129) ... 

Serialization Method:

 public static void saveTo(BatchLogging logging, Path path) throws IOException { Gson gson=new GsonBuilder().setPrettyPrinting().create(); // String json = gson.toJson(logging); String json = gson.toJson(new Tmp()); List<String> lines = Arrays.asList(json.split(System.lineSeparator())); Files.write(path, lines, StandardCharsets.UTF_8); } 
+5
source share
1 answer

Examine the object returned by Paths.get("c:\\temp\\"); in the debugger. On my machine, it has a field called fs that contains WindowsFileSystem . This, in turn, has a provider field that contains a WindowsFileSystemProvider - and provider has a theFileSystem field that contains the same WindowsFileSystem as the original fs field. Voila, circular link.

Gson uses reflection to validate and serialize, recursively, every non-transition field in the object that you give it. A loopback like this sends it to infinite recursion ending in a StackOverflowError . To fix this, you need to either implement custom serialization or serialize a specific Path property, not the entire object. Marking any or all of the fields involved in the loop as transient will also work, but this will require write access to the library code.

+3
source

Source: https://habr.com/ru/post/1243350/


All Articles