Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Сериализация и передача объектов 
:(
    Опции темы
Alar
Дата 20.7.2005, 11:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 20.7.2005
Где: г. Пермь

Репутация: нет
Всего: нет



Следующий тестовый пример. Два приложения, одно создает класс и сериализует его в файл, другое читает. Хотелось бы, чтобы второе ничего не знало о реализации интерфейса IFoo и работало только через интерфейс.

Вот тексты:
Приложение №1. В classpath содержит второе приложение для доступа к IFoo
Код

public class Serializator {
  private static class Foo implements IFoo {
    public void doSomething() {
      System.out.println("Hello, world!!!");
    }
  }
  public static void main(String[] args) {
    IFoo foo = new Foo();
    ObjectOutputStream stream;
    try {
      FileOutputStream fileOutputStream;
      fileOutputStream = new FileOutputStream("test.ser");
      stream = new ObjectOutputStream(fileOutputStream);
      stream.writeObject(foo);
      stream.close();
      System.out.println("Object written.");
    } catch (Exception e) {
      e.printStackTrace();
    } 
  }
}


Приложение №2:
IFoo.java:
Код

public interface IFoo extends Serializable {
  void doSomething();
}


Loader.java:
Код

public class Loader {
  public static void main(String[] args) {
    try {
      FileInputStream fileInputStream = new FileInputStream("test.ser");
      ObjectInputStream stream = new ObjectInputStream(fileInputStream);
      IFoo foo = (IFoo) stream.readObject();
      foo.doSomething();
    } catch (Exception e) {
      e.printStackTrace();
    } 
  }
}


При загрузке получаю java.lang.ClassNotFoundException: bla.bla.bla.Serializator$Foo. В-общем-то понятно почему: Loader не может загрузить класс Foo. Но хотелось бы как-нибудь реализовать подобную схему. То есть загрузить объект и работать с ним только через интерфейс, а про класс ничего не знать.
Куда рыть? :-)

Это сообщение отредактировал(а) Alar - 20.7.2005, 11:13
PM MAIL ICQ   Вверх
anonymouse
Дата 20.7.2005, 11:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 197
Регистрация: 18.8.2004

Репутация: нет
Всего: 1



Код

[b]public [/b]static class Foo implements IFoo {

--------------------
Много чего интересного...
PM MAIL   Вверх
Alar
Дата 20.7.2005, 11:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 20.7.2005
Где: г. Пермь

Репутация: нет
Всего: нет



anonymouse, нет не в этом дело. Так я уже пробовал (сначала класс Foo был вообще в отдельном файле). Впрочем как "для галочки" попробовал безымянным классом, через абстрактный класс (вместо интерфейса).
PM MAIL ICQ   Вверх
tux
Дата 20.7.2005, 11:34 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Летатель
***


Профиль
Группа: Участник Клуба
Сообщений: 1853
Регистрация: 10.2.2005
Где: msk.ru

Репутация: 31
Всего: 132



В любом случае класс должен лежать в Class-Path, и при вызове Serializator и при вызове Loader, информация о том какой именно это класс тоже записывается при сериализации. А вот упоминать сам класс в Loader совсем необязательно, достаточно интерфейса.
PM MAIL Skype GTalk Jabber YIM   Вверх
anonymouse
Дата 20.7.2005, 11:43 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 197
Регистрация: 18.8.2004

Репутация: нет
Всего: 1



У тебя вообше с нормаьлным классом без интерфейса работает ?
--------------------
Много чего интересного...
PM MAIL   Вверх
Alar
Дата 20.7.2005, 11:55 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 20.7.2005
Где: г. Пермь

Репутация: нет
Всего: нет



Цитата(tux @ 20.7.2005, 11:34)
В любом случае класс должен лежать в Class-Path, и при вызове Serializator и при вызове Loader, информация о том какой именно это класс тоже записывается при сериализации.

Это-то понятно. Проблема как раз в том, что небходимо, чтобы класс не лежал в classpath.
Цитата(anonymouse @ 20.7.2005, 11:43)
У тебя вообше с нормаьлным классом без интерфейса работает ?

Работает и с интерфейсом, если класс Foo затолкать в classpath.
PM MAIL ICQ   Вверх
tux
Дата 20.7.2005, 12:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Летатель
***


Профиль
Группа: Участник Клуба
Сообщений: 1853
Регистрация: 10.2.2005
Где: msk.ru

Репутация: 31
Всего: 132



Цитата
Проблема как раз в том, что небходимо, чтобы класс не лежал в classpath.

Так не получится, откуда JVM узнает инфу о классе? При сериализации байт-код не сохраняется. Единственное, что могу предложить - написать свой собственный мудреный класс-лоудер, который будет грузить класс не из Class-Path, а откуда-то из другого места, по ссылке из сети, например.
PM MAIL Skype GTalk Jabber YIM   Вверх
Alar
Дата 20.7.2005, 12:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 20.7.2005
Где: г. Пермь

Репутация: нет
Всего: нет



Цитата(tux @ 20.7.2005, 12:01)
написать свой собственный мудреный класс-лоудер,

а как это вообще делается? smile
а можно ли сделать так:
Код

      stream.writeObject(foo.getClass());
      stream.writeObject(foo);


... а другое приложение его считает?
PM MAIL ICQ   Вверх
batigoal
Дата 20.7.2005, 13:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Нелетучий Мыш
****


Профиль
Группа: Участник Клуба
Сообщений: 6423
Регистрация: 28.12.2004
Где: Санктъ-Петербургъ

Репутация: 24
Всего: 151



Цитата(Alar @ 20.7.2005, 13:52)
а как это вообще делается? smile

Посмотри тут:
Writing Your Own ClassLoader

Ну и доку:
http://java.sun.com/j2se/1.5.0/docs/api/ja...lassLoader.html


Цитата(Alar @ 20.7.2005, 13:52)
stream.writeObject(foo.getClass());
stream.writeObject(foo);

А потом восстановить его через Class.forName()? Смелая мысль. Может, попробуешь? Интересно...


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа" (Р. Шекли)
ЖоржЖЖ
PM WWW   Вверх
Alar
Дата 20.7.2005, 13:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 20.7.2005
Где: г. Пермь

Репутация: нет
Всего: нет



Цитата(Lamer @ 20.7.2005, 13:02)
Может, попробуешь?

Попробовал. Защита от извращенцев работает smile
На попытку загрузить класс:
Код

java.lang.ClassNotFoundException: bla.bla.bla.Serializator$Foo


ЗЫ. за ссылки - спасибо, почитаю.

Это сообщение отредактировал(а) Alar - 20.7.2005, 13:09
PM MAIL ICQ   Вверх
tux
Дата 20.7.2005, 13:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Летатель
***


Профиль
Группа: Участник Клуба
Сообщений: 1853
Регистрация: 10.2.2005
Где: msk.ru

Репутация: 31
Всего: 132



Вот здесь я выкладывал пример загрузчика классов:
http://forum.vingrad.ru/index.php?showtopic=53371&hl=
Цитата
А потом восстановить его через Class.forName()? Смелая мысль. Может, попробуешь? Интересно...

Опять-таки ведь в поток запишется состояние объекта, а не байт-код класса. А вот найти в Class-Path нужный класс и записать в поток байт-код можно попробовать. Хотя я себе не представляю задачу, где это нужно. Неужели проще это реализовать, чем передать клиенту jar с нужным классом?
PM MAIL Skype GTalk Jabber YIM   Вверх
kashka
Дата 20.7.2005, 16:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 117
Регистрация: 29.11.2004
Где: Wolfenbuettel, Ge rmany

Репутация: 1
Всего: 1



Странно а у меня все работает.
Hello, world!!!
PM MAIL   Вверх
Alar
Дата 21.7.2005, 06:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 20.7.2005
Где: г. Пермь

Репутация: нет
Всего: нет



Цитата(kashka @ 20.7.2005, 16:43)
Hello, world!!!

Hello, kashka!!!
Ты просто не выполнил(а) условия: нужно, чтобы первый проект видел второй (classpath), а второй НЕ видел первый. В этом смысл. Если второму добавить первый в classpath или вообще все спихать в один, то конечно все будет работать.

По теме: похоже простыми способами проблема не решается. smile Придется делать по-другому smile
Спасибо всем ответившим.
PM MAIL ICQ   Вверх
tux
Дата 21.7.2005, 08:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Летатель
***


Профиль
Группа: Участник Клуба
Сообщений: 1853
Регистрация: 10.2.2005
Где: msk.ru

Репутация: 31
Всего: 132



To Alar
В общем идея такая... Пусть сервер - это Serializator, клиент - Loader. Для того, чтобы в клиенте получить класс, которого нет в Class-Path можно реализовать следующее:
на сервере:
  • находим в jar-файлах и каталогах из Class-Path байт-код класса, получаем его как массив байтов. Как это сделать должно быть описано во всех примерах класс-лоудеров;
  • передаем клиенту полученный массив байтов и сериализованный класс через файл, сокет или еще каким-то макаром.
на клиенте:
  • реализуем класс-лоудер (без него к сожалению никуда), который преобразует массив байтов в нужный класс, опять-таки примеры реализации есть, но не для данного случая конечно;
  • получаем байт-код в массиве и сериализованный класс;
  • создаем класс, используя реализованный класс-лоудер.
Кажется должно сработать. Сложнее если в классе есть атрибуты нестандартных классов, тогда надо придумывать и как их передавать. Если будешь это реализовывать, напиши что получилось в результате. Интересно все-таки. smile
PM MAIL Skype GTalk Jabber YIM   Вверх
zone51
Дата 13.1.2008, 02:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 370
Регистрация: 17.2.2006

Репутация: нет
Всего: 1



Кстати вот у меня анаог проблема встала. Есть клиент и есть сервер. Сервер посылает клиенту обьект-мой класс. Причем с заранее установленными полями. И выскакивает такой же эксепшн что не найден класс. Прошу если кто решил эту проблему напишите или посоветуйте еще чтонить. Спасибо. smile 


--------------------
The truth is out there
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0566 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.