Сериализация Java - загрузка файлов на один компьютер, но не другой [дубликат]

Вместо того, чтобы использовать метод, в котором вы назначаете адрес электронной почты для пользователя, может быть лучшим вариантом для поиска адреса электронной почты в вашей базе данных.

Примером может быть:

  1. Подскажите имя пользователя для входа с именем пользователя и паролем
  2. Проверьте, что имя пользователя существует в вашей базе данных и получает соответствующий адрес электронной почты для этой учетной записи.
  3. Передайте этот адрес электронной почты логин легко
5
задан Joachim Sauer 24 August 2011 в 10:45
поделиться

4 ответа

Когда вы реализуете интерфейс java.io.Serializable для создания сериализуемого класса, компилятор ищет статическое конечное поле с именем «serialVersionUID» типа long. Если класс не указал это поле явно, то компилятор создаст одно такое поле и присвоит ему значение, которое выходит из зависимого от реализации вычисления serialVersionUID. Это вычисление зависит от различных аспектов класса, и оно следует за спецификациями сериализации объектов, данными Sun. Но значение не гарантируется во всех реализациях компилятора.

Это значение используется для проверки совместимости классов в отношении сериализации, и это выполняется при де-сериализации сохраненного объекта. Последовательность выполнения Serialization проверяет, что serialVersionUID класса отправителя (который использовался для сохранения состояния объекта в потоке) и класса получателя (класс, который используется для восстановления объекта, возможно, в какой-либо другой системе) оба они точно такие же. Если система приемника загрузила класс с некоторым другим идентификатором serialVersionUID, чем класс, используемый в процессе сериализации, мы получаем InvalidClassException.

ПРИМЕЧАНИЕ. Настоятельно рекомендуется явно объявить и инициализировать статический окончательный поле типа long и имя 'serialVersionUID' во всех ваших классах, которые вы хотите сделать Serializable, вместо того, чтобы полагаться на вычисление значения по умолчанию для этого поля по умолчанию. Это вычисление чрезвычайно чувствительно и может варьироваться от одной реализации компилятора к другой, и, следовательно, вы можете получить InvalidClassException даже для одного и того же класса только потому, что вы использовали различные реализации компилятора на отправителе и на концах приемника процесса сериализации.

В большинстве случаев вы использовали бы «частный» спецификатор доступа только для этого поля, поскольку объявление обычно применяется только к классу, объявляющему его, и нам действительно не нужно либо наследовать это поле в подклассах OR, либо доступ к нему извне. Итак, вряд ли есть какая-то причина, почему мы не должны держать ее «частной».

28
ответ дан amod 20 August 2018 в 10:52
поделиться
  • 1
    Привет Большое спасибо за ответ. Как вы говорите, сериализация uid специфична для компилятора. Но здесь моя версия компилятора такая же во всей системе, и это происходит периодически. – karthik 24 August 2011 в 11:11
  • 2
  • 3
    Я столкнулся с той же проблемой прямо сейчас, не соответствует ли несоответствие версии компилятора только для этого? У меня версия java 1.6.29 и 1.6.23 на двух компьютерах. – Akhilesh 8 November 2012 в 18:40
  • 4
    @Akhilesh Его действительно сложно сказать. Но несоответствие версии компилятора может быть возможным. Я бы рекомендовал вам предоставить код и спросить его здесь. – amod 27 November 2012 в 21:06
  • 5
    Спасибо за объяснение - есть ли какие-то ограничения на то, что должны быть значениями, т. Е. Можно ли их установить равными нулю? Кроме того, кто-нибудь знает, какова цель этого идентификатора? Следует ли проверить правильность декодирования класса? Если это так, то почему это должно быть настолько чувствительным, т. Е. Почему не просто хеш значения? Я предполагаю, где я собираюсь с этим, опасно ли мне переопределить это поле? Я рискую в обход теста подлинной несовместимости между компиляторами? – Alex 5 March 2013 в 00:51

Если кто-то снова столкнется с этой проблемой по отношению к EJB TimerTask - как я и сделал - вот подсказка, если вы используете WebSphere Application Server:

Есть 2 командных файла / сценарии оболочки в папке bin файла, которая может отображать и удалять задачи таймера EJB. В моем случае у меня были некоторые задачи таймера, которые сериализовали объекты с другим устаревшим serialVersionUID. Я не мог избавиться от них, поскольку сериализованные объекты действительно изменились. Поэтому я просто использовал те:

findEJBTimers.bat cancelEJBTimers.bat

Ваши задачи таймера исчезли, а также сообщения об ошибках. В моем случае это было именно то, что мне было нужно, но было сложно получить эту информацию.

2
ответ дан BJH 20 August 2018 в 10:52
поделиться

Хорошо, так как я попрошу привести пример и мою часть:

Вот список и метрики производительности для различных форм сериализации PoJos

Вам придется судить о компромиссах с производительностью и удобством. Но, поскольку я сказал «JSON» как средство сериализации, вот здесь тривиальный пример, который не зависит от компилятора. В принципе, если вы не изменили структуру своего pojo на принимающей стороне, это совершенно не имеет значения, когда / how / где вы ее скомпилируете (на самом деле, это даже не должно быть между двумя JVM). Как вы можете видеть из ссылки, JSON на самом деле является одним из самых медленных, а XML - просто свинья. Но оба они имеют решающее преимущество в поддержке повсеместно. XML даже позволяет применять таблицы стилей.

    <dependency>
        <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
        <version>2.3.1</version>
        <scope>test</scope>
    </dependency>

Код

  @Test
    public void testJSON() throws Exception {
        Foo expected = new Foo(1,"Christian",1000000.00d);
        Gson gson = new GsonBuilder().setPrettyPrinting().create();
        String testJson = gson.toJson(expected);

        System.out.println(testJson);

        Foo result = gson.fromJson(testJson, Foo.class);
        assertEquals(expected,result);

    }

    public static class Foo {

        private String name;
        private Integer age;
        private Double paycheck;

        public Foo(Integer age, String name, Double paycheck) {
            this.age = age;
            this.name = name;
            this.paycheck = paycheck;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            Foo foo = (Foo) o;

            if (age != null ? !age.equals(foo.age) : foo.age != null) return false;
            if (name != null ? !name.equals(foo.name) : foo.name != null) return false;
            if (paycheck != null ? !paycheck.equals(foo.paycheck) : foo.paycheck != null) return false;

            return true;
        }

        @Override
        public int hashCode() {
            int result = name != null ? name.hashCode() : 0;
            result = 31 * result + (age != null ? age.hashCode() : 0);
            result = 31 * result + (paycheck != null ? paycheck.hashCode() : 0);
            return result;
        }
    }

Выход

{
  "name": "Christian",
  "age": 1,
  "paycheck": 1000000.0
}
0
ответ дан Christian Bongiorno 20 August 2018 в 10:52
поделиться

Вы получаете это исключение, когда пытаетесь десериализовать объект, который был сериализован с несовместимой (обычно более ранней) версией того же класса.

Если вы явно не указали serialVersionUID в своем класса Serializable, то значение будет генерироваться на основе полей (не transient) вашего класса. Это делается для того, чтобы не восстанавливать частичные объекты (лучше провалиться, чем слепо продолжить с возможно сломанным объектом).

В системах веб-приложений для сеанса используется обычное использование сериализации : если вы поместите значение в сеанс, вероятно, он будет сериализован в конце концов (для поддержки кластеризации или просто для получения постоянных сеансов).

Итак, либо сохраняют все ваши классы совместимые между версиями или , гарантируют, что не восстановить их не нарушит ваше приложение (т. е. не храните важную информацию таким образом).

6
ответ дан Joachim Sauer 20 August 2018 в 10:52
поделиться
  • 1
    Привет Спасибо за ваш ответ. Это очень полезно. – karthik 24 August 2011 в 11:12
Другие вопросы по тегам:

Похожие вопросы: