unit-testingrestembedded-jettyscala-2.10scalatra

No multipartconfig for servlet error from Jetty using scalatra


I am trying to unit test an upload call but I get this error for the following code:

@MultipartConfig(maxFileSize = 3145728)
class WebServlet extends ScalatraServlet with FileUploadSupport {
  override def isSizeConstraintException(e: Exception) = e match {
    case se: ServletException if se.getMessage.contains("exceeds max filesize") ||
      se.getMessage.startsWith("Request exceeds maxRequestSize") => true
    case _ => false
  }
  error {
    case e: SizeConstraintExceededException => RequestEntityTooLarge("too much!")
  }
  post("/uploadscript") {
    val privateParam = try {params("private") != null && params("private").equals("true") } catch { case _ => false }
    println("privateParam = " + privateParam)
    val file = fileParams("file")
    println(s"The size of the file is ${file.size}")
  }

The error is:

java.lang.IllegalStateException: No multipart config for servlet
    at org.eclipse.jetty.server.Request.getParts(Request.java:2064) ~[jetty-server-8.1.10.v20130312.jar:8.1.10.v20130312]
    at org.scalatra.servlet.FileUploadSupport$class.getParts(FileUploadSupport.scala:133) ~[scalatra_2.10-2.2.1.jar:2.2.1]
    at org.scalatra.servlet.FileUploadSupport$class.extractMultipartParams(FileUploadSupport.scala:108) ~[scalatra_2.10-2.2.1.jar:2.2.1]
    at org.scalatra.servlet.FileUploadSupport$class.handle(FileUploadSupport.scala:79) ~[scalatra_2.10-2.2.1.jar:2.2.1]
    at com.ui.WebServlet.handle(WebServlet.scala:32) ~[classes/:na]

And this is my unit test, and the first one succeeds, so it is finding my webservice:

class WebServletSpecification extends MutableScalatraSpec {
  addServlet(classOf[WebServlet], "/*")

  "GET /hello" should {
    "return status 200" in {
      get("/hello/testcomputer") {
        status must_== 200
      }
    }
  }
  "POST /uploadscript" should {
    "return status 200" in {
    val scriptfile = "testfile"
    val scriptname = "basescript"
      post("/uploadscript", Map("private" -> "true"), Map("file" -> new File(scriptfile))) {
        status must_== 200
      }
    }
  }
}

I am running this inside of Eclipse and I am not certain what is going on.

It works fine with using HttpPost and MultipartEntity so it seems to be a problem with Eclipse or how the scalatra specification framework works.

Any idea what may be going wrong?

I don't have a separate web.xml.

I am only using jetty 8.1.10, as seen from what I use in build.sbt:

"org.eclipse.jetty" % "jetty-webapp" % "8.1.10.v20130312" % "container"

,


Solution

  • This is the solution I found when using ServletContextHandler and not WebAppContext. From here : https://bugs.eclipse.org/bugs/show_bug.cgi?id=395000

    import org.eclipse.jetty.server.Handler;
    import org.eclipse.jetty.server.Server;
    import org.eclipse.jetty.server.handler.HandlerList;
    import org.eclipse.jetty.servlet.ServletContextHandler;
    import org.eclipse.jetty.servlet.ServletHolder;
    import javax.servlet.MultipartConfigElement;
    
    public class WebServer {
    
        protected Server server;
    
        public static void main(String[] args) throws Exception {
            int port = 8080;
            Server server = new Server(port);
    
            ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
            context.setContextPath("/");
    
    
            ServletHolder fileUploadServletHolder = new ServletHolder(new FileUploadServlet());
            fileUploadServletHolder.getRegistration().setMultipartConfig(new MultipartConfigElement("data/tmp"));
            context.addServlet(fileUploadServletHolder, "/fileUpload");
    
            server.setHandler(context);
            server.start();
            server.join();
        }
    }