Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tomcat - won't load my META-INF\services\javax.servlet.ServletContainerInitializer file?

I have a web project that has a \META-INF\services\javax.servlet.ServletContainerInitializer file with its content pointing to the fully qualified name of a class that implements the ServletContainerInitializer interface. I basically followed the example given here: http://nullhaus.com/2011/03/using-servlets-3-0-servletcontainerinitializer/

I put debug lines in my class that implements the ServletContainerInitializer interface and it never makes it there. Not even the default constructor...

My application folder structure is as follows:

\MyApp
      \META-INF\services\javax.servlet.ServletContainerInitializer
      \WEB-INF\classes\
                 ... [list of classes and packages go here]

Any ideas what I need to check for??

Note 1: My Tomcat publishes from an exploded external folder that contains my application

Note 2: I started my Tomcat from Eclipse - if that makes a difference!

like image 774
Ayyoudy Avatar asked Oct 07 '11 20:10

Ayyoudy


4 Answers

For tomcat to load the META-INF directory , it has to be in classes folder . If you are using maven project , just put the META-INF directory inside src/main/resources directory .. on mvn package the same will be copied to classes directory .. No need of separerate jar .. if jar is prefered you can use HandlesTypes annotation ..

like image 121
Aneer Geek Avatar answered Nov 01 '22 19:11

Aneer Geek


The first thing to check is that you are actually using Servlet 3.0 and not an earlier version. For Tomcat, this means that you must be using Tomcat 7.0.22

Second, make sure that the \META-INF\services\javax.servlet.ServletContainerInitializer file actually exists in the exploded war file.

Third, when in doubt, configure and start Tomcat directly (not from Eclipse) - I've seen developers have endless problems with configuration of Tomcat using the Eclipse plugin.

like image 25
GreyBeardedGeek Avatar answered Nov 01 '22 19:11

GreyBeardedGeek


Well, I think that you'll need to wrap your initializer class (and it's services-related META-INF directory) into a separate *.jar and put it in the WEB-INF/lib.

This is a JAR service, so I guess it could have something to do with problems with discovering services in a *.war file. Moreover, it doesn't even help if you put your META-INF directory inside WEB-INF/classes and set unpackWAR=false in your Tomcat's server.xml.

HTH.

like image 5
Piotr Nowicki Avatar answered Nov 01 '22 21:11

Piotr Nowicki


I would like to quote some good explanation from Mark Thomas <[email protected]> given on the user mailing list of Tomcat:

Service files are loaded by class loaders from the META-INF/services directory.

*.jar!/META-INF/services and *.war/WEB-INF/classes/META-INF/services are visible to class loaders

*.war!/META-INF/services is not.

The servlet expert group recently discussed WAR vs JAR in the context of Java 9 and mutli-version JARs. The conclusion was (I'm paraphrasing) that WARs are not a specialised form of JAR and while they share a common format a feature that is available to a JAR is NOT automatically available to a WAR unless the Servlet spec (of Java EE spec) explicitly states otherwise.

Containers are free to add container specific extensions if they wish but they come with the usual (lack of) interoperability warnings.

http://mail-archives.apache.org/mod_mbox/tomcat-users/201808.mbox/

like image 1
Thorsten Schöning Avatar answered Nov 01 '22 20:11

Thorsten Schöning