tomcat - динамически перезагружать классы - PullRequest
1 голос
/ 24 ноября 2010

У меня есть папка с большим количеством файлов .class.Эти классы обновляются с 'app 1' .И есть 'приложение 2' , которое динамически загружает эти классы.

И проблема в том, что ...

'приложение 2' используетфайл класса, 'app 1' , обновите этот файл, затем 'app 2' снова понадобится класс, но, похоже, он сохранит и использует копию более старого класса.

Итак, я проверил папку и класс был успешно обновлен, я попытался перезагрузить 'app 2' , но он продолжает использовать старый класс.

Только если я перезапущу tomcat 'app 2' читает новый класс.

Почему это так?Мне разрешено перезагружать 'app 2' , но в производственной среде я не могу перезапустить tomcat.

Это очень важно в моей работе, я ценю любую идею .....

Я использую чистую установку tomcat6 и загружаю файлы классов с: Class.forName(<classname>).newInstance()

thx много

Ответы [ 4 ]

3 голосов
/ 24 ноября 2010

Проблема в том, что среда выполнения уже загрузила старый файл классов в загрузчик классов, который используется кодом, который хочет использовать измененный класс.Вам нужно найти способ заставить загрузчик классов обновить содержимое своего класса с диска, чтобы достичь того, чего вы хотите.Вот почему Class.forName () не работает: он обращается к уже загруженной (и кэшированной) версии класса.Alex R прав, что вы должны попытаться реструктурировать свой код, чтобы разделить ваши классы для этих двух проектов.Но, если вы абсолютно не хотите пытаться перезагрузить этот класс и оставить все как есть, вы можете попробовать поэкспериментировать с Classloader.defineClass () и загрузить новую версию класса из его файла .class в byte [], затем передавая этот байт [] в Classloader.defineClass ().Скорее всего, вы захотите использовать загрузчик классов контекста, связанный с вашим приложением Tomcat (а не загрузчик классов Tomcat верхнего уровня).В документации по Tomcat есть различие между ними.

2 голосов
/ 24 ноября 2010

По умолчанию классы кэшируются ClassLoader, который их загружал. Если вы выполните: Class.forName('MyClass') два раза подряд, класс будет загружен только в первый раз.

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

Вы можете быть в состоянии расширить ClassLoader и изменить поведение кэширования.

1 голос
/ 26 ноября 2010
0 голосов
/ 24 ноября 2010

Я думаю, что вы должны попытаться разделить классы для этих двух приложений.Попробуйте сначала создать 2 одинаковых каталога.Один для app1, второй для app2.Если это решит вашу проблему, упакуйте свои классы в jar и оставьте только 2 дубликата jar-файловЯ думаю, что проблема не в Java, а в файловой системе.Я считаю, что вы используете Windows.Если это так, вероятно, попытайтесь сделать то, что вы делаете сейчас в Linux (если это не имеет отношения к вашей компании).

...