2013-02-22 4 views
3

мне нужно десериализации объекта, но когда я читаю объект с помощью readObject я получаю такое исключение:Странное исключение во время десериализации

Exception raised: java.lang.Enum; Incompatible class (SUID): 
java.lang.Enum: static final long serialVersionUID =0L; 
but expected java.lang.Enum: static final long serialVersionUID =0L; 

Вот код:

public static void restore3x(PersistentHistory h, DictManager dictManager) throws Exception{ 
     SharedPreferences prefs = tryToGuess(h.mContext); 
     if (prefs == null) return; 
     Log.e("shdd","Found history!"); 
     String history = prefs.getString("History", null); 
     ObjectInputStream objIn = null; 
     try { 
      //prepare 
      objIn = new ObjectInputStream(new ByteArrayInputStream(Base64.decode(history))) { 
       @Override 
       protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException { 
        ObjectStreamClass osc = super.readClassDescriptor(); 
        if (osc.getName().contains("slovoed")) { 
         try { 
          Field f; 
          f = osc.getClass().getDeclaredField("svUID"); 
          f.setAccessible(true); 
          Log.e("shdd","Setting serialVersionUID"); 
          f.setLong(osc, serialVersionUID); 
          Log.e("shdd","Set ok"); 
          f = osc.getClass().getDeclaredField("className"); 
          f.setAccessible(true); 
          Log.e("shdd","Setting class name"); 
          f.set(osc, WordItem.class.getName()); 
          Log.e("shdd","Set ok"); 
         } catch (Exception e) { 
         } 
        } 
        return osc; 
       } 
      }; 
      //add to DB 
      Log.e("shdd","Getting items"); 
      Collection<WordItem3x> items = (Collection<WordItem3x>) objIn.readObject(); 
      Log.e("shdd","Got ok"); 
      if (items.isEmpty()) return; 
      Log.e("shdd","List's not empty"); 
      long timeSeconds = System.currentTimeMillis()/1000; 
      for (WordItem3x w : items) { 
       if (w.getWord() == null || w.getWord().length() == 0 || w.getIndexList() == 0) continue; 
       Log.e("shdd","Adding word"); 
       h.add(w.getWord(), w.getIndexList(), timeSeconds--); 
      } 
     } catch (Exception e) { 
      Log.e("shdd","Exception raised: " + e.getMessage()); 
      throw e; 
     } finally { 
      try { if (objIn != null) objIn.close(); } catch (Exception e) {} 
      //prefs.edit().remove("History").commit(); 
     } 
    } 

Я понятия не имею, что это неправильно , Может, кто-то видел такие исключения?

Вот WordItem3x readObject метод:

private void readObject(java.io.ObjectInputStream in) throws IOException, 
       ClassNotFoundException { 
      Log.e("shdd", "Reading object"); 
      in.defaultReadObject(); 

      int val1 = in.readInt(); 
      int val2 = in.readInt(); 
      if (val1 != -1 && val2 != -1) { 
       direction = new Direction(val1, val2); 
      } else 
       direction = null; 

      val1 = in.readInt(); 
      if (val1 != -1) 
       typeList = eWordListType.values()[val1]; 
      else 
       typeList = null; 
     } 

Но, как я могу видеть это никогда не называли.

+0

Что неправильно, несомненно, все, что вещи, где вы возиться с дескриптором класса , Для чего все это должно быть? – EJP

+0

Это не мой код, но я обнаружил, что это тоже странно. Но вопроса здесь нет. WordItem3x перескакивает с версии на версию приложения, поэтому похоже, что это какая-то «магия», чтобы заставить ее работать. – s0nicYouth

ответ

0

(примечание: нет кода сериализации показан, и реализация WordItem3x в основном опущена)

Основываясь на коде, догадка я могу сделать то, что хак в readClassDescriptor, где вы используете отражения для изменения serialVersionUID в конечном итоге приводит к модификации serialVersionUID. Из спецификации java вся запись перечисления serialVersionUID должна быть 0L. Я готов поспорить, что в какой-то момент вы изменили перечисление, чтобы не было 0L. Вот блок кода в AOSP, что бросил:

// Check SUIDs, note all SUID for Enum is 0L 
if (0L != classDesc.getSerialVersionUID() || 0L != superClass.getSerialVersionUID()) { 
     throw new InvalidClassException(superClass.getName(), 
       "Incompatible class (SUID): " + superClass + " but expected " + superClass); 
} 

Попытайтесь напечатать имя объекта, прежде чем изменить serialVersionUID

ObjectStreamClass osc = super.readClassDescriptor(); 
osc.getName(); // is this an enum???? 
Смежные вопросы