Почему я получаю NoClassDefFoundError в HttpServletRequest, который указывает на ServletFileUpload?

Недавно я начал использовать JMeter для загрузки теста my webapp, локально на моем компьютере. У меня есть страница jsp для загрузки изображений. Изображения обрабатываются моим сервлетом. Когда я пробовал этот процесс сегодня, я получил следующее исключение/ошибку:

exception

javax.servlet.ServletException: Servlet execution threw an exception

root cause

java.lang.NoClassDefFoundError: javax/servlet/http/HttpServletRequest
    org.apache.commons.fileupload.servlet.ServletFileUpload.isMultipartContent(ServletFileUpload.java:68)
    spyder.servlets.imageProcessing.ImageProcessingServlet.uploadEditedImagesToDB(ImageProcessingServlet.java:527)
    spyder.servlets.imageProcessing.ImageProcessingServlet.doPost(ImageProcessingServlet.java:153)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

Вот код моего сервлета, в котором это исключение ссылается -

boolean isPart = ServletFileUpload.isMultipartContent(req);

.... и да, я поместил все необходимые выражения import в класс.

Я не могу вспомнить внесение каких-либо изменений в что-либо в моей системе, что могло бы вызвать эту проблему. Этот процесс всегда запускался без каких-либо проблем, поэтому я не понимаю, что приводит к его сбою, как сейчас. Скорее совпадение, я думаю, что он терпит неудачу после того, как я использовал JMeter...

Ответ 1

Все сторонние библиотеки webapp, такие как Commons FileUpload, принадлежат /WEB-INF/lib вашего веб-приложения, а не где-либо еще. Это исключение может возникать, когда вы помещаете его в JRE/lib или JRE/lib/ext.

И действительно, как отмечает Божо, вам необходимо также обеспечить, чтобы вы не перемещали/не копировали/не дублировали любые библиотеки, специфичные для сервлетконтейнеров (которые должны быть оставлены нетронутыми в Tomcat/lib) в разных местах пути к классам. Но это должно привести к тому, что ИМО не приведет к подобному исключению. В основном это говорит о том, что загрузчик классов, загрузивший API FileUpload, полностью не знает о Servlet API.

Если вы прочитали загрузку класса Tomcat HOW-TO, вы увидите, что загружаются библиотеки в JRE/lib и JRE/lib/ext другим загрузчиком классов (бутстрапом), чем те, что указаны в Tomcat/lib (общий) и /WEB-INF/lib (webapp). Загрузочный загрузчик bootstrap не знает об общих и Webapp-библиотеках. Это наоборот. У обычного загрузчика классов есть знания о загрузчике классов bootstrap, и у загрузчика классов Webapp есть знания об обоих. Поскольку API Servlet обычно загружается общим загрузчиком классов, это может означать, что API FileUpload был загружен загрузчиком загрузки bootstrap. И это неправильно:)

Ответ 2

Это означает, что ваш контейнер сервлета не имеет api сервлета. Проведите чистую установку Tomcat и попробуйте развернуть там. Сначала проверьте, что у вас есть api jar сервлета в tomcat/lib. И убедитесь, что у вас его нет в webapps/yourapp/WEB-INF/lib