| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Java EE (J2EE) и Spring > Запустить сервлет |
| Автор: DEER 15.12.2006, 14:49 |
| Привет всем! Можно ли сделать такой сервлет, метод init которго быдет вызываться при начале работы приложения? Наподобии ActionServlet из struts, просто ActionServlet мне не подходит, так как он уже есть, и делает много разных дел, и запихивать туда ещё одну большую функциональность не хочется... |
| Автор: tux 15.12.2006, 14:56 | ||||
| Можно сделать Listener. web.xml:
SomeContextListener.java:
Будет запускаться при инициализации приложения. |
| Автор: DEER 15.12.2006, 15:00 |
| и "жить" всё время пока приложение не выключат? мне там поток надо запустить |
| Автор: DEER 15.12.2006, 15:12 |
| чтобы потом его корректно завершить. закрыть все конекшены и сказать "пока" спасибо tux |
| Автор: DEER 15.12.2006, 18:15 |
| попробовал создать простой listener, запускаю debug чтобы осмотреть как он отработает, и что же я вижу? Он туда заходит ДВА раза!! Первый раз при начале загрузки tomkat'а, а второй раз уже непосредственно когда приложение стартовало. Скажите, так и должно быть? Я использовать в сервлет и написать в его описании load-on-startup не решит мою проблему? |
| Автор: 3x3 15.12.2006, 19:55 | ||
Кстати, вы уверены, что два раза он заходит по разным событиям? У меня было ощущение/подозрение (на почве эксперимента с одновременной загрузкой 9ти идентичных страничек во фреймсет), что томкат по дефолту стартует два (или три) процесса для обслуживания HTTP-запросов и озадачивает их по очереди. Не может так быть что листенер инитится для каждого из них персонально? |
| Автор: y3u 15.12.2006, 20:12 |
| ну есть еще старый добрый вариант, которым мало кто теперь пользуется - это сделать сервелет, сделать ему <load-on-startup>1</load-on-startup> но не мепить его ни на како контекст... можно в нем тогда перекрыть init() и destoy()... уж сервлет то должен заинициалайзиться точно только один раз... |
| Автор: Stampede 15.12.2006, 21:02 | ||
| Все-таки иделогически более правильно делать такие вещи через ServletContextListener. То, что он два раза вызывается - это какой-то глюк. Надо просто его отловить и потом спокойно пользоваться. Как отловить глюк? Ну давай для начала посмотрим, что говорит стек вызовов. Если есть отладчик (какая IDE?), то делается вообще на раз, через брейкпойнт. Если отладчика нету, то можно сделать так:
И сразу все станет ясно. Должно, по крайней мере. Если что - кидай вывод в форум, попробуем разобраться. |
| Автор: Greg 15.12.2006, 23:11 | ||
Тебе нужен сервлет который вызывается только в самом начале ? Смущает сравнение с ActionServlet который отрабатывает на каждом запросе к контейнеру. |
| Автор: 3x3 17.12.2006, 04:32 | ||||
| Попробовал поэкспериментировать с Томкатом (v.5.5.17) на ту тему, о которой писал выше, но использовал JSP. Похоже он действительно дважды создаёт сервлет. Непосредственно после запуска сервера (или первого обращения к JSP-странице) пользовательские запросы какое-то время выполняет один экземпляр класса, а потом (через секунду-две) в работу включается другой, и остаётся уже навсегда. Вот вырожденный случай - первый файл это просто фреймсет 3х3 одинаковых фреймов, содержимое которых генерится jsp-шкой, код которой занимается лишь деланием toString() объекта и представлен во втором файле: test4.html
test4.jsp
Так вот что выводится во фреймах (первая цифра - номер фрейма): 1. this: org.apache.jsp.test4_jsp@1493995 2. this: org.apache.jsp.test4_jsp@1493995 3. this: org.apache.jsp.test4_jsp@1493995 4. this: org.apache.jsp.test4_jsp@1493995 5. this: org.apache.jsp.test4_jsp@1493995 6. this: org.apache.jsp.test4_jsp@2c39d2 7. this: org.apache.jsp.test4_jsp@2c39d2 8. this: org.apache.jsp.test4_jsp@2c39d2 9. this: org.apache.jsp.test4_jsp@2c39d2 Если заглушить спячку в JSP-файле, то во все фреймы выводится одинаковый ID объекта, но при самой первой загрузке он один, а при последующих - другой, и при том уже, похоже, больше уже не меняется. Интересно, что это за первый инстанс, который сначала отрабатывает запросы и потом заменяется другим экземпляром того же объекта и нафига он нужен? |
| Автор: tux 17.12.2006, 13:04 | ||||
У меня есть версия почему так может происходить. Если war описан с помощью тэга <Context> в server.xml и при этом лежит в каталоге ${CATALINA_HOME}/webapps, для которого включен autoDeploy, то Tomcat инициализирует приложение дважды, как следствие ServletContextListener вызывается два раза. Насчет JSP действительно интересно. У меня получилось тоже самое. Потом покопался в документации и вот чего обнаружил. В Tomcat 5.5 используется Jasper 2 и одно из его свойств:
То есть JSP может компилироваться (судя по всему делается это когда JSP изменился и при старте приложения) в фоновом режиме и какое-то время пока выполняется компиляция будет использоваться старый экземпляр. А вот когда приложение запустилось первый раз, Tomcat зачем-то первый раз компилит JSP в связи с тем, что он вообще еще не компилировался, а затем второй раз в связи с тем, что приложение запустилось. Зачем не понятно. Видимо Jasper 2 все еще недостаточно интеллектуален. |
| Автор: 3x3 17.12.2006, 15:07 | ||
Да, точно, к сервлету это не относится. |
| Автор: DEER 18.12.2006, 10:40 | ||||
| ДаДаДа короче запускается ВСЁ по два раза, но не из за того что это Листенер-ы, потому что и сервлеты, у который прописано <load-on-startup>1</load-on-startup> тоже по два раза отрабатывают это потому что,
ну или по крайней мере приблизительно потому что, короче у меня проект лежит в одном каталоге, а деплоится при запуске в другой, из за этого и происходит... На других рабочих станциях всё нормально работает! Всем спасибо!!! Добавлено @ 10:48 Stampede, вот чо пишется в консоли при запуске
некоторые строки помечены Duplicate |
| Автор: Катена 8.1.2007, 04:06 |
| Помогите пожалуйста!!!!!!! .java не компилируется в .class Установила j2se, j2ee, прописала все переменные окружения ошибку выдает на import javax.servlet.*; и import javax.servlet.http.*; |
| Автор: 3x3 8.1.2007, 04:46 | ||
Оно ещё должно знать где сидит jar-файл с этими классами. Например у меня под томкатом эти классы сидят в T:/Tomcat.5.5.17/common/lib/servlet-api.jar и если я хочу что-нибудь скомпилировать с их участием, могу вставить эту строчку в CLASSPATH (целиком, вместе с именем класса) или иначе указать компилятору где брать этот архив. При запуске из-под томката, контейнер уже сам позаботится что бы АПИ был доступен. |