servletsjettysbtxsbt-web-pluginjetty-9

Unable to get servlet to be hooked in with @WebServlet annotation in an SBT project using Jetty 9


I ran into the issue while working on an existing Java project which I'd converted to use SBT (was based purely on Eclipse before). There was a servlet (say org.my.FooServlet) that was not possible to be accessed via a web browser even though Eclipse (was still using Eclipse with sbteclipse) was reporting that /FooServlet was mapped to org.my.FooServlet.

So in order to rule out some issues possibly stemming from having converted the project to use SBT (e.g. some missing dependencies, or hidden or seemingly unrelated (mis)configuration issues), I went ahead and created a fresh SBT project to try to reproduce the issue with minimal complexity. So I currently have the below configuration/code/output and am still experiencing the issue:

container:start output:

[info] jetty-9.1.0.v20131115
[info] Started o.e.j.w.WebAppContext@33c4522{/,[file:/Users/erik.allik/code/scala/webtest/src/main/webapp/],AVAILABLE}
[info] Started ServerConnector@52879ec6{HTTP/1.1}{0.0.0.0:8080}
[success] Total time: 0 s, completed 25.11.2013 14:39:34

build.sbt:

scalaVersion := "2.10.3"

libraryDependencies ++= Seq(
  "org.eclipse.jetty" % "jetty-webapp" % "9.1.0.v20131115" % "container",
  "org.eclipse.jetty" % "jetty-jsp" % "9.1.0.v20131115" % "container",
  "org.eclipse.jetty" % "jetty-servlet" % "9.1.0.v20131115" % "container",
  "org.eclipse.jetty" % "jetty-servlets" % "9.1.0.v20131115" % "container",
  "org.eclipse.jetty" % "jetty-annotations" % "9.1.0.v20131115" % "container",
  "org.eclipse.jetty" % "jetty-plus" % "9.1.0.v20131115" % "container",
  "org.eclipse.jetty.orbit" % "javax.servlet" % "3.0.0.v201112011016" artifacts (Artifact("javax.servlet", "jar", "jar"))
)

seq(webSettings :_*)

project/plugins.sbt:

addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "0.4.2")

src/main/java/webtest/TestServlet.java:

package webtest;
// ...
@WebServlet(urlPatterns = { "/test" }, loadOnStartup = 1)
public class TestServlet extends HttpServlet {
    @Override public void init() { System.out.println("init"); }
    @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) { System.out.println("GET"); }
}

src/main/webapp/WEB-INF/web.xml: (removing it altogether makes no difference)

<?xml version="1.0" encoding="UTF-8"?>
<web-app
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" xsi:schemalocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    id="WebApp_ID" version="3.0" metadata-complete="false">
</web-app>

The container is reloaded whenever I edit and save either of the 2 code files, and the files are compiled, so at least SBT is picking them up; now the question is, why isn't Jetty. I've also tried (within the original project, not the test-dummy one) copying all classes from under target/scala-2.10/classes to src/main/webapp/WEB-INF/classes to no avail.


Solution

  • Support for Jetty Annotations was added in version 0.7.0. Update xsbt-web-plugin in your plugins.sbt and you should be good to go:

    project/plugins.sbt:

    addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "0.7.0")
    

    I also recommend adding a build.properties to maintain control over the version of sbt that your project uses:

    project/build.properties:

    sbt.version=0.13.1
    

    Here is a complete, working example: https://earldouglas.com/ext/stackoverflow.com/questions/20179351/