I am learning Java EE 7 Servlets and tried to deploy hello2
example from Java EE 7 tutorial using embedded Jetty (v 9.3.7) with little success. hello2
consists of two servlets and an image file. The configuration is annotated and the project does not have any web.xml.
Following the WebAppContext
part from embedded Jetty examples I created this main class to initiate my embedded server:
public class MyServer {
public static void main(String[] args) throws Exception {
Server server = new Server(8080);
String webappPath = new File(MyServer.class.getProtectionDomain().getCodeSource().getLocation().getFile())
.getParentFile().getParentFile().getAbsolutePath();
WebAppContext webapp = new WebAppContext(webappPath, "");
webapp.setConfigurations(new Configuration[]{
new AnnotationConfiguration()});
server.setHandler(webapp);
server.start();
server.join();
}
}
As I understand, since Jetty is a Java EE web container, it should be able to serve the example Serlvet project as-is, and I simply need to point to the war folder structure. The following is the structure of the project:
-- hello2
\-- src
\-- main
+-- java
│ +-- MyServer.java
│ \-- javaeetutorial
│ \-- hello2
│ +-- GreetingServlet.java
│ \-- ResponseServlet.java
\-- webapp
+-- WEB-INF
│ \-- classes
│ +-- MyServer.class
│ \-- javaeetutorial
│ \-- hello2
│ +-- GreetingServlet.class
│ \-- ResponseServlet.class
+-- index.html
\-- resources
\-- images
\-- duke.waving.gif
The hello2
example code can be found here. Here are some parts of GreetingServlet
@WebServlet("/greeting")
public class GreetingServlet extends HttpServlet {
@Override
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
....
and ResponseServlet
@WebServlet("/response")
public class ResponseServlet extends HttpServlet {
@Override
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
....
The files are compiled to hello2/webapp/classes/
thus making the webapp
folder an exploded WAR. The index.html is something I added just to test whether Jetty picks it up. The result is that I get error 404 when I visit localhost:8080, localhost:8080/greeting or localhost:8080/response
If I add WebXmlConfiguration
with webapp.setConfigurations()
and then set the resource base like webapp.setResourceBase(webappPath)
, I manage to get into the Jetty's static file server. This is because Jetty then uses a default web.xml
which adds its own servlets for file serving purpose to the server. But even then my annotated servlets are not picked up.
The way I got Jetty to read the annotated servlet configuration is by setting the WEB-INF
directory explicitly using WebAppContext.getMetadata().setWebInfClassesDirs()
:
webapp.getMetaData().setWebInfClassesDirs(
Arrays.asList(Resource.newResource(
MyServer.class.getProtectionDomain().getCodeSource().getLocation())));
Then, the servlets respond as expected, but this this does not serve my index.html
or the image file. I also set the resource base to no use. So what I want is Jetty to serve my web application without web.xml
, and by simply pointing it to the exploded WAR directory. Clearly I am missing something.