Есть ли возможность перезагрузить класс
От: Oval  
Дата: 09.03.04 17:26
Оценка:
Загруженый статическим методом class.forName
(перезагрузить надо прекомпилированный class-плагин)
Re: Есть ли возможность перезагрузить класс
От: Blazkowicz Россия  
Дата: 09.03.04 17:30
Оценка:
Здравствуйте, Oval, Вы писали:

O>Загруженый статическим методом class.forName

O>(перезагрузить надо прекомпилированный class-плагин)

Да. загружай его отдельным загрузчиком (Classloader). И forName делай с указанием конкретного загрузчика. Для обновления нужна создать новый загрузчик. И спросить класс у него. Он загрузит его заново.

В Яве 1.5 обещают более красивое решение.
Re[2]: Есть ли возможность перезагрузить класс
От: Oval  
Дата: 09.03.04 18:44
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

B>Здравствуйте, Oval, Вы писали:


O>>Загруженый статическим методом class.forName

O>>(перезагрузить надо прекомпилированный class-плагин)

B>Да. загружай его отдельным загрузчиком (Classloader). И forName делай с указанием конкретного загрузчика. Для обновления нужна создать новый загрузчик. И спросить класс у него. Он загрузит его заново.


B>В Яве 1.5 обещают более красивое решение.


Мысля вокруг этого и крутилась — не охота было проверять — тонну кода перелапачивать.
То есть практически в программе возможно существование разных классов но с одинаковыми именами?
Re: Есть ли возможность перезагрузить класс
От: dshe  
Дата: 10.03.04 07:01
Оценка:
Здравствуйте, Oval, Вы писали:

O>Загруженый статическим методом class.forName

O>(перезагрузить надо прекомпилированный class-плагин)

http://www.javaworld.com/javaqa/2002-07/01-qa-0705-loader-synch_p.html?

Q: I use the Class.forName() method to dynamically load Java classes. However, if I recompile a class and reload it, the new recompiled class does not load. How do I force class reloading?

A: The standard class loader will not reload a class for you. Instead, you need to develop a custom class loader. Luckily, such a class loader already exists, and I'm sure with a little alteration it will serve your needs.

First, download JUnit. Then look at its junit.runner.TestCaseClassLoader.java, a class loader able to reload any given class. JUnit uses TestCaseClassLoader so you do not need to shut down the test GUI (graphical user interface) every time you recompile your test classes. Unfortunately, the latest version cannot reload classes from jar files.

--
Дмитро
Re[3]: Есть ли возможность перезагрузить класс
От: Blazkowicz Россия  
Дата: 10.03.04 08:44
Оценка:
Здравствуйте, Oval, Вы писали:

O>Мысля вокруг этого и крутилась — не охота было проверять — тонну кода перелапачивать.

O>То есть практически в программе возможно существование разных классов но с одинаковыми именами?

Да. И что самое противное такая ситуация является потонцеальным источником различных ошибок. Особенно в таких бесплатных решениях как JBoss.

Я бы на твоём месте попытался построить решение на базе 1.5. Если, конечно есть возможность.
Re[4]: Есть ли возможность перезагрузить класс
От: dshe  
Дата: 10.03.04 09:05
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

B>Я бы на твоём месте попытался построить решение на базе 1.5. Если, конечно есть возможность.


Я что-то сходу не нашел. Точно есть?
--
Дмитро
Re[5]: Есть ли возможность перезагрузить класс
От: Blazkowicz Россия  
Дата: 10.03.04 09:22
Оценка:
Здравствуйте, dshe, Вы писали:

D>Я что-то сходу не нашел. Точно есть?


А ты хорошо читал статьи, ссылки на которые давал?

http://java.sun.com/developer/technicalArticles/releases/j2se15/

Раздел:

New JVM profiling API (JSR-163)

Фича называется Instrumentation.

The new java.lang.instrument package provides services that allow Java programming agents to instrument programs running on the Java virtual machine. The intrumentation mechanism is modification of the bytecodes of methods.

Re[6]: Есть ли возможность перезагрузить класс
От: dshe  
Дата: 10.03.04 09:55
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

B>Раздел:

B>New JVM profiling API (JSR-163)
B>Фича называется Instrumentation.

Что ж, готов согласиться, что это API может помочь в решении данной задачи. Спасибо за подсказку.
--
Дмитро
Re: Есть ли возможность перезагрузить класс
От: Аноним  
Дата: 10.03.04 09:58
Оценка:
Да, конечно, вспомни школу.
Re[7]: Есть ли возможность перезагрузить класс
От: fenix13  
Дата: 23.01.08 17:14
Оценка:
Привет ребята :

Я использую пример по данной вами ссылки выше .

И у меня ничего не выходит .
У меня постоянно такая ошибка redefineClasses is not supported in this environment

Что это может быть ?
Re[8]: Есть ли возможность перезагрузить класс
От: Blazkowicz Россия  
Дата: 23.01.08 18:34
Оценка:
Здравствуйте, fenix13, Вы писали:

F>У меня постоянно такая ошибка redefineClasses is not supported in this environment

Полнай текст ошибки + stacktrace. А так же используемая JVM, ОС, и как запускаешь.
Re[8]: Есть ли возможность перезагрузить класс
От: Blazkowicz Россия  
Дата: 23.01.08 18:35
Оценка:
Здравствуйте, fenix13, Вы писали:

F>У меня постоянно такая ошибка redefineClasses is not supported in this environment


http://download.java.net/jdk/jdk-api-localizations/jdk-api-zh-cn/builds/latest/html/en/api/java/lang/instrument/Instrumentation.html#isRedefineClassesSupported()
Re[8]: Есть ли возможность перезагрузить класс
От: dshe  
Дата: 24.01.08 07:15
Оценка:
Здравствуйте, fenix13, Вы писали:

F>Я использую пример по данной вами ссылки выше .


F>И у меня ничего не выходит .

F>У меня постоянно такая ошибка redefineClasses is not supported in this environment

На текущий момент в большинстве случаев я предпочел бы вариант с classloader'ами (не такой уж некрасивый этот вариант), а Instrumentation оставил бы для очень специфических случаев.
--
Дмитро
Re[9]: Есть ли возможность перезагрузить класс
От: fenix13  
Дата: 24.01.08 07:43
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

B>Полнай текст ошибки + stacktrace. А так же используемая JVM, ОС, и как запускаешь.


OS: Windows XP Pro SP2
JVM: 1.6.0.04
IDE: Eclipse 3.4

Запускаю из еклипса след образом :
запускаю главный класс BCITest с параметром VM: -javaagent:D:/work/NewJVMProfilingAPI/lib/myBCI.jar

Этот myBCI.jar — я делал следующим образом :
скомпилил класс myBCI из примера — получил myBCI.class , сдела вручную MANIFEST.MF — со следующим контентом :
Manifest-Version: 1.0
Created-By: 1.6.0_04 (Sun Microsystems Inc.)
Premain-Class: myBCI

Дальше вручную сделал myBCI.jar файл : jar cfM myBCI.jar META-INF/MANIFEST.MF myBCI.class . Получил правельный джар.

Ошибка :
OriginalClass — это выполнение первой версии класс , она проходит нормально
java.lang.UnsupportedOperationException: redefineClasses is not supported in this environment

Если выполнять эту программу в консоли так как написано в примере то результатом будет :
OriginalClass

тоесть ошибки не выдает , или просто не пишет сюда .

Что это может быть ?
Спасибо,
Re[9]: Есть ли возможность перезагрузить класс
От: fenix13  
Дата: 24.01.08 07:48
Оценка:
Здравствуйте, dshe, Вы писали:

D>На текущий момент в большинстве случаев я предпочел бы вариант с classloader'ами (не такой уж некрасивый этот вариант), а Instrumentation оставил бы для очень специфических случаев.


Да это неплохой и рабочий вариант . Но сколько я не бился — он не позволяет подменить класс. Загрузить новый класс и работать с ним можно . Но это не то что мне нужно .

Если есть реализация примера с classloader'ами — которая подменяет классы то киньте мне . Интересно как сделано в Tomacat ? У них реализовано както что Сервлеты подгребаються автоматически без перезагрузки Tomcat .
Re[10]: Есть ли возможность перезагрузить класс
От: Blazkowicz Россия  
Дата: 24.01.08 08:04
Оценка:
Здравствуйте, fenix13, Вы писали:

F>скомпилил класс myBCI из примера — получил myBCI.class , сдела вручную MANIFEST.MF — со следующим контентом :

F>Manifest-Version: 1.0
F>Created-By: 1.6.0_04 (Sun Microsystems Inc.)
F>Premain-Class: myBCI

http://rsdn.ru/forum/message/2809283.1.aspx
Автор: Blazkowicz
Дата: 23.01.08
Re[10]: Есть ли возможность перезагрузить класс
От: dshe  
Дата: 24.01.08 09:15
Оценка:
Здравствуйте, fenix13, Вы писали:

F>Здравствуйте, dshe, Вы писали:


D>>На текущий момент в большинстве случаев я предпочел бы вариант с classloader'ами (не такой уж некрасивый этот вариант), а Instrumentation оставил бы для очень специфических случаев.


F>Да это неплохой и рабочий вариант . Но сколько я не бился — он не позволяет подменить класс. Загрузить новый класс и работать с ним можно . Но это не то что мне нужно .


С подменой класса есть некоторые нюансы, которые надо учитывать. Например, что делать с существующими экземплярами классов, если класс исчез, или в классе добавилось новое поле? Расширять? Каким значением тогда инициализировать? Что делать если в момент переопределения исполняется метод, который в новом классе отсутствует? или идет обращение в удаленному (или переименованному) полю?

Поэтому Instrumentation обладает ограниченными возможностями по переопределению классов (в частности, насколько я понял из javadoc, добавление, удаление и переименовывание полей и методов не допускаются; можно только менять тела методов). Вариант с classloader'ами в определенной степени разрешает данные вопросы поскольку допускает сосуществование старой и новой версии классов (загруженных разными класслоадерами).

F>Если есть реализация примера с classloader'ами — которая подменяет классы то киньте мне . Интересно как сделано в Tomacat ? У них реализовано както что Сервлеты подгребаються автоматически без перезагрузки Tomcat .


Каждое веб-приложение загружаются своим classloader'ом. Когда Tomcat обнаруживает, что нужно перегрузить некоторое приложение (например, если поменялся web.xml), то он останавливает загруженное (вызывает destroy у сервлетов, фильтров, session и servlet context listener'ов), загружает новым класслоадером новое приложение и заново его инициализирует, а о старом (с его класслоадером) забывает позволяя GC его собрать. С jsp та же история.
--
Дмитро
Re[11]: Есть ли возможность перезагрузить класс
От: fenix13  
Дата: 24.01.08 09:38
Оценка:
Здравствуйте, dshe, Вы писали:



D>С подменой класса есть некоторые нюансы, которые надо учитывать. Например, что делать с существующими экземплярами классов, если класс исчез, или в классе добавилось новое поле? Расширять? Каким значением тогда инициализировать? Что делать если в момент переопределения исполняется метод, который в новом классе отсутствует? или идет обращение в удаленному (или переименованному) полю?


Есть не спорю , но идея таки в том что я буду менять только тело методов .

D>Поэтому Instrumentation обладает ограниченными возможностями по переопределению классов (в частности, насколько я понял из javadoc, добавление, удаление и переименовывание полей и методов не допускаются; можно только менять тела методов). Вариант с classloader'ами в определенной степени разрешает данные вопросы поскольку допускает сосуществование старой и новой версии классов (загруженных разными класслоадерами).


F>>Если есть реализация примера с classloader'ами — которая подменяет классы то киньте мне . Интересно как сделано в Tomacat ? У них реализовано както что Сервлеты подгребаються автоматически без перезагрузки Tomcat .


D>Каждое веб-приложение загружаются своим classloader'ом. Когда Tomcat обнаруживает, что нужно перегрузить некоторое приложение (например, если поменялся web.xml), то он останавливает загруженное (вызывает destroy у сервлетов, фильтров, session и servlet context listener'ов), загружает новым класслоадером новое приложение и заново его инициализирует, а о старом (с его класслоадером) забывает позволяя GC его собрать. С jsp та же история.


Вот это, мне очень нравиться . Я по началу тоже пытался так сделать . Но не придумал как удалять старый клас лоадер . Если есть идеи поделитесь . И если например убить старый клас лоадер . То я так понимаю когда я загружу новый лоадер с новой версией класс . То когда понадобиться этот класс — то автоматически подгребётся новая версия класса .
Re[11]: Есть ли возможность перезагрузить класс
От: fenix13  
Дата: 24.01.08 09:45
Оценка:
Здравствуйте, Blazkowicz, Вы писали:


B>http://rsdn.ru/forum/message/2809283.1.aspx
Автор: Blazkowicz
Дата: 23.01.08


Намёк я понял и использовал его . По идеи в Манифесте нехватало Can-Redefine-Classes: true

Я поставил и функция isRedefineClassesSupported() — стала выдавать true . Незнаю или правду говорит или просто берет значение из манифеста . Может еще чего нужно конфигурировать в самом JVM ?

Появились новые проблемы (это происходит в момент вызова redefineClasses):

OriginalClass
Exception in thread "main" java.lang.NoClassDefFoundError: class names don't match
at sun.instrument.InstrumentationImpl.redefineClasses0(Native Method)
at sun.instrument.InstrumentationImpl.redefineClasses(Unknown Source)
at BCITest.main(BCITest.java:28)


Значения я проверяю , валидные ему даю все нормально . Что еще может быть ?

Может этот пример очень сырой — его както дополнять нужно может ?
Re[12]: Есть ли возможность перезагрузить класс
От: fenix13  
Дата: 24.01.08 10:25
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

Ура!!!!!!!!! Я сделал . Радости нет придела и благодарности тоже , за оказанную помощ .

Короче это уже я затупил . У меня второй клас которым я хотел заменить созданный был в пакете . Получалось что имена не совпадали .

Большое спасибо !!!!!!.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.