views:

1170

answers:

4

I'm developing a servlet that receives a multipart request with content of multiple files, and I'm using apache commons file upload libraries.

When I call parseRequest(request); method servlet throws following exception:

GRAVE: Servlet.service() for servlet DiffOntology threw exception
java.lang.NoClassDefFoundError: javax/servlet/http/HttpServletRequest
    at org.apache.commons.fileupload.servlet.ServletRequestContext.getContentType(ServletRequestContext.java:73)
    at org.apache.commons.fileupload.FileUploadBase$FileItemIteratorImpl.<init>(FileUploadBase.java:882)
    at org.apache.commons.fileupload.FileUploadBase.getItemIterator(FileUploadBase.java:331)
    at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:349)
    at org.apache.commons.fileupload.servlet.ServletFileUpload.parseRequest(ServletFileUpload.java:126)
    at DiffOntology.doPost(DiffOntology.java:38)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:738)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    at java.lang.Thread.run(Thread.java:619)

I put all libraries in WEB-INF/lib.

A: 

This can happen when you've placed server-specific libraries in the webapp's /WEB-INF/lib or probably JRE/lib. Big chance that you copied Tomcat's /lib/servlet-api.jar into there. You shouldn't do that. This would only lead to collisions in the classpath which leads to this kind of errors and it will make your webapp unportable (i.e. it is tied to run on Tomcat only, you can't run it at another servers like Glassfish, JBoss AS, Websphere, etc). You should keep the server-specific libraries at their default location. Cleanup the /WEB-INF/lib from any server-specific libraries and cleanup JRE/lib from any 3rd party libraries.

You probably copied server-specific libraries there because you wasn't able to compile your servlets. Copying the libraries in /WEB-INF/lib is the wrong solution. You should basically just specify those libraries in the compiletime classpath. Since you're using Eclipse, this can be done easily: first add Tomcat in Servers view, then associate your webapp project with the integrated Tomcat instance. This way Eclipse will automatically add the server-specific libraries to the project's buildpath. On a brand new web project you can choose the server during project creation wizard. On existing web projects, you can modify it in Targeted Runtimes section in project's properties.

BalusC
Placing servlet-api.jar in WEB-INF/lib would have no effect, since Tomcat delegates to the parent class loader for javax.servlet. Even if it didn't, the exception would be ClassCastException, not NoClassDefFoundError.
bkail
@bkail: Fair point which of course depends on classloading policies (for which is true that this doesn't apply on a default Tomcat config), but was that worth a downvote? How about the remnant of the answer? That's a bit too harsh. Point is still clear: *do not pollute webapp/JRE libs with server-specific libraries*.
BalusC
Sorry, I didn't mean to be harsh. The site FAQ says to downvote misinformation, and it is misinformation to say that placement of servlet-api.jar (or even "server-specific libraries") in WEB-INF/lib or JRE/lib could be the cause of the NoClassDefFoundError, so your first paragraph would only cause the user to spend time investigating the wrong thing. The rest of your answer is good, so fix that and of course I'll remove the downvote.
bkail
Thanks @BalusC , I had the same problem , but when I moved the libs from JRE/lib to other path, it worked without any exception.
BugKiller
+1  A: 

You must have incorrectly copied commons-fileupload.jar to JRE/lib/ext, JRE/lib/endorsed, or otherwise placed it on a classpath that does not have visibility to the servlet APIs. Start the JVM with -verbose:class, which will print which classpath loaded the ServletFileUpload class. If the class is loaded from anywhere other than WEB-INF/lib, you'll need to remove it.

bkail
Huh? Why are you suggesting to place libraries in `JRE/lib`? This may work, but this makes your webapp unportable. This is certainly not the right way. This is more a hack/workaround.
BalusC
"Huh?" indeed :-). My answer must have been worded poorly, so I've updated to add the word "incorrectly". I was not saying he should put jars in JRE/lib, I was saying that in order to get NoClassDefFoundError, that's what he must have already done. He needs to use _only_ WEB-INF/lib for commons-fileupload.jar, and he needs to delete any jars he added to other classpaths.
bkail
OK, I removed the downvote after your answer improvement.
BalusC
A: 

servlet-api.jar is in the correct directory (tomcat/lib) and all others libraries are in WEB-INF/lib

I think maybe the problem could be the following: I'm developing this web project in Eclipse, and I imported file uploads libraries in the classpath.

How it doesn't work?

I'm desperate!!

pAkY88
Since you're developing in Eclipse, are you launching the app through Eclipse or launching it manually in a separate installation of your servlet container?
chrisbunney
Please post updates to questions in question itself (click `edit` link) or post it as a comment to answers (click `add comment`) link. Don't post them as answers. As to the problem, how about `JRE/lib`? Having the servlet libs there can also lead to this kind of problems since it is loaded by a different classloader.
BalusC
A: 

Add servlet.jar to your classpath. You may download it from http://www.findjar.com/jar/com.oracle/oc4j/11/jars/servlet.jar.html

You may put that in WEB-INF/lib folder.

arcamax
You should never copy server-specific libraries outside their original location. You should certainly also not mix libraries from different servers together (your linked JAR file is Oracle OC4J specific). Tomcat already ships with a Servlet API library itself. Just keep it there.
BalusC