سؤال

I use the following class to deserialize a string and map the incoming classes to new ones in a different package.

They contain the exact same attributes ( except the mapped equivalents ) and the same serial version uid.

public class CompatibilityImporter {


public void loadOldImport(final File f, final CompatibilityImportListener importListener, final String password) {
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                String oldExport = readFileAsString(f);
                ObjectInputStream ois = new ClassNameMappingObjectInputStream(new ByteArrayInputStream(Base64.decode(oldExport, Base64.DEFAULT)));
                ExportPackageCompat exportPackage = (ExportPackageCompat) ois.readObject();
                importListener.onImportDone();
            } catch (Exception e) {
                Log.e(e, "Compatibility Import failed! ");
                importListener.onImportError();
            }
        }
    }).start();
}

public class ClassNameMappingObjectInputStream extends ObjectInputStream {

    public Map<String, Class> classNameMapping = initclassNameMapping();

    public ClassNameMappingObjectInputStream(InputStream in) throws IOException {
        super(in);
        initclassNameMapping();
    }

    protected ClassNameMappingObjectInputStream() throws IOException, SecurityException {
        super();
        initclassNameMapping();
    }

    private Map<String, Class> initclassNameMapping() {
        Map<String, Class> res = new HashMap<String, Class>();
        res.put("com.example.myapp.app.settings.backup.ExportPackage", ExportPackageCompat.class);
        res.put("com.example.myapp.app.settings.backup.ExportPackage$SavedPhotoFile", SavedPhotoFileCompat.class);
        // all the other model mappings
        return Collections.unmodifiableMap(res);
    }

    @Override
    protected java.io.ObjectStreamClass readClassDescriptor()
            throws IOException, ClassNotFoundException {
        ObjectStreamClass desc = super.readClassDescriptor();
        Log.d("ObjectInputStream", "Reading descriptor -> " + desc);
        if (classNameMapping.containsKey(desc.getName())) {
            return ObjectStreamClass.lookup(classNameMapping.get(desc.getName()));
        }
        return desc;
    }
}
}

For some reason at some point the desiarialisation process seems to try to match 2 attributes that cant go together.

(A String attribute phone is tryed to be written with an arraylist. )

Here is the Logcat:

22953-23138/com.example.myapp D/ObjectInputStream﹕ Reading descriptor -> 
com.example.myapp.app.settings.backup.ExportPackage: static final long serialVersionUID =3985293256L;
22953-23138/com.example.myapp D/ObjectInputStream﹕ Reading descriptor -> java.util.ArrayList: static final long serialVersionUID =8683452581122892189L;
22953-23138/com.example.myapp D/ObjectInputStream﹕ Reading descriptor -> com.example.myapp.model.Crate: static final long serialVersionUID =-2892184805959193218L;
22953-23138/com.example.myapp D/ObjectInputStream﹕ Reading descriptor -> java.util.Date: static final long serialVersionUID =7523967970034938905L;
22953-23138/com.example.myapp D/ObjectInputStream﹕ Reading descriptor -> com.example.myapp.model.Shipment: static final long serialVersionUID =-2477342699440006438L;
22953-23138/com.example.myapp D/ObjectInputStream﹕ Reading descriptor -> com.example.myapp.model.Photo: static final long serialVersionUID =-3384005512499715344L;
22953-23138/com.example.myapp D/ObjectInputStream﹕ Reading descriptor -> com.example.myapp.app.settings.backup.ExportPackage$Extras: static final long serialVersionUID =4664556672506779299L;
22953-23138/com.example.myapp D/ObjectInputStream﹕ Reading descriptor -> [B: static final long serialVersionUID =-5984413125824719648L;
22953-23138/com.example.myapp D/ObjectInputStream﹕ Reading descriptor -> com.example.myapp.model.Shipment$ShipmentType: static final long serialVersionUID =0L;
22953-23138/com.example.myapp D/ObjectInputStream﹕ Reading descriptor -> java.lang.Enum: static final long serialVersionUID =0L;
22953-23138/com.example.myapp D/ObjectInputStream﹕ Reading descriptor -> com.example.myapp.model.Donut: static final long serialVersionUID =-5666180507659888627L;
22953-23138/com.example.myapp D/ObjectInputStream﹕ Reading descriptor -> com.example.myapp.model.DonutPackage: static final long serialVersionUID =5365476511704148082L;
22953-23138/com.example.myapp E/Apotheke﹕ Compatibility Import failed!
    java.lang.ClassCastException: com.example.myapp.app.settings.backup.compatibility.CrateCompat.phone - class java.lang.String not compatible with class java.util.ArrayList
            at java.io.ObjectInputStream.readFieldValues(ObjectInputStream.java:1151)
            at java.io.ObjectInputStream.defaultReadObject(ObjectInputStream.java:455)
            at java.io.ObjectInputStream.readObjectForClass(ObjectInputStream.java:1372)
            at java.io.ObjectInputStream.readHierarchy(ObjectInputStream.java:1269)
            at java.io.ObjectInputStream.readNewObject(ObjectInputStream.java:1858)
            at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:787)
            at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2006)
            at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1963)
            at java.util.ArrayList.readObject(ArrayList.java:661)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:525)
            at java.io.ObjectInputStream.readObjectForClass(ObjectInputStream.java:1357)
            at java.io.ObjectInputStream.readHierarchy(ObjectInputStream.java:1269)
            at java.io.ObjectInputStream.readNewObject(ObjectInputStream.java:1858)
            at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:787)
            at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2006)
            at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1963)
            at java.io.ObjectInputStream.readFieldValues(ObjectInputStream.java:1140)
            at java.io.ObjectInputStream.defaultReadObject(ObjectInputStream.java:455)
            at java.io.ObjectInputStream.readObjectForClass(ObjectInputStream.java:1372)
            at java.io.ObjectInputStream.readHierarchy(ObjectInputStream.java:1269)
            at java.io.ObjectInputStream.readNewObject(ObjectInputStream.java:1858)
            at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:787)
            at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2006)
            at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1963)
            at com.example.myapp.app.settings.backup.compatibility.CompatibilityImporter$1.run(CompatibilityImporter.java:48)
            at java.lang.Thread.run(Thread.java:841)

Has anyone any idea what might go wrong?

I'm hoping for someone who shared and solved my problem or knows how the mixup between the attributes might happen.

هل كانت مفيدة؟

المحلول

In one of the Objects i mapped to an attribute was missing and caused the mixup.

My mistake!

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top