Java Advanced Сериализация и RMI Содержание Сериализация Концепции RMI Применение RMI Дополнительные возможности RMI Заключение Georgiy Korneev Java Advanced / Сериализация и RMI 2 Часть 1 Сериализация Сериализация и десериализация Сериализация – запись объекта в байтовый поток Десериализация – чтение объекта из байтового потока Пакет java.io При сериализации и десериализация используется все данные, которые достижимы из объекта Georgiy Korneev Java Advanced / Сериализация и RMI 4 Сериализация объектов Запись объектов Интерфейс ObjectOutput extends DataOutput Класс ObjectOutputStream Метод writeObject(object) Исключение NotSerializableException Georgiy Korneev Java Advanced / Сериализация и RMI 5 Десериализация объектов Чтение объектов Интерфейс ObjectInput extends DataInput Класс ObjectInputStream Метод readObject() Исключение Georgiy Korneev ClassNotFoundException InvalidClassException Java Advanced / Сериализация и RMI 6 Что можно сериализовать Автоматически сериализуемые классы Маркерный интерфейс Serializable Классы, сериализуемые вручную Интерфейс Externalizable extends Serializable Georgiy Korneev Java Advanced / Сериализация и RMI 7 Автоматическая сериализация Процесс записи Записывается предок Записываются значения всех полей, не имеющих модификатора transient Процесс чтения Выделяется память под объект Считывается предок Считываются значения всех полей , не имеющих модификатора transient Georgiy Korneev Java Advanced / Сериализация и RMI 8 Пример 1. Автоматическая сериализация public class Data implements Serializable { private List<Integer> data; ... } public class Data2 extends Data { private transient String toStringCache; ... } Georgiy Korneev Java Advanced / Сериализация и RMI 9 Сериализация в ручную Интерфейс Externalizable Методы readExternal(ObjectInput in) – должен прочесть состояние из потока writeExternal(ObjectOutput out) – должен записать состояние в поток Процесс чтения Создание конструктором по умолчанию Вызов метода readExternal Georgiy Korneev Java Advanced / Сериализация и RMI 10 Настраиваемая сериализация Применяется для обеспечения совместимости Методы readObject(ObjectInputStream in) – должен прочесть состояние из потока writeObject(ObjectOutputStream out) – должен записать состояние в поток Процесс чтения Выделение памяти Чтение родителя Вызов метода readObject Georgiy Korneev Java Advanced / Сериализация и RMI 11 Сериализация с несериализуемым предком Несериализуемый предок должен иметь конструктор по умолчанию ObjectOuputStream.defaultWriteObject() – записывает поля текущего класса ObjectInoutStream.defaultReadObject() – считывает поля текущего класса Georgiy Korneev Java Advanced / Сериализация и RMI 12 Версии сериализованных классов Применяется для обеспечения совместимости когда версии сериализованного объекта меняются Поле private final static long serialVersionUID Инструмент serialver <имя класса> Georgiy Korneev Java Advanced / Сериализация и RMI 13 Русная сериализация полей Константа ObjectStreamField[] serialPersistentFields – сериализуемые поля ObjectOutputStream.PutField putFields() – поля для записи writeFields() – записывает поля ObjectInputStream.GetField getFields() – читает поля из потока Georgiy Korneev Java Advanced / Сериализация и RMI 14 Запись и чтение дескрипторов Применяется когда сам объект не должен сериализовываться Методы Object writeReplace() – какой объект записать вместо этого Object readResolve() – какой объект реально был записан Реализуются у разных классов Georgiy Korneev Java Advanced / Сериализация и RMI 15 Часть 2 Концепции RMI Remote Method Invocation Механизм, позволяющий объектом из одной Java-машины вызывать методы другой Java-машины RMI работает по сети Пакет java.rmi Georgiy Korneev Java Advanced / Сериализация и RMI 17 Схема взаимодействия Client Server IInterface IInterface Stub Skeleton Remote Reference Layer Remote Reference Layer Transport Layer Georgiy Korneev Java Advanced / Сериализация и RMI 18 Удаленные интерфейсы Удаленный интерфейс – интерфейс, унаследованный от Remote Все методы удаленных интерфейсов должны бросать RemoteException Georgiy Korneev Java Advanced / Сериализация и RMI 19 Передача данных Объекты, реализующие интерфейс Remote передаются по удаленным ссылкам Остальные объекты передаются по значению путем сериализации Georgiy Korneev Java Advanced / Сериализация и RMI 20 Stub и Skeleton Stub и Skeleton генерируются по удаленному классу Stub служит для передачи данных по сети. Реализует все удаленные интерфейсы класса и только их Skeleton служит для приема данных по сети и вызов методов реальтного объекта Georgiy Korneev Java Advanced / Сериализация и RMI 21 Distributed Garbage Collecting Удаление объектов, на которых больше не ссылок в распределенной среде Механизм лизинга Интерфейс Unreferenced Метод unreferenced() Georgiy Korneev Java Advanced / Сериализация и RMI 22 Поиск удаленных объектов (1) Ссылки на удаленный объекты публикуются в RMI registry Удаленные объекты ищутся по URL вида rmi://<host>:<port>/<object>, где host:port – местоположение RMI registry object – зарегистрированное имя объекта Georgiy Korneev Java Advanced / Сериализация и RMI 23 Поиск удаленных объектов (2) Класс Naming – интерфейс к RMI registry Методы класса bind(name, object) – зарегистрировать объект lookup(name) – получить объект по имени unbind(name) – отменить регистрацию объекта rebind(name, object) – зарегистрировать новый объект Georgiy Korneev Java Advanced / Сериализация и RMI 24 Экспорт объектов Прежде чем быть переданными на другую машину объект должен быть экспортирован Метод UnicastRemoteObject.exportObject(object) Наследники UnicastRemoteObject экспортируются автоматически Georgiy Korneev Java Advanced / Сериализация и RMI 25 Часть 3 Применение RMI Пример: банк Банк поддерживает счета, идентифицируемые строками По счету можно Узнать идентификатор Узнать сумму денег на счете Изменить сумму денег на счете Georgiy Korneev Java Advanced / Сериализация и RMI 27 Удаленный интерфейс банка public interface Bank extends Remote { // Создает счет public Account createAccount(String id) throws RemoteException; // Возвращает счет public Account getAccount(String id) throws RemoteException; } Georgiy Korneev Java Advanced / Сериализация и RMI 28 Удаленный интерфейс счета public interface Account extends Remote { // Узнать идентификатор public String getId() throws RemoteException; // Узнать количество денег public int getAmount() throws RemoteException; // Установить количество денег public void setAmount(int amount) throws RemoteException; } Georgiy Korneev Java Advanced / Сериализация и RMI 29 Реализация счета Класс AccountImpl implements Account public String getId() { return id; } public int getAmount() { return amount; } public void setAmount(int amount) { this.amount = amount; } Georgiy Korneev Java Advanced / Сериализация и RMI 30 Реализация банка Класс BankImpl implements Bank public Account createAccount(String id) { Account account = new AccountImpl(id); accounts.put(id, account); return account; } public Account getAccount(String id) { return accounts.get(id); } Georgiy Korneev Java Advanced / Сериализация и RMI 31 Сервер Регистрация банка в RMI registry Bank bank = new BankImpl(); try { UnicastRemoteObject.exportObject(bank); Naming.rebind("rmi://localhost/bank", bank); } catch (RemoteException e) { System.out.println("Cannot export object: " + e.getMessage()); e.printStackTrace(); } catch (MalformedURLException e) { System.out.println("Malformed URL"); } Georgiy Korneev Java Advanced / Сериализация и RMI 32 Клиент (1) Получение ссылки на банк Bank bank; try { bank = (Bank) Naming.lookup("rmi://localhost/bank"); } catch (NotBoundException e) { System.out.println("Bank is not bound"); return; } catch (MalformedURLException e) { System.out.println("Bank URL is invalid"); return; } Georgiy Korneev Java Advanced / Сериализация и RMI 33 Клиент (2) Создание счета Account account = bank.getAccount("geo"); if (account == null) { System.out.println("Creating account"); account = bank.createAccount("geo"); } else { System.out.println("Account already exists"); } Georgiy Korneev Java Advanced / Сериализация и RMI 34 Клиент (3) Операции со счетом System.out.println("Money: " + account.getAmount()); System.out.println("Adding money"); account.setAmount(account.getAmount() + 100); System.out.println("Money: " + account.getAmount()); Georgiy Korneev Java Advanced / Сериализация и RMI 35 Запуск Создание Stub для классов rmic AccountImpl BankImpl Запуск RMI Registry rmiregistry Запуск сервера Запуск клиента Georgiy Korneev Java Advanced / Сериализация и RMI 36 Часть 4 Дополнительные возможности RMI Фабрики сокетов Класс RMIClientSocketFactory – фабрика клиентских сокетов Класс RMIServerSocketFactory – фабрика серверных сокетов Метод Socket createSocket(String host, int port) Метод ServerSocket createServerSocket(int port) Класс RMISocketFactory – фабрика сокетов, применяемая по умолчанию UnicastRemoteObject.exportObject(object, port, csf, ssf) – экспортирует объект Georgiy Korneev Java Advanced / Сериализация и RMI 38 Создание Registry на лету Интерфейс Registry – экземпляр RMI registry Класс LocateRegistry – позволяет находить и создавать экземпляры RMI registry getRegistry(host?, port?) – найти RMI registry createRegistry(port) – создать экземпляр RMI registry Georgiy Korneev Java Advanced / Сериализация и RMI 39 Дополнительные возможности RMI Использование callback процедур Activation – технология, позволяющая создавать удаленные объекты Загрузка .class файлов с HTTP сервера Georgiy Korneev Java Advanced / Сериализация и RMI 40 Часть 5 Заключение Ссылки по сериализации Java Object Serialization Specification // http://java.sun.com/j2se/1.5.0/docs/guide/seri alization/spec/serialTOC.html Object Serialization (Guide) // http://java.sun.com/j2se/1.5.0/docs/guide/seri alization/index.html Serialization (Tutorial) // http://java.sun.com/developer/onlineTraining/ Programming/BasicJava2/serial.html Serialization FAQ // http://java.sun.com/products/jdk/serialization/f aq/ Georgiy Korneev Java Advanced / Сериализация и RMI 42 Ссылки по RMI RMI (Guide & tutotials) http://java.sun.com/j2se/1.5.0/docs/guide/rmi/ Java RMI Specification // http://java.sun.com/j2se/1.5.0/docs/guide/rmi/ spec/rmiTOC.html RMI Tutorial // http://java.sun.com/developer/onlineTraining/r mi/RMI.html Georgiy Korneev Java Advanced / Сериализация и RMI 43 Вопросы Georgiy Korneev Java Advanced / Сериализация и RMI 44