2012-08-09 10 views
5

का उपयोग कर रहा (एक डिफ़ॉल्ट कोई आर्ग निर्माता होने कहते हैं, SomeClass) एक byte[] सरणी, Kryo 2.19 और डिफ़ॉल्ट serializer (FieldSerializer) का उपयोग को क्रमानुसार और एक कस्टम वर्ग की वस्तुओं deserialize करने के लिए कोशिश कर रहा हूँ।जेनेरिक जावा क्रमांकन/deserialization Kryo

सीरियलाइजेशन ठीक काम करता प्रतीत होता है, लेकिन मुझे SomeClass के वास्तविक कार्यान्वयन के आधार पर deserialization में विभिन्न अपवाद मिलते हैं।

SomeClass object = getObject(); // Create and populate a new object of SomeClass 

Kryo kryo = new Kryo(); 
FieldSerializer<?> serializer = new FieldSerializer<SomeClass>(kryo, SomeClass.class); 
kryo.register(SomeClass.class, serializer); 

ByteArrayOutputStream stream = new ByteArrayOutputStream(); 
Output output = new Output(stream); 

kryo.writeObject(output, object); 

output.close(); // Also calls output.flush() 

byte[] buffer = stream.toByteArray(); // Serialization done, get bytes 

// Deserialize the serialized object. 
object = kryo.readObject(new Input(new ByteArrayInputStream(buffer)), SomeClass.class); 

अपवाद मैं हो रही है की एक उदाहरण है::

Exception in thread "main" java.lang.IncompatibleClassChangeError: Found interface org.objectweb.asm.MethodVisitor, but class was expected 
    at com.esotericsoftware.reflectasm.ConstructorAccess.insertConstructor(ConstructorAccess.java:89) 
    at com.esotericsoftware.reflectasm.ConstructorAccess.get(ConstructorAccess.java:70) 
    at com.esotericsoftware.kryo.Kryo.newInstantiator(Kryo.java:1009) 
    at com.esotericsoftware.kryo.Kryo.newInstance(Kryo.java:1059) 
    at com.esotericsoftware.kryo.serializers.FieldSerializer.create(FieldSerializer.java:228) 
    at com.esotericsoftware.kryo.serializers.FieldSerializer.read(FieldSerializer.java:217) 
    at com.esotericsoftware.kryo.Kryo.readObject(Kryo.java:629) 

ऐसा लगता है कि पैरामिट्रीकृत प्रकार deserialize करने के लिए समस्याग्रस्त हैं

कोड कुछ इस तरह लग रहा है। इस धारणा का परीक्षण करने के लिए, यहाँ SomeClass और getObject() की एक पैरामिट्रीकृत दिया गया है:

class SomeClass<T extends Serializable> 
{ 
    private final T[] elements; 

    private final int first; 
    private final int second; 

    private SomeClass() 
    { 
     this.elements = null; 
     this.first = 0; 
     this.second = 0; 
    } 

    private SomeClass(T[] elements, int first, int second) 
    { 
     this.elements = elements; 
     this.first = first; 
     this.second = second; 
    } 
} 

SomeClass<?> getObject() 
{ 
    String[] elements = new String[] {"This is a test", "one"}; 

    return new SomeClass<String>(elements, 1, 2); 
} 

यह ठीक serializes, लेकिन अक्रमांकन निम्नलिखित अपवाद (निरीक्षण कैसे स्ट्रिंग के पहले अक्षर को अपवाद कारण की रिपोर्ट में नहीं है) फेंकता है:

Exception in thread "main" com.esotericsoftware.kryo.KryoException: Unable to find class: his is a test 
Serialization trace: 
elements (net.cetas.parserserver.data.report.SourceDataReporter$SomeClass) 
    at com.esotericsoftware.kryo.util.DefaultClassResolver.readName(DefaultClassResolver.java:132) 
    at com.esotericsoftware.kryo.util.DefaultClassResolver.readClass(DefaultClassResolver.java:109) 
    at com.esotericsoftware.kryo.Kryo.readClass(Kryo.java:613) 
    at com.esotericsoftware.kryo.Kryo.readClassAndObject(Kryo.java:724) 
    at com.esotericsoftware.kryo.serializers.DefaultArraySerializers$ObjectArraySerializer.read(DefaultArraySerializers.java:338) 
    at com.esotericsoftware.kryo.serializers.DefaultArraySerializers$ObjectArraySerializer.read(DefaultArraySerializers.java:293) 
    at com.esotericsoftware.kryo.Kryo.readObjectOrNull(Kryo.java:702) 
    at com.esotericsoftware.kryo.serializers.FieldSerializer$ObjectField.read(FieldSerializer.java:521) 
    at com.esotericsoftware.kryo.serializers.FieldSerializer.read(FieldSerializer.java:221) 
    at com.esotericsoftware.kryo.Kryo.readObject(Kryo.java:629) 

ऊपर वर्ग parameterization के बिना लागू किया जाता है तो (यानी, elements सरणी एक String[] के रूप में घोषित) के रूप में उम्मीद, अक्रमांकन काम करता है।

कोई भी विचार?

+1

क्या आप यहां 'SomeClass' कोड पोस्ट कर सकते हैं? मुझे याद है कि क्रियो में आपको उन सभी वर्गों को पंजीकृत करना चाहिए जिन्हें धारावाहिक किया जा सकता है (उदाहरण के लिए, यदि आप कक्षा एरेलिस्ट का उपयोग करती है, तो इसे भी पंजीकृत किया जाना चाहिए)। एक और सवाल, क्या यह जानबूझकर सरल वर्ग के लिए काम करता है? –

+0

ऐसा लगता है कि जेनेरिक के साथ करना है। कक्षा को पैरामीटर किया गया है, यानी कुछ क्लास एक निजी आवृत्ति चर टी [] के साथ। यदि वह चर हटा दिया गया है, तो यह काम करता है। अन्यथा, विविधता के आधार पर कई प्रकार के अपवाद फेंक दिए जाते हैं। – PNS

+1

ऐसा लगता है कि आपको 'SomeClass ' – Dahaka

उत्तर

11
Exception in thread "main" java.lang.IncompatibleClassChangeError: Found interface org.objectweb.asm.MethodVisitor, but class was expected 

कृपया जांचें कि आप अपने प्रोजेक्ट में एएसएम का किस संस्करण का उपयोग करते हैं। MethodVisitor 3.3 तक एएसएम में एक इंटरफ़ेस है। 4.0 संस्करण के बाद यह एक वर्ग है।

लिंक:

0

आप क्रमबद्धता और डी-क्रमबद्धता के लिए एक ही कक्षा संस्करण का उपयोग सुनिश्चित करें। यदि आप एक वर्ग संस्करण का उपयोग करके क्रमबद्ध करते हैं और एक अलग वर्ग संस्करण का उपयोग करते हैं (जैसे किसी फ़ील्ड को जोड़ने या हटाने के बाद) तो यह त्रुटि होने की संभावना है। इसका मतलब यह नहीं है कि यह केवल उस स्थिति के दौरान हो सकता है।

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