Tomcat-won';是否加载META-INF\services\javax.servlet.ServletContainerInitializer文件?

Tomcat-won';是否加载META-INF\services\javax.servlet.ServletContainerInitializer文件?,java,eclipse,web-applications,tomcat,Java,Eclipse,Web Applications,Tomcat,我有一个web项目,它有一个\META-INF\services\javax.servlet.ServletContainerInitializer文件,其内容指向实现ServletContainerInitializer接口的类的完全限定名。我基本上遵循了这里给出的示例: 我将调试行放在实现ServletContainerInitializer接口的类中,但它从未实现过。甚至不是默认的构造函数 我的应用程序文件夹结构如下: \MyApp \META-INF\services\jav

我有一个web项目,它有一个
\META-INF\services\javax.servlet.ServletContainerInitializer
文件,其内容指向实现ServletContainerInitializer接口的类的完全限定名。我基本上遵循了这里给出的示例:

我将调试行放在实现ServletContainerInitializer接口的类中,但它从未实现过。甚至不是默认的构造函数

我的应用程序文件夹结构如下:

\MyApp
      \META-INF\services\javax.servlet.ServletContainerInitializer
      \WEB-INF\classes\
                 ... [list of classes and packages go here]
你知道我需要检查什么吗

注1:我的Tomcat从包含我的应用程序的分解外部文件夹发布


注2:我是从Eclipse开始使用Tomcat的——如果这有什么不同的话

首先要检查的是,您实际使用的是Servlet 3.0,而不是早期版本。对于Tomcat,这意味着您必须使用Tomcat 7.0.22

其次,确保\META-INF\services\javax.servlet.ServletContainerInitializer文件实际存在于分解的war文件中


第三,当有疑问时,直接配置并启动Tomcat(而不是从Eclipse)——我看到开发人员在使用Eclipse插件配置Tomcat时遇到了无数问题。

好吧,我认为您需要包装您的初始值设定项类(以及它与服务相关的META-INF目录)放入一个单独的*.jar中,并将其放入
WEB-INF/lib

这是一个JAR服务,所以我想它可能与在*.war文件中发现服务的问题有关。此外,如果您将META-INF目录放在
WEB-INF/classes
中,并在Tomcat的
server.xml
中设置
unpwar=false
,它也不会有帮助


HTH.

要让tomcat加载META-INF目录,它必须位于classes文件夹中。如果您使用的是maven项目,只需将META-INF目录放在src/main/resources目录中即可。。在mvn包上,相同的文件将被复制到classes目录中。。不需要分离罐。。如果您更喜欢jar,您可以使用
手柄类型注释

我想引用Tomcat用户邮件列表上给出的Mark Thomas的一些很好的解释:

服务文件由类加载器从META-INF/services加载 目录

*jar先生/META-INF/服务 和 *.war/WEB-INF/classes/META-INF/services 对类装入器可见

*.战争/META-INF/服务 事实并非如此

servlet专家组最近在 Java9和多版本JAR。结论是(我在解释) 战争不是一种特殊形式的战争 通用格式JAR可用的特性不会自动更改 可用于WAR,除非Servlet规范(JavaEE规范)明确 另有说明

如果容器愿意,可以自由添加特定于容器的扩展 但是,它们附带了通常的(缺乏)互操作性警告


您是否仍在使用此ServletContainerInitializer时遇到问题?是的,我放弃了,决定采用另一种方法。。。但是,这很烦人,因为它无法解释为什么它不起作用。你也有同样的问题吗?不,我没有。我只是你在文章中提到的博客的作者,这就是为什么我想知道我是否能帮你:-)啊,谢谢。好吧,这看起来很简单,应该是这样,但无论我怎么尝试,它都不会爆发。就好像javax.servlet.ServletContainerInitializer文件根本不存在。我能够在JBoss上运行它,所以我知道这不是我的war文件如何设置的问题,而是Tomcat如何扫描服务文件夹的问题。你使用了什么Tomcat?我将尝试设置您正在使用的环境。谢谢您的回答。这可以解释这种行为。。然而,我确实觉得奇怪的是JBoss似乎与我的设置一起工作,并且可以在services文件夹中发现服务,即使您没有将它们包装在Jar文件中。。。但是雄猫没有!无论如何,谢谢你。很高兴我能帮忙。当你说JBoss找到了服务时,你把“服务”目录放在应用程序的哪里了?是在
WEB-INF/classes/META-INF
内部还是在
META-INF
内部与
WEB-INF
处于同一级别?我确认这个答案。类和META-INF/services/javax.servlet.ServletContainerInitializer定义文件都必须位于WEB-INF/lib中单独的.jar文件中。将META-INF/services或WEB-INF/classes/META-INF/services中的WAR文件放入META-INF/services中不起作用。此外,如果相关JAR文件放在Tomcat自己的lib目录中,它可以看到所有上下文初始化。如果将它放在web应用程序的web-INF/lib目录中,则只能看到web应用程序的上下文初始化。Spring Framework 3.1提供了一个很好的自行打包jar的解决方案。spring-web-VERSION.jar包含一个
ServletContainerInitializer
实现,并包含
META-INF/services/javax.servlet.ServletContainerInitializer
文件,该文件指示容器加载
org.springframework.web.SpringServletContainerInitializer
SpringServletContainerInitializer
将加载扩展Spring的
WebApplicationInitializer
接口的任何类。此外,
WebApplicationInitializer#onStartup
是一个比
servletcontainerinInitializer#onStartup
更易于实现的接口。同样,Windows上的进程监视器清楚地显示,例如Tomcat 7.0.90正在扫描
WEB-INF/classes/META-INF/services/[…]
META-INF
WEB-INF
的同一级别上似乎根本没有被使用。我前面的陈述对Tom来说是正确的