2011-12-02 16 views
9

के बारे में मैंने कुछ संबंधित प्रश्न और उत्तर यहां देखा, लेकिन वे मदद नहीं कर पाए। तो मुझे लगता है कि मुझे यहां एक अलग प्रश्न पोस्ट करने की आवश्यकता है:क्रमबद्धता, serialVersionUID, और असंगत वर्ग

मेरे पास एक धारावाहिक वर्ग MyDataClass है, जिसमें कुछ और धारावाहिक आंतरिक कक्षाएं हैं। मैं इसे FileOutputStream और ObjectOutputStream का उपयोग कर फ़ाइल में सहेजता हूं। जब इसे पढ़ने वापस, मैं कभी कभी एक अपवाद मिल (शायद ClassNotFoundException या InvalidClassException लेकिन मुझे यकीन नहीं कर रहा हूँ), और अपवाद के संदेश इस प्रकार है:

public static class MyDataClass implements Serializable { 

    private static final long serialVersionUID = 0x98F22BF5; 
    ..... 
    public boolean bNoTitle; 
    public short syncOption; 
    ..... 

    public class InnerClass implements Serializable { 
     private static final long serialVersionUID = 0x99D32720; 
     double premium; 
     double interest; 
    } 
} 
:

12-01 18:44:16.479: D/My App Name(534): ***** exception occurred 
com.xyz.myapp.lib.am; Incompatible class (SUID): com.xyz.myapp.lib.am: 
static final long serialVersionUID =3894560643019408205L; but expected 
com.xyz.myapp.lib.am: static final long serialVersionUID =-4215454881436014736L; 

MyDataClass कुछ इस तरह है

तो मैं इसे पढ़ने के लिए निम्न कोड का प्रयोग किया:

MyDataClass oc; 
FileInputStream fin = new FileInputStream(dataFile); 
ObjectInputStream ois = new ObjectInputStream(fin); 
oc = (MyDataClass)ois.readObject(); 
ois.close(); 
fin.close(); 

एक अपवाद readObject, हर समय से फेंक दिया जाता है, लेकिन कभी कभी यह है कि मैं नहीं कर सकता अभी तक pinpoint। मैंने कहीं पढ़ा है कि वास्तव में फ़ाइल में लिखा गया serialVersionUID वह नहीं है जो मैंने कोड में असाइन किया था। तो जब इसे वापस पढ़ा जाता है, तो यूआईडी मेल नहीं खाता है, और इस प्रकार अपवाद। क्या वह सही है? यदि हां, तो मैं कैसे सुनिश्चित कर सकता हूं कि कोई अपवाद नहीं है और ऑब्जेक्ट को अपेक्षित रूप से वापस पढ़ा जाता है?

धन्यवाद।

संपादित करें: ऐसा लगता है कि ग्रहण से डीबगिंग करते समय, यह ठीक था। लेकिन जब मैंने ant का उपयोग करके निर्माण किया, तो समस्या सामने आएगी। लेकिन ant निर्माण के बाद हर बार नहीं, लेकिन कभी-कभी।

संपादित करें:

आप एक फ़ाइल से पढ़ने रहे हैं: मैं एक और पोस्ट में देखा था? उस स्थिति में, इससे कोई फ़र्क नहीं पड़ता कि आपने अब serialVersionUID को जोड़ा है, यह फ़ाइल में संग्रहीत एक से अलग है, और यह अपवाद बनाता है। SerialVersionUID को 4209360273818925922L पर सेट करने का एक त्वरित समाधान हो सकता है, जो धारावाहिक VersionUID प्रतीत होता है जो जावा द्वारा स्वचालित रूप से जेनरेट किया गया था जब आपने उस समय उस ऑब्जेक्ट को उस फ़ाइल में सहेजा था।

उपयोगकर्ता फ़ाइल को ऐप का उपयोग करने पर कई बार सहेजा/पढ़ा जाएगा। यदि जावा एक अलग यूआईडी प्रत्येक बार फ़ाइल को सहेजता है, तो मैं कोड से पहले कोड में नंबर कैसे तार कर सकता हूं? मुझे ant निर्माण के बाद भी वास्तव में स्थैतिक यूआईडी की आवश्यकता नहीं है।

+0

क्या आप जानबूझकर serialVersionUID के रूप में एक पूर्णांक असाइन करते हैं? आम तौर पर यह कोई समस्या नहीं होनी चाहिए लेकिन आमतौर पर आपको लंबे मूल्यों का उपयोग करना चाहिए। – Robert

+0

@Robert, जाहिर है, यह ऐसा ही होता है। मुझे नहीं लगता कि यह एक समस्या है। – wwyt

उत्तर

1

जैसा कि आप स्पष्ट रूप से serialVersionUID घोषित कर रहे हैं, तब तक धारावाहिक और deserializing में कोई समस्या नहीं होनी चाहिए जब तक serialVersionUID नहीं बदला जाता है (और कक्षा में भारी बदलाव नहीं हुआ है)।

अपवाद संदेश से मुझे लगता है कि आपके पास कुछ सदस्य वर्ग हो सकता है जो धारावाहिक हो रहा है लेकिन इसमें स्पष्ट सीरियल संस्करण यूआईडी नहीं है, इसलिए आपको उस वर्ग में धारावाहिक VERSIONUID को स्पष्ट रूप से घोषित करने की आवश्यकता हो सकती है।

एक और संभावना यह है कि आप स्पष्ट रूप से एक फ़ाइल को पढ़ने की कोशिश कर रहे हैं जो स्पष्ट serialVersionUID डालने से पहले सहेजा गया था।

+0

प्रतिक्रियाओं के लिए धन्यवाद। ये वास्तव में बहुत ही स्मार्ट अनुमान हैं, खासकर दूसरा। लेकिन मुझे पूरा यकीन है कि ये मामले नहीं हैं। लेकिन पॉइंटर्स के लिए धन्यवाद। – wwyt

2

मैं AKJ से सहमत:

मुझे लगता है कि आपकी पहली समस्या के लिए 'वर्ग नहीं मिला' - आप शायद एक वातावरण है जो इस वर्ग को नहीं जानता है में वर्ग deserializing कर रहे हैं। यह भी संभव है कि आपके पास कक्षा के 2 प्रतियों के साथ 2 enviornments है।

कोई भी, सीरियलाइजेशन का यूआईडी इस प्रकार काम करता है: यदि आपने एक निर्दिष्ट नहीं किया है, तो यह हर बार संकलित/निर्माण करने पर स्वचालित रूप से उत्पन्न होगा - अन्यथा, यदि आपने एक निर्दिष्ट किया है, तो वह एक यूआईडी है।

ध्यान दें कि एजेके आपको यह जानने के बिना सही हो सकता है - आपकी कक्षा के प्रत्येक वर्ग के सदस्य को डिफ़ॉल्ट रूप से क्रमबद्ध किया जाता है, जब तक कि इसे घोषित करने पर आप क्षणिक निर्दिष्ट नहीं करते हैं। इसलिए, यदि आपके पास छोटा, लंबा, स्ट्रिंग, MyClass या जो कुछ भी है, तो वे सभी serilization के माध्यम से जाना होगा। उपरोक्त स्पष्टीकरण के अनुसार, यदि कोई स्थिर यूआईडी सेट नहीं है, तो हर बार जब आप वाईपीयू संकलित करेंगे तो एक अलग यूआईडी प्राप्त होगा - और इससे आपकी समस्या हो सकती है।

शुभकामनाएं।

संबंधित मुद्दे