#java #eclipse #web-applications #tomcat
#java #eclipse #веб-приложения #tomcat
Вопрос:
У меня есть веб-проект, в котором есть META-INFservicesjavax.servlet.ServletContainerInitializer
файл с содержимым, указывающим на полное имя класса, который реализует интерфейс ServletContainerInitializer. Я в основном следовал приведенному здесь примеру: http://nullhaus.com/2011/03/using-servlets-3-0-servletcontainerinitializer /
Я помещаю строки отладки в свой класс, который реализует интерфейс ServletContainerInitializer, и он никогда не попадает туда. Нет даже конструктора по умолчанию…
Структура папок моего приложения выглядит следующим образом:
MyApp
META-INFservicesjavax.servlet.ServletContainerInitializer
WEB-INFclasses
... [list of classes and packages go here]
Есть идеи, что мне нужно проверить??
Примечание 1: Мой Tomcat публикует из разнесенной внешней папки, содержащей мое приложение
Примечание 2: я запустил свой Tomcat из Eclipse — если это имеет значение!
Комментарии:
1. у вас все еще возникают проблемы с этим ServletContainerInitializer?
2. да, я сдался и решил использовать другой подход… однако это очень раздражает, потому что не имеет смысла, почему это не сработает. У вас тоже такая же проблема?
3. нет, я этого не делаю. Я просто автор блога, который вы упомянули в своем сообщении, поэтому мне любопытно, могу ли я помочь вам с этим 🙂
4. ах, спасибо. Ну, это кажется таким простым, и так и должно быть, но независимо от того, что я пробовал, это просто не сработало. Это как если бы javax.servlet. Файла ServletContainerInitializer даже нет. Мне удалось настроить его на JBoss, поэтому я точно знаю, что проблема не в том, как был настроен мой файл war, а в том, как Tomcat сканирует папку services.
5. и какой Tomcat вы использовали? Я попытаюсь настроить среду, которую вы используете.
Ответ №1:
Ну, я думаю, что вам нужно будет обернуть ваш класс инициализатора (и его каталог META-INF, связанный с сервисами) в отдельный * .jar и поместить его в WEB-INF/lib
.
Это служба JAR, поэтому я предполагаю, что это может иметь какое-то отношение к проблемам с обнаружением служб в файле * .war . Более того, это даже не поможет, если вы поместите свой каталог META-INF внутрь WEB-INF/classes
и установите unpackWAR=false
в свой каталог Tomcat server.xml
.
HTH.
Комментарии:
1. Спасибо за этот ответ. Это объясняет поведение.. Однако я нахожу странным то, что JBoss , похоже, работает с моей настройкой и может обнаруживать службы внутри папки Services, даже если они не завернуты в файл Jar… но Tomcat этого не делает! В любом случае, спасибо вам за это.
2. Рад, что смог помочь. Когда вы говорите, что JBoss нашел службы — куда вы поместили каталог «services» в приложении? Был ли он внутри
WEB-INF/classes/META-INF
или внутриMETA-INF
на том же уровне,WEB-INF
что и?3. Я подтверждаю этот ответ. Как класс, так и файл META-INF/services/javax.servlet . Файл определения ServletContainerInitializer должен быть отдельным. файл jar в WEB-INF / lib. Помещение META-INF/services в файл WAR в /META-INF/services или WEB-INF/classes/META-INF/services не работает.
4. В дополнение к этому, если соответствующий файл JAR помещен в собственный каталог библиотеки Tomcat, он может видеть все инициализации контекста. Если он помещен в каталог WEB-INF / lib веб-приложения, он может видеть только инициализации контекста этого веб-приложения.
5. Spring Framework 3.1 предоставляет хорошее решение для самостоятельной упаковки jar. spring-web-VERSION.jar содержит
ServletContainerInitializer
реализацию и включаетMETA-INF/services/javax.servlet.ServletContainerInitializer
файл , который указывает контейнеру на загрузкуorg.springframework.web.SpringServletContainerInitializer
. ЗатемSpringServletContainerInitializer
будут загружены любые классы, расширяющиеWebApplicationInitializer
интерфейс Spring. Кроме того,WebApplicationInitializer#onStartup
это более простой интерфейс для реализации, чемServletContainerInitializer#onStartup
.
Ответ №2:
Первое, что нужно проверить, это то, что вы на самом деле используете Servlet 3.0, а не более раннюю версию. Для Tomcat это означает, что вы должны использовать Tomcat 7.0.22
Во-вторых, убедитесь, что META-INFservicesjavax.servlet .Файл ServletContainerInitializer фактически существует в взорванном файле war.
В-третьих, если вы сомневаетесь, настройте и запустите Tomcat напрямую (не из Eclipse) — я видел, что у разработчиков возникают бесконечные проблемы с настройкой Tomcat с помощью плагина Eclipse.
Ответ №3:
Чтобы tomcat загрузил каталог META-INF, он должен находиться в папке classes . Если вы используете проект maven, просто поместите каталог META-INF в каталог src / main /resources .. в пакете mvn то же самое будет скопировано в каталог classes .. Нет необходимости разделять jar .. если предпочтительнее jar, вы можете использовать аннотацию HandlesTypes ..
Комментарии:
1. То же самое здесь, Process Monitor в Windows четко показывает, что, например, Tomcat 7.0.90 сканирует
WEB-INF/classes/META-INF/services/[...]
.META-INF
на том же уровнеWEB-INF
, похоже, вообще не используется.2. Мое предыдущее утверждение верно для Tomcat, используемого как внутри, так и отдельно за пределами Eclipse, протестировано как.
Ответ №4:
Я хотел бы привести несколько хороших объяснений, Mark Thomas <markt@apache.org>
приведенных в списке рассылки пользователей Tomcat:
Служебные файлы загружаются загрузчиками классов из каталога META-INF / services .
* .jar!/META-INF/services и *.war/WEB-INF/classes/META-INF/services видны загрузчикам классов
*.war!/META-INF/services нет.
Группа экспертов по сервлетам недавно обсуждала WAR против JAR в контексте Java 9 и многоверсионных JAR. Вывод был (я перефразирую), что войны не являются специализированной формой JAR, и, хотя они имеют общий формат, функция, доступная для JAR, АВТОМАТИЧЕСКИ НЕ доступна для WAR, если в спецификации сервлета (спецификации Java EE) явно не указано иное.
Контейнеры могут свободно добавлять определенные для контейнера расширения, если пожелают, но они поставляются с обычными предупреждениями о совместимости (отсутствии).
http://mail-archives.apache.org/mod_mbox/tomcat-users/201808.mbox/