2016-02-18 7 views
5

Serialisierung dies bewirkt eine Stackoverflow:Gson: Serialisierung eine java.nio.Path verursacht eine Stackoverflow

import java.nio.file.Path; 
import java.nio.file.Paths; 

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

Es sieht aus wie ein Bug zu mir! Oder mache ich etwas falsch? Gibt es Abhilfe (erwarten einige benutzerdefinierte Serializer zu schreiben, die den Pfad zu String konvertiert)

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) 
    ... 

Serialisierung Methode ist:

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); 
} 
+0

http://stackoverflow.com/q/36964995/1032167 weitere Informationen. Erstellen Sie benutzerdefinierte 'Klasse PathConverter implementiert JsonDeserializer , JsonSerializer ' und registrieren Sie es als '.RegisterTypeHierarchyAdapter (Path.class, neue MyPathConverter())' – varren

Antwort

3

Untersuchen Sie die von Paths.get("c:\\temp\\"); in einem Debugger zurückgegebene Objekt. Auf meinem Computer hat es ein Feld mit dem Namen fs, das eine WindowsFileSystem enthält. Dies wiederum hat ein Feld provider, das ein WindowsFileSystemProvider enthält - und provider hat ein Feld theFileSystem, das das gleiche WindowsFileSystem enthält wie das ursprüngliche Feld fs. Voila, zyklische Referenz.

Gson verwendet Reflektion, um rekursiv jedes nicht-transiente Feld in dem Objekt, das Sie ihm geben, zu inspizieren und serialisieren. Eine zyklische Referenz wie diese sendet sie in eine unendliche Rekursion, die in StackOverflowError endet. Um dies zu beheben, müssen Sie entweder eine benutzerdefinierte Serialisierung implementieren oder eine bestimmte Eigenschaft des Path statt des gesamten Objekts serialisieren. Das Markieren irgendeines oder aller der in dem Zyklus involvierten Felder, wie , würde ebenfalls funktionieren, aber das würde Schreibzugriff auf den Bibliothekscode erfordern.

+1

Ich verstehe, dass. Aber gleichzeitig ist diese Klasse eine Kern-Java-Klasse seit Java 7 und sollte von Gson korrekt gehandhabt werden. Ich finde es nicht gut, dass jeder Entwickler seinen eigenen Serializer/Deserializer für diese Klasse implementieren muss. Dies sollte ein Kernmerkmal von Gson sein. – lvr123

+1

@ lvr123 Es implementiert nicht 'Serializable' und sein Zweck besteht hauptsächlich darin, Daten zu parsen, zu validieren, zu manipulieren und anderweitig zu verwenden, nicht um sie zu speichern. Weder Gson noch irgendeine andere Serialisierungsbibliothek hat einen guten Grund, um eine spezielle Handhabung zu geben, da die Serialisierung nicht das ist, wofür "Pfad" ist. Map und die vielen Subschnittstellen von Collection haben Datenspeicher als Hauptzweck, und Gson hat eine spezielle Handhabung für diese. – Douglas

+2

Was schlagen Sie vor, diesen Objekttyp zu serialisieren? – lvr123

Verwandte Themen