15

I'm using Eclipse + Maven + m2eclipse to build and test a web application in Apache Tomcat.

I've configured a Tomcat server inside Eclipse, and configured the deployment assembly for my web app, including "Maven Dependencies" (specialization of Java Build Path Entries).

When I deploy and start the server, Tomcat/Catalina always warns me:

INFO: validateJarFile(/projects/src/main/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/webapp/WEB-INF/lib/servlet-api-2.5.jar) - jar not loaded. See Servlet Spec 2.3, section 9.7.2. Offending class: javax/servlet/Servlet.class

This is because m2eclipse sees servlet-api-2.5 as a dependency of my project, and considers it as part of "Maven Dependencies", and copies it as part of the deployment assembly, but the Tomcat servlet container has its own copy of this and doesn't like seeing 2 copies on the class path.

I've marked the dependency from my project to servlet-api-2.5 in my pom.xml with

<scope>
provided
</scope>

which does prevent standalone Maven from packaging servlet-api-2.5 into my builds, but m2eclipse doesn't see it that way.

(This isn't a huge deal because the warning is harmless, I only see it during testing inside the IDE, and real customers won't see it, but I'd still like to know how to fix it because I like cleanliness and I like knowing how things work.)

Is there a correct way to tell m2eclipse not to deploy this file, or to tell Eclipse not to let m2eclipse have the final say on which dependencies are runtime dependencies?

I did find https://issues.sonatype.org/browse/MNGECLIPSE-1193 which mentions

the "Maven Dependencies" container reflects test compile time scope, so it is supposed to have dependencies with scope "provided"

metamatt
  • 13,809
  • 7
  • 46
  • 56
  • Can you show the pOM for this project? Have you tested to put the scope tags into a single line? Do you have other dependencies own projects or transitive projects? Have you checked the dependency tree? – khmarbaise May 06 '11 at 12:37
  • @khmarbaise I have checked the dependency tree using "mvn dependency:tree" and every reference to servlet-api has provided scope. (Example: javax.servlet:servlet-api:jar:2.5:provided (version managed from 2.3; scope managed from compile)). I actually do have the scope tags in a single line, though I really hope no xml parser would care about that. – metamatt May 06 '11 at 17:23
  • How are you packaging your war? – khmarbaise May 07 '11 at 13:57
  • No war, just a bunch of jars. This bunch of jars includes servlet-api-2.5.jar in Eclipse's temporary deployment directory (.project/metadata/tmp/.../wtpwebapp), but not in my real target directory when I build with "mvn package". – metamatt May 07 '11 at 15:32
  • May be my questions was not clear enought. Does you maven build create a war file which contains the correct files and how to you package via the maven-war-plugin (packaging set as war?)? – khmarbaise May 07 '11 at 20:00
  • We don't create a war either for the Eclipse build or the standalone Maven build. Just a bunch of jars. – metamatt May 08 '11 at 00:18

5 Answers5

15

Install extras for m2eclipse plugin ("Maven Integration for WTP") from update site http://m2eclipse.sonatype.org/sites/m2e-extras. After install, update the project configuration.

  • Wow, thanks, that works. I didn't realize there was a separate WTP piece for m2eclipse. More on that here, now that I know what to search for: http://stackoverflow.com/questions/1822290/m2eclipse-and-eclipse-wtp – metamatt Jun 01 '11 at 22:09
6

Normally there is a dependency in your project that is depending on servlet-apî.jar

The default behaviour of Maven is that i wiill try to import your dependency + the dependencies of the imported dependency.

If you want to exclude a specific "sub-dependency", you can give maven a configuration like this :

<dependency>
    <groupId>com.hpsworldwide.mbtrs.switch</groupId>
    <artifactId>YOUR_DEPENDENCY</artifactId>
    <version>1.0</version>
    <exclusions>
        <exclusion>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
        </exclusion>
    </exclusions>
</dependency>

then maven will import YOUR_DEPENDENCY + all YOUR_DEPENDENCY dependencies, but will exclude servlet-api from the dependencies of YOUR_DEPENDENCY.

kapex
  • 28,903
  • 6
  • 107
  • 121
Mohammed Ali
  • 61
  • 1
  • 1
  • I understood this by lucky , I guess , the answer could explain how we know the pom dependencies to exclude servlet-api in the right dependency – Sérgio Nov 24 '21 at 01:30
5

I have just had a similar problem, and believe I have got to the bottom of it.

If you go to your server configuration settings in Eclipse and select "Serve Modules without Publishing" then this should no longer occur.

Maven/M2Eclipse is building the WAR correctly - servlet-api-2.5.jar wont be in your target directories or WAR file.

But the problem is, when you deploy the application via eclipse on to your tomcat, Eclipse does not use your maven built WAR/target directories as default, it just uses the normal Eclipse "export" settings for your project. So it sees in your "Java EE Modules" (or "Deployment Assembly List" if you are using Helios) the list of all the jars in your Maven_Dependencies, but it does not respect the scope, and just deploys all the jars.

If you select serve without publishing option then Eclipst/Tomcat should just run the app straight off your target directory so will respect the maven scopes.

It won't ever affect your live deployments (unless you are deploying via eclipse!) as maven is doing the right thing, but it can sometimes cause problems locally as you can ave conflicting servlet/jsp jars which can cause classcastexceptions and general misery...

rhinds
  • 9,976
  • 13
  • 68
  • 111
  • Thanks, that sounds very plausible. It doesn't seem to work for me, in that when I select "Serve modules without publishing" and start the server, it fails to start with a call stack like http://jira.codehaus.org/browse/MTOMCAT-6 and http://jira.codehaus.org/browse/MTOMCAT-49 (but #6 was fixed long ago and #49 was a failure to specify scope=provided which I'm doing). I don't think I'm actually using mtomcat anyway so it's likely not the same reason, but it's not happy. – metamatt May 08 '11 at 01:03
  • Are you using Eclipse Helios or an older version? – rhinds May 08 '11 at 08:21
  • can you provide the stack trace you get when you try to serve modules without publishing? It looks like you might be getting the exact same problems I am having trying to get Helios to play nicely with maven setup and serve modules without publishing (http://stackoverflow.com/questions/5924720/serve-modules-without-publishing-not-working-in-helios) – rhinds May 09 '11 at 08:43
  • Here: http://pastebin.com/NcqncHe3. And the same thing repeats for a couple other classes which cannot be cast to javax.servlet.Filter. (Anod note that o.sf.w.f.DelegatingFilterProxy does implement javax.servlet.Filter, so the cast should be legal -- http://static.springsource.org/spring/docs/1.2.9/api/org/springframework/web/filter/DelegatingFilterProxy.html.) – metamatt May 09 '11 at 22:48
  • Yep, that looks similar to the stack trace i am getting when I try to serve without publishing. Unfortunately, I am still trying to get to the bottom of it (in the meantime just not serving without publishing and manually removing the jars in my local server) but will update if i find anything else – rhinds May 11 '11 at 10:11
  • Ok, one thing I noticed that might resolve this problem for you - it seems as though if you go to properties > Java Build Path > Source, you should see all your maven folders listed - its seems as though when I imported my maven project to Eclipse it recognised all the folders, but under src/main/resources it sets Excluded: ** Which is very bizarre as it obviously means all your resources are excluded - try editing that so it says Excluded:None and try again – rhinds May 20 '11 at 19:15
4

If you are using Indigo you can find the WTP plugin by clicking to "Window" -> "Preferences" -> "Maven" -> "Discovery" -> "Open Catalog".

Simon Jester
  • 303
  • 2
  • 5
1

One tip: after install "Maven Integration for WTP" and update the project configuration, check the directory /WEB-INF/lib and delete all JARs inside. Now, clean the Tomcat work dir and run again.