2016-02-18 8 views
5

इस Serializing का कारण बनता है, एक StackOverFlowError कारण बनता है:Gson: एक java.nio.Path serializing एक 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\\"); 
    } 
} 

यह मेरे लिए एक बग की तरह लग रहा है! या मैं कुछ गलत कर रहा हूँ? वहाँ वैकल्पिक हल है (कि स्ट्रिंग के लिए पथ धर्मान्तरित कुछ कस्टम serializer लिख उम्मीद)

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

Serializing विधि है:

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 अधिक जानकारी। कस्टम 'क्लास पाथकॉन्टरर लागू करें जेसनडेसरियललाइज़र , जेसनसेरियलज़र ' और इसे '.registerTypeHierarchyAdapter (Path.class, new MyPathConverter())' – varren

उत्तर

3

वस्तु एक डिबगर में Paths.get("c:\\temp\\"); द्वारा वापस की जांच करना। मेरी मशीन पर, इसमें fs नामक एक फ़ील्ड है जिसमें WindowsFileSystem है। बदले में, इसमें provider फ़ील्ड है जिसमें WindowsFileSystemProvider है - और provider में फ़ील्ड theFileSystem है जिसमें मूल fs फ़ील्ड है। वोला, चक्रीय संदर्भ।

जीसन आपके द्वारा दिए गए ऑब्जेक्ट में प्रत्येक गैर-क्षणिक क्षेत्र का निरीक्षण और क्रमबद्ध करने के लिए प्रतिबिंब का उपयोग करता है। इस तरह एक चक्रीय संदर्भ इसे अनंत रिकर्सन में भेजता है, जो StackOverflowError में समाप्त होता है। इसे ठीक करने के लिए, आपको या तो कस्टम क्रमबद्धता लागू करने या पूरे ऑब्जेक्ट की बजाय Path की विशिष्ट संपत्ति को क्रमबद्ध करने की आवश्यकता होगी। transient के रूप में चक्र में शामिल किसी भी या सभी फ़ील्ड को चिह्नित करना भी काम करेगा, लेकिन इसके लिए पुस्तकालय के कोड में लेखन पहुंच की आवश्यकता होगी।

+1

'के रूप में पंजीकृत करें। लेकिन साथ ही, यह कक्षा जावा 7 के बाद से कोर जावा क्लास है और इसे जीसन द्वारा सही तरीके से संभाला जाना चाहिए। मुझे यह नहीं लगता कि प्रत्येक डेवलपर को इस कक्षा के लिए अपने स्वयं के धारावाहिक/deserializer लागू करना होगा। यह जीसन की मुख्य विशेषता होनी चाहिए। – lvr123

+1

@ lvr123 यह 'सीरियलज़ेबल 'को लागू नहीं करता है और इसका उद्देश्य अधिकतर डेटा को पार्स, मान्य, कुशलतापूर्वक उपयोग करने और डेटा का उपयोग करने के लिए है, इसे स्टोर न करने के लिए। न तो जीसन और न ही किसी अन्य धारावाहिक पुस्तकालय के पास इसे विशेष हैंडलिंग देने का एक अच्छा कारण है क्योंकि धारावाहिकता 'पथ' के लिए नहीं है। मानचित्र और संग्रह के कई उपनिवेशों में डेटा संग्रहण को उनके प्राथमिक उद्देश्य के रूप में रखा गया है, और जीसन के लिए विशेष हैंडलिंग है। – Douglas

+2

इस प्रकार के ऑब्जेक्ट को क्रमबद्ध करने का प्रस्ताव क्या है? – lvr123