j2objc - исключение при десериализации enum
У меня проблемы с десериализацией объектов, содержащих перечисление. Объект сериализуется без жалоб, но я получаю исключение InvalidObjectException при десериализации объекта. В сообщении об исключении говорится, что "нет константы перечисления com.mypackagname".
Я выделил и воспроизвел проблему, создав некоторый тестовый код на основе метода testSerialization() в SerializationTest.java.
public class SerializationTest {
private static final String TEST_FILE_NAME = "serialization-test.bin";
public enum Gender { MALE, FEMALE }
public void testEnumSerialization() throws IOException, ClassNotFoundException {
Gender gender = Gender.MALE;
// Save the enum to a file.
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(TEST_FILE_NAME));
out.writeObject(gender);
out.close();
// Read back the enum.
ObjectInputStream in = new ObjectInputStream(new FileInputStream(TEST_FILE_NAME));
Gender gender2 = (Gender) in.readObject();
in.close();
}
}
Я обнаружил, что если я добавлю строковое значение к инициализации enum в сгенерированном коде Objective C, десериализация будет работать нормально. Результирующий метод инициализации в Obj C выглядит следующим образом:
+ (void)initialize {
if (self == [SerializationTest_Gender class]) {
JreEnum(SerializationTest_Gender, MALE) = new_SerializationTest_Gender_initWithNSString_withInt_(@"MALE", 0);
JreEnum(SerializationTest_Gender, FEMALE) = new_SerializationTest_Gender_initWithNSString_withInt_(@"FEMALE", 1);
J2OBJC_SET_INITIALIZED(SerializationTest_Gender)
}
}
Обратите внимание, что я добавил @"MALE" и @"FEMALE", значение по умолчанию из вывода j2objc - @"".
У меня два вопроса. (1) Это правильный способ включить сериализацию / десериализацию перечислений в оба конца? (2) Если так, есть ли способ, чтобы j2objc автоматически заполнял строковые константы в перечислении, а не кодировал их вручную?
Спасибо за любую помощь, которую вы можете предоставить.
1 ответ
Мы, вероятно, сломали это недавним изменением, исключив избыточные строки имен констант enum. У нас было имя, определенное как в инициализаторе класса enum, так и в его метаданных, плюс у нас был важный запрос, чтобы прекратить делать константы enum легко обнаруживаемыми в двоичных файлах приложений (очевидно, технические писатели, как известно, дампили двоичные файлы раннего доступа и запускали на них строки для получить совки на любые новые функции). Теперь имя константы есть только в метаданных (без избыточности), и если приложение создается с --strip-отражением, у enum нет метаданных, и имя становится классом enum плюс порядковый номер константы. Однако поддержка сериализации была упущена из виду, так как приложения Google вместо этого используют протоколовые буферы (быстрее и менее чувствительны к версии).
Спасибо за отличный контрольный пример, который будет легче исправить. Пожалуйста, отправьте сообщение об ошибке, если вы хотите получать уведомления, когда это будет исправлено.