2008-09-30 21 views
20

के बीच संगत है, मुझे आश्चर्य है कि यह जेडीके 1.5 और 1.6 (जावा 6) ऑब्जेक्ट सीरियलाइजेशन (बाइडरक्शनल संचार) को मिश्रण करना सुरक्षित है या नहीं। मैंने इस सवाल से संबंधित सूर्य से एक स्पष्ट बयान की खोज की लेकिन सफल नहीं हुआ। इसलिए, तकनीकी व्यवहार्यता के अलावा मैं समस्या से संबंधित एक "आधिकारिक" कथन की तलाश में हूं।जावा ऑब्जेक्ट सीरियलाइजेशन 1.5 और 1.6

+0

मैं जानता हूँ कि यह एक पुराने सवाल है, लेकिन भविष्य डेवलपर्स के लिए, यह है कुछ ऐसा जो मैंने ग्राहकों के साथ बड़े पैमाने पर उपयोग किया है, कई वर्षों तक पीओजेओ का उपयोग कर सर्वर। संस्करणों के बीच क्रमबद्ध वस्तुओं ने समस्याओं के बिना काम किया है। जब हमने सीरियलाइजेशन नियम तोड़ दिए तो हमें एक समस्या थी। उदाहरण के लिए, एक चर के प्रकार को मत बदलें। –

उत्तर

2

जावा 1.5 प्रोग्राम में ऑब्जेक्टऑटपुटस्ट्रीम का उपयोग करके फ़ाइल में लिखे गए एक क्रमबद्ध ऑब्जेक्ट के साथ परीक्षण करने के बाद, जावा 1.6 प्रोग्राम में ऑब्जेक्ट इनपुटपुट के साथ एक पठन चला रहा है, मैं कह सकता हूं कि यह किसी भी मुद्दे के बिना काम करता है।

+0

नहीं आप नहीं कर सकते। आपने इसे एक वर्ग के लिए परीक्षण किया है। एक निगल गर्मी नहीं करता है। – EJP

16

धारावाहिक तंत्र स्वयं नहीं बदला है। व्यक्तिगत कक्षाओं के लिए यह विशिष्ट वर्ग पर निर्भर करेगा। यदि किसी वर्ग में एक serialVersionUID फ़ील्ड है, तो यह क्रमबद्धता compatiblity इंगित करने के लिए माना जाता है।

कुछ की तरह:

private static final long serialVersionUID = 8683452581122892189L; 

यदि यह अपरिवर्तित है, धारावाहिक संस्करणों संगत हैं। जेडीके कक्षाओं के लिए यह गारंटीकृत है, लेकिन निश्चित रूप से ब्रेकिंग परिवर्तन करने के बाद serialVersionUID को अपडेट करना हमेशा भूलना संभव है।

जब जेडीके कक्षाओं को संगत होने की गारंटी नहीं दी जाती है, तो इसका आमतौर पर जावाडोक में उल्लेख किया जाता है।

चेतावनी: इस वर्ग के धारावाहिक वस्तुओं भविष्य स्विंग रिलीज

2

मैं जल्दी से जोड़ना होगा कि यह वर्ग बदलने के लिए लेकिन भूल serialVersionUID बदलना संभव है के साथ संगत नहीं होगा। तो यह गलत है कि "यदि वर्ग एक serialVersionUID को परिभाषित करता है, और यह नहीं बदलता है, तो वर्ग को संगत होने की गारंटी दी जाती है।" इसके बजाय, एक ही serialVersionUID होने का तरीका एपीआई पिछड़ा संगतता का वादा करता है।

+0

मुझे लगता है कि सवाल जेडीके कक्षाओं के बारे में है, और यह कि उनके धारावाहिक VersionUID सही हैं ... – Tom

+0

पर्याप्त मेला: यदि आपका जेडीके अपग्रेड सीरियलज़ेबल को गड़बड़ कर देता है, तो आपके बड़े लड़के जेडीके (यानी सूर्य, बीईए, आईबीएम इत्यादि) के ग्राहक।) खूनी हत्या (और मेरे पास) चिल्लाया जाना चाहिए। माना जाता है कि सवाल स्पष्ट नहीं था कि यह केवल जेडीके वर्गों के बारे में था। – Alan

2

जब तक अन्यथा कहा न जाए, यह बाइनरी संगतता का हिस्सा होना चाहिए। स्विंग कक्षाएं स्पष्ट रूप से संस्करणों के बीच संगत नहीं हैं। यदि आपको अन्य कक्षाओं में कोई समस्या है, तो bugs.sun.com पर एक बग की रिपोर्ट करें।

+0

बाइनरी compatiblity जनता और संरक्षित इंटरफ़ेस के बारे में है, जबकि serialization संगतता आमतौर पर निजी क्षेत्रों के साथ सौदों। क्या आप सुनिश्चित हैं कि एक दूसरे का तात्पर्य है? – Tom

+0

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

2

क्या आपने Java Object Serialization Specification पढ़ा है? versioning पर एक विषय है। कक्षा कार्यान्वयनकर्ताओं के लिए एक लेख भी है: Discover the secrets of the Java Serialization API। जावा की प्रत्येक रिलीज compatibility notes के साथ है।

क्रमबद्धता पर जावा 6 कल्पना से:


लक्ष्य हैं करने के लिए:

    : एक वर्ग द्वारा अलग आभासी मशीनों में सक्रिय विभिन्न संस्करणों के बीच

    • समर्थन द्विदिश संचार
    • एक तंत्र को परिभाषित करना जो जावाटीएम कक्षाओं को उसी वर्ग के पुराने संस्करणों द्वारा लिखित धाराओं को पढ़ने की अनुमति देता है।
    • एक तंत्र को परिभाषित करना जो जावाटीएम कक्षाओं को उसी वर्ग के पुराने संस्करणों द्वारा पढ़ने के लिए इच्छित धाराओं को लिखने की अनुमति देता है।
  • दृढ़ता और आरएमआई के लिए डिफ़ॉल्ट क्रमबद्धता प्रदान करें।
  • अच्छी तरह से प्रदर्शन करें और सरल मामलों में कॉम्पैक्ट स्ट्रीम का उत्पादन करें, ताकि आरएमआई क्रमबद्धता का उपयोग कर सके।
  • स्ट्रीम लिखने के लिए उपयोग की जाने वाली सटीक कक्षा से मेल खाने वाली कक्षाओं को पहचानने और लोड करने में सक्षम हो।
  • ओवरवर्ड्स वाले वर्गों के लिए ओवरहेड कम रखें।
  • एक स्ट्रीम प्रारूप का उपयोग करें जो स्ट्रीम में सहेजे गए ऑब्जेक्ट्स के लिए विशिष्ट विधियों के बिना स्ट्रीम के ट्रैवर्सल को अनुमति देता है।

3

1,5 में क्रमबद्धता तंत्र और 1.6 संगत है। इस प्रकार, 1.5 और 1.6 संदर्भ में संकलित/चलने वाला कोड उसी क्रमबद्ध वस्तुओं का आदान-प्रदान कर सकता है। चाहे दो वीएम उदाहरणों के वर्ग के समान/संगत संस्करण (जैसा कि serialVersionUID फ़ील्ड द्वारा इंगित किया जा सकता है) एक अलग सवाल है जो जेडीके संस्करण से संबंधित नहीं है।

यदि आपके पास एक serializable Foo.java है और इसे 1.5 और 1.6 जेडीके/वीएम में उपयोग करें, तो एक वी द्वारा बनाई गई फू के क्रमबद्ध उदाहरण; दूसरे द्वारा deserialized किया जा सकता है।

0

ध्यान दें कि जावा बीन्स विनिर्देश एक संस्करण-स्वतंत्र धारावाहिक विधि का विवरण देता है जो मजबूत पिछड़ा-संगतता की अनुमति देता है। यह पठनीय "धारावाहिक" रूपों में भी परिणाम देता है। वास्तव में एक serialized वस्तु तंत्र का उपयोग कर आसानी से बनाया जा सकता है।

XMLEncoder और XMLDecoder कक्षाओं में दस्तावेज़ देखें।

मैं तार पर किसी ऑब्जेक्ट को पास करने के लिए इसका उपयोग नहीं करता (हालांकि यदि उच्च प्रदर्शन की आवश्यकता है, तो मैं क्रमबद्धता का उपयोग नहीं करता) लेकिन यह लगातार ऑब्जेक्ट स्टोरेज के लिए अमूल्य है।

0

जावा 1.5 और 1.6 मिश्रण करना सुरक्षित नहीं है। उदाहरण के लिए मेरे पास एक जावा 1.5 ऑब्जेक्ट्स फ़ाइल में क्रमबद्ध है और जावा 1.6 में खोलने का प्रयास किया है, लेकिन यह नीचे की त्रुटि

java.io.InvalidClassException: javax.swing.JComponent; स्थानीय वर्ग असंगत: धारा classdesc serialVersionUID = 7917968344860800289, स्थानीय वर्ग serialVersionUID = -1030230214076481435 java.io.ObjectStreamClass.initNonProxy (अज्ञात स्रोत) पर java.io.ObjectInputStream.readNonProxyDesc (अज्ञात स्रोत) पर java.io.ObjectInputStream पर। java.io.ObjectInputStream.readClassDesc (अज्ञात स्रोत) पर readClassDesc (अज्ञात स्रोत) java.io.ObjectInputStream.readNonProxyDesc (अज्ञात स्रोत) पर java.io.ObjectInputStream.readNonProxyDesc (अज्ञात स्रोत) java.io. पर पर Java.io.ObjectInputStream.readObject0 (अज्ञात स्रोत)पर ObjectInputStream.readClassDesc (अज्ञात स्रोत) java.io.ObjectInputStream.readOrdinaryObject (अज्ञात स्रोत) पर। java.io.ObjectInputStream.readArray (अज्ञात स्रोत) java.io.ObjectInputStream.readObject0 (अज्ञात स्रोत) पर java.io.ObjectInputStream.defaultReadFields (अज्ञात स्रोत) पर java.io.ObjectInputStream.readSerialData पर पर 63,210 (अज्ञात स्रोत) java.io.ObjectInputStream.readOrdinaryObject (अज्ञात स्रोत) पर java.io.ObjectInputStream.readObject0 (अज्ञात स्रोत) पर java.io.ObjectInputStream.defaultReadFields (अज्ञात स्रोत) पर java.io.ObjectInputStream.readSerialData पर (अज्ञात स्रोत) java.io.ObjectInputStream.readOrdinaryObject (अज्ञात स्रोत) java.io.ObjectInputStream.readObject0 (अज्ञात स्रोत) java.io.ObjectInputStream पर।java.io.ObjectInputStream.defaultReadFields (अज्ञात स्रोत) पर readArray (अज्ञात स्रोत) java.io.ObjectInputStream.readObject0 (अज्ञात स्रोत) पर java.io.ObjectInputStream.readSerialData (अज्ञात स्रोत) java.io. पर पर java.io.ObjectInputStream.readObject पर ObjectInputStream.readOrdinaryObject (अज्ञात स्रोत) java.io.ObjectInputStream.readObject0 (अज्ञात स्रोत) पर (अज्ञात स्रोत)

+0

यह विशिष्ट वर्ग के लिए सुरक्षित नहीं है, * क्योंकि यह स्पष्ट रूप से अपने स्वयं के जावाडोक में बताता है। आप यहां ब्रह्मांड के कानून पर ठोकर नहीं गए हैं। – EJP

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